From: Yasuhiro Matsumoto Date: Sat, 21 Feb 2026 09:55:18 +0000 (+0000) Subject: patch 9.2.0035: syntax highlighting lost in popup with opacity X-Git-Tag: v9.2.0035^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=782345c9e6d4539c462d8e51b8eb82c28fa1232a;p=thirdparty%2Fvim.git patch 9.2.0035: syntax highlighting lost in popup with opacity Problem: syntax highlighting lost in popup with opacity lower than 100 (after v9.2.0017) Solution: Before blending, combine the popup's window color attribute with the character's own attribute using hl_combine_attr() (Yasuhiro Matsumoto). related: #19272 closes: #19478 Signed-off-by: Yasuhiro Matsumoto Signed-off-by: Christian Brabandt --- diff --git a/src/screen.c b/src/screen.c index 74e4a40e37..6e6f11b70b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -666,10 +666,15 @@ screen_line( opacity_blank = TRUE; // Keep the underlying character and blend its foreground color // from popup background color to original color. + // Combine the popup window color with the character's own + // attribute (e.g. match highlight) so that its background + // color is preserved on blank cells. + int char_attr = ScreenAttrs[off_from]; int popup_attr = get_wcr_attr(screen_opacity_popup); + int combined = hl_combine_attr(popup_attr, char_attr); int blend = screen_opacity_popup->w_popup_blend; ScreenAttrs[off_to] = hl_blend_attr(ScreenAttrs[off_to], - popup_attr, blend, TRUE); + combined, blend, TRUE); screen_char(off_to, row, col + coloff); // For wide background character, also update the second cell. if (bg_char_cells == 2) @@ -818,11 +823,14 @@ skip_opacity: && (flags & SLF_POPUP) && screen_opacity_popup->w_popup_blend > 0) { + int char_attr = ScreenAttrs[off_from]; int popup_attr = get_wcr_attr(screen_opacity_popup); int blend = screen_opacity_popup->w_popup_blend; - // Blend popup attr with default background (0) - // FALSE = keep popup foreground color, blend background only - ScreenAttrs[off_to] = hl_blend_attr(0, popup_attr, blend, FALSE); + // Combine popup window color with the character's own + // attribute (e.g. syntax highlighting) so that the + // character's foreground color is preserved. + int combined = hl_combine_attr(popup_attr, char_attr); + ScreenAttrs[off_to] = hl_blend_attr(0, combined, blend, FALSE); } #endif diff --git a/src/testdir/dumps/Test_popupwin_opacity_hl_100.dump b/src/testdir/dumps/Test_popupwin_opacity_hl_100.dump new file mode 100644 index 0000000000..f087349e4d --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_opacity_hl_100.dump @@ -0,0 +1,10 @@ +>1+0&#ffffff0| @73 +|2| @73 +|3| @7|f+0#ff404010#5fd7ff255|o@1| @1|b+0#0000000&|a|r| +0&#ffffff0@57 +|4| @7|b+0fd7ff255|a|z| @4| +0&#ffffff0@57 +|5| @73 +|6| @73 +|7| @73 +|8| @73 +|9| @73 +@57|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_popupwin_opacity_hl_80.dump b/src/testdir/dumps/Test_popupwin_opacity_hl_80.dump new file mode 100644 index 0000000000..89700f9c40 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_opacity_hl_80.dump @@ -0,0 +1,10 @@ +>1+0&#ffffff0| @73 +|2| @73 +|3| @7|f+0#ff404010#5fd7ff255|o@1| @1|b+0#0000000&|a|r| +0&#ffffff0@57 +|4| @7|b+0fd7ff255|a|z| @4| +0&#ffffff0@57 +|5| @73 +|6| @73 +|7| @73 +|8| @73 +|9| @73 +|:| @55|1|,|1| @10|T|o|p| diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim index a608fbaf59..c00ac29a7e 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -4653,6 +4653,40 @@ func Test_popupwin_bottom_position_without_decoration() call StopVimInTerminal(buf) endfunc +func Test_popup_opacity_highlight() + CheckScreendump + + " Verify that match highlighting is preserved when opacity < 100, + " both for non-blank characters and trailing blank cells. + let lines =<< trim END + call setline(1, range(1, 100)) + hi PopupColor ctermbg=lightblue + hi MyHl ctermfg=red + + " 'foo ' includes trailing spaces to test the opacity blank path. + let winid = popup_create(['foo bar', 'baz'], + \ #{line: 3, col: 10, highlight: 'PopupColor', opacity: 100}) + call win_execute(winid, "call matchadd('MyHl', 'foo ')") + END + call writefile(lines, 'XtestPopupOpacity', 'D') + let buf = RunVimInTerminal('-S XtestPopupOpacity', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_popupwin_opacity_hl_100', {}) + + " opacity=80: highlighted text should still be visible + call term_sendkeys(buf, ":call popup_clear()\") + call TermWait(buf) + call term_sendkeys(buf, ":let winid = popup_create(['foo bar', 'baz']," + \ .. " #{line: 3, col: 10, highlight: 'PopupColor', opacity: 80})\") + call TermWait(buf) + call term_sendkeys(buf, ":call win_execute(winid," + \ .. " \"call matchadd('MyHl', 'foo ')\")\") + call TermWait(buf) + call term_sendkeys(buf, ":\") + call VerifyScreenDump(buf, 'Test_popupwin_opacity_hl_80', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_popup_getwininfo_tabnr() tab split let winid1 = popup_create('sup', #{tabpage: 1}) diff --git a/src/version.c b/src/version.c index b7510a5e9f..9e140b13f0 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 35, /**/ 34, /**/