]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0230: popup: opacity not working accross vert splits v9.2.0230
authorYasuhiro Matsumoto <mattn.jp@gmail.com>
Sun, 22 Mar 2026 20:38:22 +0000 (20:38 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 22 Mar 2026 20:38:22 +0000 (20:38 +0000)
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>
src/popupwin.c
src/testdir/dumps/Test_popupwin_opacity_vsplit_1.dump [new file with mode: 0644]
src/testdir/dumps/Test_popupwin_opacity_vsplit_2.dump [new file with mode: 0644]
src/testdir/test_popupwin.vim
src/version.c

index fe06777f7ccd02799690c31322e5acbc5df396ee..ed6f6fc1bbbfd37b23518d937379ee9efc228380 100644 (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)
+           int     line_cp = r;
+           int     col_cp = col;
+           win_T   *twp;
+
+           twp = mouse_find_win(&line_cp, &col_cp, IGNORE_POPUP);
+           if (twp != NULL && twp != prev_twp)
            {
-               linenr_T lnum;
+               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);
+                   (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;
        }
     }
 }
diff --git a/src/testdir/dumps/Test_popupwin_opacity_vsplit_1.dump b/src/testdir/dumps/Test_popupwin_opacity_vsplit_1.dump
new file mode 100644 (file)
index 0000000..f672090
--- /dev/null
@@ -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
diff --git a/src/testdir/dumps/Test_popupwin_opacity_vsplit_2.dump b/src/testdir/dumps/Test_popupwin_opacity_vsplit_2.dump
new file mode 100644 (file)
index 0000000..cf2f426
--- /dev/null
@@ -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
index 41cd6f0d0f76b20f7fe6afcc9412b01ac41c2b32..ab6a74d07717f9d953efcf5431355e9d0b318798 100644 (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
index fd702323c1d29695947656455fde1f46c17a72f3..cfd6d06570a6d4280e8abb3d7edb20b7b1b67554 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    230,
 /**/
     229,
 /**/