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 <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yasuhiro Matsumoto
2026-02-21 09:55:18 +00:00
committed by Christian Brabandt
parent 2ab37c07a8
commit 782345c9e6
5 changed files with 68 additions and 4 deletions
+12 -4
View File
@@ -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
@@ -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+0&#5fd7ff255|a|z| @4| +0&#ffffff0@57
|5| @73
|6| @73
|7| @73
|8| @73
|9| @73
@57|1|,|1| @10|T|o|p|
@@ -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+0&#5fd7ff255|a|z| @4| +0&#ffffff0@57
|5| @73
|6| @73
|7| @73
|8| @73
|9| @73
|:| @55|1|,|1| @10|T|o|p|
+34
View File
@@ -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()\<CR>")
call TermWait(buf)
call term_sendkeys(buf, ":let winid = popup_create(['foo bar', 'baz'],"
\ .. " #{line: 3, col: 10, highlight: 'PopupColor', opacity: 80})\<CR>")
call TermWait(buf)
call term_sendkeys(buf, ":call win_execute(winid,"
\ .. " \"call matchadd('MyHl', 'foo ')\")\<CR>")
call TermWait(buf)
call term_sendkeys(buf, ":\<CR>")
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})
+2
View File
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
35,
/**/
34,
/**/