patch 9.2.0230: popup: opacity not working accross vert splits

Problem:  popup: opacity not working across vert splits
Solution: Iterate over the full popup width to find all underlying
          windows (Yasuhiro Matsumoto)

redraw_win_under_opacity_popup() only checked the popup's left column
to find underlying windows. When a popup spans a vertical split, the
right-side window was never forced to redraw, causing blended
ScreenAttrs values to accumulate across redraw cycles.

Iterate across the full popup width to find and redraw all underlying
windows.

closes: #19737

Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yasuhiro Matsumoto
2026-03-22 20:38:22 +00:00
committed by Christian Brabandt
parent 1fe0d1e8f5
commit 196cf9f644
5 changed files with 92 additions and 14 deletions
+26 -14
View File
@@ -4298,6 +4298,7 @@ popup_mark_opacity_zindex(win_T *wp)
redraw_win_under_opacity_popup(win_T *wp)
{
int height;
int width;
int r;
if (!(wp->w_popup_flags & POPF_OPACITY) || wp->w_popup_blend <= 0
@@ -4305,27 +4306,38 @@ redraw_win_under_opacity_popup(win_T *wp)
return;
height = popup_height(wp);
width = popup_width(wp);
for (r = wp->w_winrow;
r < wp->w_winrow + height && r < screen_Rows; ++r)
{
int line_cp = r;
int col_cp = wp->w_wincol;
win_T *twp;
int col;
win_T *prev_twp = NULL;
twp = mouse_find_win(&line_cp, &col_cp, IGNORE_POPUP);
if (twp != NULL)
// Check across the full width of the popup to find all underlying
// windows (e.g., when the popup spans a vertical split).
for (col = wp->w_wincol;
col < wp->w_wincol + width && col < screen_Columns; ++col)
{
if (line_cp < twp->w_height)
{
linenr_T lnum;
int line_cp = r;
int col_cp = col;
win_T *twp;
(void)mouse_comp_pos(twp, &line_cp, &col_cp, &lnum, NULL);
redrawWinline(twp, lnum);
twp = mouse_find_win(&line_cp, &col_cp, IGNORE_POPUP);
if (twp != NULL && twp != prev_twp)
{
prev_twp = twp;
if (line_cp < twp->w_height)
{
linenr_T lnum;
(void)mouse_comp_pos(twp, &line_cp, &col_cp, &lnum, NULL);
redrawWinline(twp, lnum);
}
else if (line_cp == twp->w_height)
// Status bar line: mark for redraw to prevent
// opacity blend accumulation.
twp->w_redr_status = TRUE;
}
else if (line_cp == twp->w_height)
// Status bar line: mark for redraw to prevent
// opacity blend accumulation.
twp->w_redr_status = TRUE;
}
}
}
+12
View File
@@ -0,0 +1,12 @@
>r+0&#ffffff0|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @1|o|p|a|c|i|t|y| |o|v|e|r+1&&|l+0&&|v|s|p|l|i|t|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|[+3&&|N|o| |N|a|m|e|]| |[|+|]| @8|1|,|1| @11|A|l@1| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1
| +0&&@77
+12
View File
@@ -0,0 +1,12 @@
|r+0&#ffffff0|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @1|o|p|a|c|i|t|y| |o|v|e|r+1&&|l+0&&|v|s|p|l|i|t|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
>r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|r|i|g|h|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @12||+1&&|l+0&&|e|f|t| |w|i|n|d|o|w| |t|e|x|t| |h|e|r|e| |x@3| @10
|[+3&&|N|o| |N|a|m|e|]| |[|+|]| @8|6|,|1| @11|A|l@1| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1
| +0&&@77
+40
View File
@@ -4985,4 +4985,44 @@ func Test_popup_conceal_wrap()
call StopVimInTerminal(buf)
endfunc
func Test_popup_opacity_vsplit()
CheckScreendump
" Opacity popup spanning a vertical split should redraw both windows
" underneath, not just the left one (blend accumulation bug).
let lines =<< trim END
call setline(1, repeat(['left window text here xxxx'], 10))
vnew
call setline(1, repeat(['right window text here xxxx'], 10))
wincmd h
hi PopupColor guibg=darkblue guifg=white
let g:pop_id = popup_create(['opacity over vsplit'], #{
\ line: 3, col: 30,
\ minwidth: 25,
\ highlight: 'PopupColor',
\ opacity: 50,
\ zindex: 50,
\})
END
call writefile(lines, 'XtestPopupOpacityVsplit', 'D')
let buf = RunVimInTerminal('-S XtestPopupOpacityVsplit', #{rows: 12, cols: 80})
call VerifyScreenDump(buf, 'Test_popupwin_opacity_vsplit_1', {})
" Move cursor multiple times to trigger redraws; without the fix the
" right-side window blend accumulates on each redraw cycle.
call term_sendkeys(buf, "j")
call TermWait(buf, 50)
call term_sendkeys(buf, "j")
call TermWait(buf, 50)
call term_sendkeys(buf, "j")
call TermWait(buf, 50)
call term_sendkeys(buf, "j")
call TermWait(buf, 50)
call term_sendkeys(buf, "j")
call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_popupwin_opacity_vsplit_2', {})
call StopVimInTerminal(buf)
endfunc
" vim: shiftwidth=2 sts=2
+2
View File
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
230,
/**/
229,
/**/