Commit: patch 9.2.0602: popup: No opacity when background not set for Popup group

3 views
Skip to first unread message

Christian Brabandt

unread,
Jun 7, 2026, 3:30:13 PM (2 days ago) Jun 7
to vim...@googlegroups.com
patch 9.2.0602: popup: No opacity when background not set for Popup group

Commit: https://github.com/vim/vim/commit/1ffc1aaa4317979b7159123b19f3af2bd65f9bea
Author: Shad <shadow...@free.fr>
Date: Sun Jun 7 19:22:33 2026 +0000

patch 9.2.0602: popup: No opacity when background not set for Popup group

Problem: popup: When the Popup highlight group has no guibg/ctermbg the
popup becomes fully transparent.
Solution: Create an entry if no popup_attr exists (highlight group
cleared for example), and test if popup_attr exists but
without guibg/ctermbg attributes to fallaback to normal bg
color.

closes: #20414

Signed-off-by: Shad <shadow...@free.fr>
Signed-off-by: Hirohito Higashi <h.eas...@gmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/highlight.c b/src/highlight.c
index 7405aed32..325e5d65f 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -3407,10 +3407,8 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
attrentry_T *char_aep = NULL;
attrentry_T *popup_aep;
attrentry_T new_en;
+ attrentry_T tmp_en;

- // If both attrs are 0, return 0
- if (char_attr == 0 && popup_attr == 0)
- return 0;
if (blend >= 100 && blend_fg)
return char_attr; // Fully transparent for both fg and bg

@@ -3431,46 +3429,62 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
new_en.ae_attr = char_attr;
}

- if (popup_attr > HL_ALL)
+ // initialize an empty entry if no highlight set for popup
+ if (popup_attr <= HL_ALL)
{
+ CLEAR_FIELD(tmp_en);
+ tmp_en.ae_u.gui.fg_color = INVALCOLOR;
+ tmp_en.ae_u.gui.bg_color = INVALCOLOR;
+ tmp_en.ae_u.gui.sp_color = INVALCOLOR;
+ // preserve attributes other than color
+ tmp_en.ae_attr = popup_attr;
+ popup_aep = &tmp_en;
+
+ popup_aep->ae_u.gui.bg_color = fallback_bg_rgb;
+ }
+ else
popup_aep = syn_gui_attr2entry(popup_attr);
- if (popup_aep != NULL)
+
+ if (popup_aep != NULL)
+ {
+ guicolor_T popup_bg_rgb = popup_aep->ae_u.gui.bg_color;
+ if (COLOR_INVALID(popup_bg_rgb))
+ popup_bg_rgb = fallback_bg_rgb;
+
+ if (blend_fg)
{
- if (blend_fg)
+ // blend_fg=TRUE: fade underlying text toward popup bg.
{
- // blend_fg=TRUE: fade underlying text toward popup bg.
- if (popup_aep->ae_u.gui.bg_color != INVALCOLOR)
- {
- int base_fg = fallback_fg_rgb;
- if (char_aep != NULL
- && char_aep->ae_u.gui.fg_color != INVALCOLOR)
- base_fg = char_aep->ae_u.gui.fg_color;
- new_en.ae_u.gui.fg_color = blend_colors(
- popup_aep->ae_u.gui.bg_color, base_fg, blend);
- }
- }
- else
- {
- // blend_fg=FALSE: popup text is opaque. Replace the
- // underlying cell's attribute flags, fg and special
- // color with the popup's, so the underlying syntax
- // highlighting and any decoration (textprop undercurl,
- // ...) do not bleed through.
- new_en.ae_attr = popup_aep->ae_attr;
- new_en.ae_u.gui.fg_color = popup_aep->ae_u.gui.fg_color;
- new_en.ae_u.gui.sp_color = popup_aep->ae_u.gui.sp_color;
- }
- // Blend background color: blend popup bg toward underlying bg
- if (popup_aep->ae_u.gui.bg_color != INVALCOLOR)
- {
- guicolor_T underlying_bg = fallback_bg_rgb;
- if (char_aep != NULL)
- underlying_bg = char_aep->ae_u.gui.bg_color;
- new_en.ae_u.gui.bg_color = blend_colors(
- popup_aep->ae_u.gui.bg_color,
- underlying_bg, blend);
+ int base_fg = fallback_fg_rgb;
+ if (char_aep != NULL
+ && char_aep->ae_u.gui.fg_color != INVALCOLOR)
+ base_fg = char_aep->ae_u.gui.fg_color;
+ new_en.ae_u.gui.fg_color = blend_colors(
+ popup_bg_rgb, base_fg, blend);
}
}
+ else
+ {
+ // blend_fg=FALSE: popup text is opaque. Replace the
+ // underlying cell's attribute flags, fg and special
+ // color with the popup's, so the underlying syntax
+ // highlighting and any decoration (textprop undercurl,
+ // ...) do not bleed through.
+ new_en.ae_attr = popup_aep->ae_attr;
+ // fallback correctly to Normal fg color if fg_color == INVALCOLOR
+ new_en.ae_u.gui.fg_color = popup_aep->ae_u.gui.fg_color;
+ new_en.ae_u.gui.sp_color = popup_aep->ae_u.gui.sp_color;
+ }
+ // Blend background color: blend popup bg toward underlying bg
+ {
+ guicolor_T underlying_bg = fallback_bg_rgb;
+ if (char_aep != NULL
+ && !COLOR_INVALID(char_aep->ae_u.gui.bg_color))
+ underlying_bg = char_aep->ae_u.gui.bg_color;
+ new_en.ae_u.gui.bg_color = blend_colors(
+ popup_bg_rgb,
+ underlying_bg, blend);
+ }
}
return get_attr_entry(&gui_attr_table, &new_en);
}
@@ -3494,130 +3508,151 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
new_en.ae_attr = char_attr;
}

- if (popup_attr > HL_ALL)
+ // initialize an empty entry if no highlight set for popup
+ if (popup_attr <= HL_ALL)
{
+ CLEAR_FIELD(tmp_en);
+#ifdef FEAT_TERMGUICOLORS
+ tmp_en.ae_u.cterm.fg_rgb = INVALCOLOR;
+ tmp_en.ae_u.cterm.ul_rgb = INVALCOLOR;
+ // allow blending with termguicolors
+ tmp_en.ae_u.cterm.bg_rgb = fallback_bg_rgb;
+#endif
+ // preserve attributes other than color
+ tmp_en.ae_attr = popup_attr;
+ popup_aep = &tmp_en;
+
+ // allow blending with notermguicolors
+ popup_aep->ae_u.cterm.bg_color = cterm_normal_bg_color;
+ }
+ else
popup_aep = syn_cterm_attr2entry(popup_attr);
- if (popup_aep != NULL)
+
+ if (popup_aep != NULL)
+ {
+ guicolor_T popup_bg_rgb = INVALCOLOR;
+#ifdef FEAT_TERMGUICOLORS
+ // Fall back to cterm color converted to RGB when gui color is not set.
+ popup_bg_rgb = popup_aep->ae_u.cterm.bg_rgb;
+ if (COLOR_INVALID(popup_bg_rgb)
+ && popup_aep->ae_u.cterm.bg_color > 0)
+ popup_bg_rgb = cterm_color_to_rgb(
+ popup_aep->ae_u.cterm.bg_color);
+#endif
+ // assign default color if guibg and ctermbg are not set for popup
+ if (COLOR_INVALID(popup_bg_rgb)
+ && popup_aep->ae_u.cterm.bg_color == 0)
+ popup_bg_rgb = fallback_bg_rgb;
+
+ if (!blend_fg)
{
- if (!blend_fg)
- {
- // blend_fg=FALSE: popup text is opaque. Replace the
- // underlying cell's attribute flags, fg and underline
- // color with the popup's, so the underlying syntax
- // highlighting and any decoration (textprop undercurl,
- // ...) do not bleed through. When the popup has no fg
- // (e.g. "guifg=NONE") fall back to Normal's fg so the
- // text is still readable instead of taking on whatever
- // the underlying cell happened to have.
- new_en.ae_attr = popup_aep->ae_attr;
- if (popup_aep->ae_u.cterm.fg_color > 0)
- new_en.ae_u.cterm.fg_color =
- popup_aep->ae_u.cterm.fg_color;
- else if (cterm_normal_fg_color > 0)
- new_en.ae_u.cterm.fg_color = cterm_normal_fg_color;
- else
- new_en.ae_u.cterm.fg_color = 16; // white-ish
- new_en.ae_u.cterm.ul_color = popup_aep->ae_u.cterm.ul_color;
+ // blend_fg=FALSE: popup text is opaque. Replace the
+ // underlying cell's attribute flags, fg and underline
+ // color with the popup's, so the underlying syntax
+ // highlighting and any decoration (textprop undercurl,
+ // ...) do not bleed through. When the popup has no fg
+ // (e.g. "guifg=NONE") fall back to Normal's fg so the
+ // text is still readable instead of taking on whatever
+ // the underlying cell happened to have.
+ new_en.ae_attr = popup_aep->ae_attr;
+ if (popup_aep->ae_u.cterm.fg_color > 0)
+ new_en.ae_u.cterm.fg_color =
+ popup_aep->ae_u.cterm.fg_color;
+ else if (cterm_normal_fg_color > 0)
+ new_en.ae_u.cterm.fg_color = cterm_normal_fg_color;
+ else
+ // black-ish or white-ish
+ new_en.ae_u.cterm.fg_color = (*p_bg == 'l') ? 1 : 16;
+ new_en.ae_u.cterm.ul_color = popup_aep->ae_u.cterm.ul_color;
#ifdef FEAT_TERMGUICOLORS
- new_en.ae_u.cterm.ul_rgb = popup_aep->ae_u.cterm.ul_rgb;
+ new_en.ae_u.cterm.ul_rgb = popup_aep->ae_u.cterm.ul_rgb;
#endif
- }
- else
- {
- // blend_fg=TRUE: fade underlying fg toward popup bg in
- // the 256-color palette. Used when the popup is over a
- // cell rendered with cterm colors (no termguicolors RGB).
- int under_fg = (char_aep != NULL)
- ? char_aep->ae_u.cterm.fg_color : 0;
- guicolor_T under_fg_rgb = INVALCOLOR;
- guicolor_T popup_bg_rgb = INVALCOLOR;
+ }
+ else
+ {
+ // blend_fg=TRUE: fade underlying fg toward popup bg in
+ // the 256-color palette. Used when the popup is over a
+ // cell rendered with cterm colors (no termguicolors RGB).
+ int under_fg = (char_aep != NULL)
+ ? char_aep->ae_u.cterm.fg_color : 0;
+ guicolor_T under_fg_rgb = INVALCOLOR;
#ifdef FEAT_TERMGUICOLORS
- if (char_aep != NULL)
- under_fg_rgb = char_aep->ae_u.cterm.fg_rgb;
- popup_bg_rgb = popup_aep->ae_u.cterm.bg_rgb;
+ if (char_aep != NULL)
+ under_fg_rgb = char_aep->ae_u.cterm.fg_rgb;
#endif
- new_en.ae_u.cterm.fg_color = blend_cterm_colors(
- popup_aep->ae_u.cterm.bg_color, popup_bg_rgb,
- under_fg, under_fg_rgb, fallback_fg_rgb, blend);
- }
- // Approximate cterm bg by blending with the underlying bg
- // in the 256-color palette and mapping to the nearest entry.
- {
- int under_bg = (char_aep != NULL)
- ? char_aep->ae_u.cterm.bg_color : 0;
- guicolor_T under_bg_rgb = INVALCOLOR;
- guicolor_T popup_bg_rgb = INVALCOLOR;
+ new_en.ae_u.cterm.fg_color = blend_cterm_colors(
+ popup_aep->ae_u.cterm.bg_color, popup_bg_rgb,
+ under_fg, under_fg_rgb, fallback_fg_rgb, blend);
+ }
+ // Approximate cterm bg by blending with the underlying bg
+ // in the 256-color palette and mapping to the nearest entry.
+ {
+ int under_bg = (char_aep != NULL)
+ ? char_aep->ae_u.cterm.bg_color : 0;
+ guicolor_T under_bg_rgb = INVALCOLOR;
#ifdef FEAT_TERMGUICOLORS
- if (char_aep != NULL)
- under_bg_rgb = char_aep->ae_u.cterm.bg_rgb;
- popup_bg_rgb = popup_aep->ae_u.cterm.bg_rgb;
+ if (char_aep != NULL)
+ under_bg_rgb = char_aep->ae_u.cterm.bg_rgb;
#endif
- new_en.ae_u.cterm.bg_color = blend_cterm_colors(
- popup_aep->ae_u.cterm.bg_color, popup_bg_rgb,
- under_bg, under_bg_rgb, fallback_bg_rgb, blend);
- }
+ new_en.ae_u.cterm.bg_color = blend_cterm_colors(
+ popup_aep->ae_u.cterm.bg_color, popup_bg_rgb,
+ under_bg, under_bg_rgb, fallback_bg_rgb, blend);
+ }
#ifdef FEAT_TERMGUICOLORS
- // Blend RGB colors for termguicolors mode.
- // Fall back to cterm color converted to RGB when
- // gui color is not set.
+ // Blend RGB colors for termguicolors mode.
+ // Fall back to cterm color converted to RGB when
+ // gui color is not set.
+ {
+ guicolor_T popup_fg = popup_aep->ae_u.cterm.fg_rgb;
+
+ if (COLOR_INVALID(popup_fg)
+ && popup_aep->ae_u.cterm.fg_color > 0)
+ popup_fg = cterm_color_to_rgb(
+ popup_aep->ae_u.cterm.fg_color);
+
+ if (blend_fg)
{
- guicolor_T popup_bg = popup_aep->ae_u.cterm.bg_rgb;
- guicolor_T popup_fg = popup_aep->ae_u.cterm.fg_rgb;
-
- if (COLOR_INVALID(popup_bg)
- && popup_aep->ae_u.cterm.bg_color > 0)
- popup_bg = cterm_color_to_rgb(
- popup_aep->ae_u.cterm.bg_color);
- if (COLOR_INVALID(popup_fg)
- && popup_aep->ae_u.cterm.fg_color > 0)
- popup_fg = cterm_color_to_rgb(
- popup_aep->ae_u.cterm.fg_color);
-
- if (blend_fg)
- {
- // blend_fg=TRUE: fade underlying text toward popup bg.
- if (popup_bg != INVALCOLOR)
- {
- int base_fg = fallback_fg_rgb;
- // CTERMCOLOR is a sentinel meaning "use the cterm
- // color"; treat it as no underlying color so it is
- // not blended in as a real near-white pixel.
- if (char_aep != NULL
- && !COLOR_INVALID(char_aep->ae_u.cterm.fg_rgb))
- base_fg = char_aep->ae_u.cterm.fg_rgb;
- new_en.ae_u.cterm.fg_rgb = blend_colors(
- popup_bg, base_fg, blend);
- }
- }
- else
- {
- // blend_fg=FALSE: popup text is opaque. Replace fg
- // with popup's so the underlying syntax highlighting
- // fg does not bleed. ae_attr was already set above
- // for this branch. When the popup has no fg fall
- // back to Normal's fg, then to white, so the text
- // stays readable instead of rendering as default
- // (which can be black on dark themes).
- if (!COLOR_INVALID(popup_fg))
- new_en.ae_u.cterm.fg_rgb = popup_fg;
- else if (!COLOR_INVALID(cterm_normal_fg_gui_color))
- new_en.ae_u.cterm.fg_rgb = cterm_normal_fg_gui_color;
- else
- new_en.ae_u.cterm.fg_rgb = fallback_fg_rgb;
- }
- if (popup_bg != INVALCOLOR)
+ // blend_fg=TRUE: fade underlying text toward popup bg.
+ if (popup_bg_rgb != INVALCOLOR)
{
- // Blend popup bg toward underlying bg
- guicolor_T underlying_bg = fallback_bg_rgb;
+ int base_fg = fallback_fg_rgb;
+ // CTERMCOLOR is a sentinel meaning "use the cterm
+ // color"; treat it as no underlying color so it is
+ // not blended in as a real near-white pixel.
if (char_aep != NULL
- && !COLOR_INVALID(char_aep->ae_u.cterm.bg_rgb))
- underlying_bg = char_aep->ae_u.cterm.bg_rgb;
- new_en.ae_u.cterm.bg_rgb = blend_colors(
- popup_bg, underlying_bg, blend);
+ && !COLOR_INVALID(char_aep->ae_u.cterm.fg_rgb))
+ base_fg = char_aep->ae_u.cterm.fg_rgb;
+ new_en.ae_u.cterm.fg_rgb = blend_colors(
+ popup_bg_rgb, base_fg, blend);
}
}
-#endif
+ else
+ {
+ // blend_fg=FALSE: popup text is opaque. Replace fg with
+ // popup's so the underlying syntax highlighting fg does
+ // not bleed. ae_attr was already set above for this
+ // branch. When the popup has no fg fall back to Normal's
+ // fg, then to white, so the text stays readable instead of
+ // rendering as default (which can be black on dark themes).
+ if (!COLOR_INVALID(popup_fg))
+ new_en.ae_u.cterm.fg_rgb = popup_fg;
+ else if (!COLOR_INVALID(cterm_normal_fg_gui_color))
+ new_en.ae_u.cterm.fg_rgb = cterm_normal_fg_gui_color;
+ else
+ new_en.ae_u.cterm.fg_rgb = fallback_fg_rgb;
+ }
+ if (popup_bg_rgb != INVALCOLOR)
+ {
+ // Blend popup bg toward underlying bg
+ guicolor_T underlying_bg = fallback_bg_rgb;
+ if (char_aep != NULL
+ && !COLOR_INVALID(char_aep->ae_u.cterm.bg_rgb))
+ underlying_bg = char_aep->ae_u.cterm.bg_rgb;
+ new_en.ae_u.cterm.bg_rgb = blend_colors(
+ popup_bg_rgb, underlying_bg, blend);
+ }
}
+#endif
}
return get_attr_entry(&cterm_attr_table, &new_en);
}
diff --git a/src/testdir/dumps/Test_popup_opacity_attr_1.dump b/src/testdir/dumps/Test_popup_opacity_attr_1.dump
new file mode 100644
index 000000000..da0602e34
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_attr_1.dump
@@ -0,0 +1,12 @@
+>X+0&#ffffff0| |X| |X| |X| |X| |X| |X| |X| |X| |X| @40
+|X| |╔+2#0000001#ffffff255|═@19|╗| +0#0000000#ffffff0@35
+|X| |║+2#0000001#ffffff255|b|o|l|d| +0#949494255&|X| |X| |X| |X| |X| |X| @3|║+2#0000001&| +0#0000000#ffffff0@35
+|X| |║+2#0000001#ffffff255| +0#949494255&|X| |X| |X| |X| |X| |X| |X| |X| @3|║+2#0000001&| +0#0000000#ffffff0@35
+|X| |╚+2#0000001#ffffff255|═@19|╝| +0#0000000#ffffff0@35
+|X| |╔+2#ff404010#ffffff255|═@19|╗| +0#0000000#ffffff0@35
+|X| |║+2#ff404010#ffffff255|b|o|l|d|c|o|l|o|r|X+0#949494255&| |X| |X| |X| @3|║+2#ff404010&| +0#0000000#ffffff0@35
+|X| |║+2#ff404010#ffffff255| +0#949494255&|X| |X| |X| |X| |X| |X| |X| |X| @3|║+2#ff404010&| +0#0000000#ffffff0@35
+|X| |╚+2#ff404010#ffffff255|═@19|╝| +0#0000000#ffffff0@35
+|X| |X| |X| |X| |X| |X| |X| |X| |X| |X| @40
+|~+0#4040ff13&| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_attr_2.dump b/src/testdir/dumps/Test_popup_opacity_attr_2.dump
new file mode 100644
index 000000000..9a549c42a
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_attr_2.dump
@@ -0,0 +1,12 @@
+>X+0&#ffffff0| |X| |X| |X| |X| |X| |X| |X| |X| |X| @40
+|X| |╔+2#000000255#ffffff255|═@19|╗| +0#0000000#ffffff0@35
+|X| |║+2#000000255#ffffff255|b|o|l|d| +0#999999255&|X| |X| |X| |X| |X| |X| @3|║+2#000000255&| +0#0000000#ffffff0@35
+|X| |║+2#000000255#ffffff255| +0#999999255&|X| |X| |X| |X| |X| |X| |X| |X| @3|║+2#000000255&| +0#0000000#ffffff0@35
+|X| |╚+2#000000255#ffffff255|═@19|╝| +0#0000000#ffffff0@35
+|X| |╔+2#ff0000255#ffffff255|═@19|╗| +0#0000000#ffffff0@35
+|X| |║+2#ff0000255#ffffff255|b|o|l|d|c|o|l|o|r|X+0#999999255&| |X| |X| |X| @3|║+2#ff0000255&| +0#0000000#ffffff0@35
+|X| |║+2#ff0000255#ffffff255| +0#999999255&|X| |X| |X| |X| |X| |X| |X| |X| @3|║+2#ff0000255&| +0#0000000#ffffff0@35
+|X| |╚+2#ff0000255#ffffff255|═@19|╝| +0#0000000#ffffff0@35
+|X| |X| |X| |X| |X| |X| |X| |X| |X| |X| @40
+|~+0#0000ff255&| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_1.dump b/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_1.dump
new file mode 100644
index 000000000..97e52e95b
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_1.dump
@@ -0,0 +1,12 @@
+>X+0&#ffffff0| @2|X| @2|X| @2|X| @2|X| @42
+|X| |P+0#0000001#ffafaf255|o|p|u|p| +0#875f5f255&|X| @2|X+0#0000000#ffffff0| @2|X| @42
+|X| | +0#875f5f255#ffafaf255@1|X| @2|X| @2|X+0#0000000#ffffff0| @2|X| @42
+|X| @2|X| @2|X| @2|X| @2|X| @42
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_2.dump b/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_2.dump
new file mode 100644
index 000000000..36892be96
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_2.dump
@@ -0,0 +1,12 @@
+>X+0&#ffffff0| @2|X| @2|X| @2|X| @2|X| @42
+|X| |P+0#000000255#ffb2b2255|o|p|u|p| +0#994d4d255&|X| @2|X+0#0000000#ffffff0| @2|X| @42
+|X| | +0#994d4d255#ffb2b2255@1|X| @2|X| @2|X+0#0000000#ffffff0| @2|X| @42
+|X| @2|X| @2|X| @2|X| @2|X| @42
+|~+0#0000ff255&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_3.dump b/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_3.dump
new file mode 100644
index 000000000..17cf2c13c
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_3.dump
@@ -0,0 +1,12 @@
+>X+0&#ffffff0| @2|X| @2|X| @2|X| @2|X| @42
+|X| |P+0#000000255#ff6666255|o|p|u|p| +0#990000255&|X| @2|X+0#0000000#ffffff0| @2|X| @42
+|X| | +0#990000255#ff6666255@1|X| @2|X| @2|X+0#0000000#ffffff0| @2|X| @42
+|X| @2|X| @2|X| @2|X| @2|X| @42
+|~+0#0000ff255&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|:+0#0000000&|h|i|g|h|l|i|g|h|t| |P|o|p|u|p|C|o|l|o|r| |c|t|e|r|m|b|g|=|N|O|N|E| |g|u|i|b|g|=|r|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_4.dump b/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_4.dump
new file mode 100644
index 000000000..b3c81fa97
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_only_cterm_or_gui_set_4.dump
@@ -0,0 +1,12 @@
+>X+0&#ffffff0| @2|X| @2|X| @2|X| @2|X| @42
+|X| |P+0#0000001#ff5f5f255|o|p|u|p| +0#870000255&|X| @2|X+0#0000000#ffffff0| @2|X| @42
+|X| | +0#870000255#ff5f5f255@1|X| @2|X| @2|X+0#0000000#ffffff0| @2|X| @42
+|X| @2|X| @2|X| @2|X| @2|X| @42
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_1.dump b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_1.dump
new file mode 100644
index 000000000..412e0c9f5
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_1.dump
@@ -0,0 +1,12 @@
+>r+0#ff404010#ffffff0|e|d| +0#0000000&|R+0&#ff404010|E|D| +0&#ffffff0|g+0#40ff4011&|r|e@1|n| +0#0000000&|G+0&#40ff4011|R|E@1|N| +0&#ffffff0|b+0#4040ff13&|l|u|e| +0#0000000&|B+0&#4040ff13|L|U|E| +0&#ffffff0|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E| +0&&@15
+|r+0#ff404010&|e|╔+0#0000001#ffffff255|═@40|╗| +0#0000000#ffffff0@14
+|r+0#ff404010&|e|║+0#0000001#ffffff255|P|o+0&#ff8787255|p|u|p+0&#ffffff255|g+0#87ff87255&|P+0#0000001&|o|p|u|p|G+0#949494255#87ff87255|P+0#0000001&|o|p|u|p+0&#ffffff255|b+0#8787ff255&|P+0#0000001&|o|p|u|p+0&#8787ff255|L+0#949494255&|P+0#0000001&|o|p+0&#ffffff255|u|p|r+0#949494255&|P+0#0000001&|o|p|u|p|E+1#949494255&|P+0#0000001&|o|p|u|p|║| +0#0000000#ffffff0@14
+|r+0#ff404010&|e|║+0#0000001#ffffff255| +0#949494255&|R+0&#ff8787255|E|D| +0&#ffffff255|g+0#87ff87255&|r|e@1|n| +0#949494255&|G+0&#87ff87255|R|E@1|N| +0&#ffffff255|b+0#8787ff255&|l|u|e| +0#949494255&|B+0&#8787ff255|L|U|E| +0&#ffffff255|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E|║+0#0000001&| +0#0000000#ffffff0@14
+|r+0#ff404010&|e|╚+0#0000001#ffffff255|═@40|╝| +0#0000000#ffffff0@14
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_2.dump b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_2.dump
new file mode 100644
index 000000000..b2f64df85
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_2.dump
@@ -0,0 +1,12 @@
+>r+0#ff404010#ffffff0|e|d| +0#0000000&|R+0&#ff404010|E|D| +0&#ffffff0|g+0#40ff4011&|r|e@1|n| +0#0000000&|G+0&#40ff4011|R|E@1|N| +0&#ffffff0|b+0#4040ff13&|l|u|e| +0#0000000&|B+0&#4040ff13|L|U|E| +0&#ffffff0|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E| +0&&@15
+|r+0#ff404010&|e|╔+0#ffffff16#000000255|═@40|╗| +0#0000000#ffffff0@14
+|r+0#ff404010&|e|║+0#ffffff16#000000255|P|o+0&#5f0000255|p|u|p+0&#000000255|g+0#005f00255&|P+0#ffffff16&|o|p|u|p|G+0#626262255#005f00255|P+0#ffffff16&|o|p|u|p+0&#000000255|b+0#00005f255&|P+0#ffffff16&|o|p|u|p+0&#00005f255|L+0#626262255&|P+0#ffffff16&|o|p+0&#000000255|u|p|r+0#626262255&|P+0#ffffff16&|o|p|u|p|E+1#626262255&|P+0#ffffff16&|o|p|u|p|║| +0#0000000#ffffff0@14
+|r+0#ff404010&|e|║+0#ffffff16#000000255| +0#626262255&|R+0&#5f0000255|E|D| +0&#000000255|g+0#005f00255&|r|e@1|n| +0#626262255&|G+0&#005f00255|R|E@1|N| +0&#000000255|b+0#00005f255&|l|u|e| +0#626262255&|B+0&#00005f255|L|U|E| +0&#000000255|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E|║+0#ffffff16&| +0#0000000#ffffff0@14
+|r+0#ff404010&|e|╚+0#ffffff16#000000255|═@40|╝| +0#0000000#ffffff0@14
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_3.dump b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_3.dump
new file mode 100644
index 000000000..733f7c8c3
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_3.dump
@@ -0,0 +1,12 @@
+>r+0#ff0000255#ffffff0|e|d| +0#0000000&|R+0&#ff0000255|E|D| +0&#ffffff0|g+0#00ff00255&|r|e@1|n| +0#0000000&|G+0&#00ff00255|R|E@1|N| +0&#ffffff0|b+0#0000ff255&|l|u|e| +0#0000000&|B+0&#0000ff255|L|U|E| +0&#ffffff0|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E| +0&&@15
+|r+0#ff0000255&|e|╔+0#ffffff255#000000255|═@40|╗| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|║+0#ffffff255#000000255|P|o+0&#660000255|p|u|p+0&#000000255|g+0#006600255&|P+0#ffffff255&|o|p|u|p|G+0#666666255#006600255|P+0#ffffff255&|o|p|u|p+0&#000000255|b+0#000066255&|P+0#ffffff255&|o|p|u|p+0&#000066255|L+0#666666255&|P+0#ffffff255&|o|p+0&#000000255|u|p|r+0#666666255&|P+0#ffffff255&|o|p|u|p|E+1#666666255&|P+0#ffffff255&|o|p|u|p|║| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|║+0#ffffff255#000000255| +0#666666255&|R+0&#660000255|E|D| +0&#000000255|g+0#006600255&|r|e@1|n| +0#666666255&|G+0&#006600255|R|E@1|N| +0&#000000255|b+0#000066255&|l|u|e| +0#666666255&|B+0&#000066255|L|U|E| +0&#000000255|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E|║+0#ffffff255&| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|╚+0#ffffff255#000000255|═@40|╝| +0#0000000#ffffff0@14
+|~+0#0000ff255&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_4.dump b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_4.dump
new file mode 100644
index 000000000..8c56ad954
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_4.dump
@@ -0,0 +1,12 @@
+>r+0#ff0000255#ffffff0|e|d| +0#0000000&|R+0&#ff0000255|E|D| +0&#ffffff0|g+0#00ff00255&|r|e@1|n| +0#0000000&|G+0&#00ff00255|R|E@1|N| +0&#ffffff0|b+0#0000ff255&|l|u|e| +0#0000000&|B+0&#0000ff255|L|U|E| +0&#ffffff0|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E| +0&&@15
+|r+0#ff0000255&|e|╔+0#000000255#ffffff255|═@40|╗| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|║+0#000000255#ffffff255|P|o+0&#ff9999255|p|u|p+0&#ffffff255|g+0#99ff99255&|P+0#000000255&|o|p|u|p|G+0#999999255#99ff99255|P+0#000000255&|o|p|u|p+0&#ffffff255|b+0#9999ff255&|P+0#000000255&|o|p|u|p+0&#9999ff255|L+0#999999255&|P+0#000000255&|o|p+0&#ffffff255|u|p|r+0#999999255&|P+0#000000255&|o|p|u|p|E+1#999999255&|P+0#000000255&|o|p|u|p|║| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|║+0#000000255#ffffff255| +0#999999255&|R+0&#ff9999255|E|D| +0&#ffffff255|g+0#99ff99255&|r|e@1|n| +0#999999255&|G+0&#99ff99255|R|E@1|N| +0&#ffffff255|b+0#9999ff255&|l|u|e| +0#999999255&|B+0&#9999ff255|L|U|E| +0&#ffffff255|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E|║+0#000000255&| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|╚+0#000000255#ffffff255|═@40|╝| +0#0000000#ffffff0@14
+|~+0#0000ff255&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_5.dump b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_5.dump
new file mode 100644
index 000000000..cb1742b10
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_5.dump
@@ -0,0 +1,12 @@
+>r+0#ff0000255#ffffff0|e|d| +0#0000000&|R+0&#ff0000255|E|D| +0&#ffffff0|g+0#00ff00255&|r|e@1|n| +0#0000000&|G+0&#00ff00255|R|E@1|N| +0&#ffffff0|b+0#0000ff255&|l|u|e| +0#0000000&|B+0&#0000ff255|L|U|E| +0&#ffffff0|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E| +0&&@15
+|r+0#ff0000255&|e|╔+0#8b008b255#ffffff255|═@40|╗| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|║+0#8b008b255#ffffff255|P|o+0&#ff9999255|p|u|p+0&#ffffff255|g+0#99ff99255&|P+0#8b008b255&|o|p|u|p|G+0#999999255#99ff99255|P+0#8b008b255&|o|p|u|p+0&#ffffff255|b+0#9999ff255&|P+0#8b008b255&|o|p|u|p+0&#9999ff255|L+0#999999255&|P+0#8b008b255&|o|p+0&#ffffff255|u|p|r+0#999999255&|P+0#8b008b255&|o|p|u|p|E+1#999999255&|P+0#8b008b255&|o|p|u|p|║| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|║+0#8b008b255#ffffff255| +0#999999255&|R+0&#ff9999255|E|D| +0&#ffffff255|g+0#99ff99255&|r|e@1|n| +0#999999255&|G+0&#99ff99255|R|E@1|N| +0&#ffffff255|b+0#9999ff255&|l|u|e| +0#999999255&|B+0&#9999ff255|L|U|E| +0&#ffffff255|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E|║+0#8b008b255&| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|╚+0#8b008b255#ffffff255|═@40|╝| +0#0000000#ffffff0@14
+|~+0#0000ff255&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|:+0#0000000&|h|i|g|h|l|i|g|h|t| |P|o|p|u|p|C|o|l|o|r| |c|t|e|r|m|f|g|=|D|a|r|k|M|a|g|e|n|t|a| |1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_6.dump b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_6.dump
new file mode 100644
index 000000000..9dccb841b
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_6.dump
@@ -0,0 +1,12 @@
+>r+0#ff0000255#ffffff0|e|d| +0#0000000&|R+0&#ff0000255|E|D| +0&#ffffff0|g+0#00ff00255&|r|e@1|n| +0#0000000&|G+0&#00ff00255|R|E@1|N| +0&#ffffff0|b+0#0000ff255&|l|u|e| +0#0000000&|B+0&#0000ff255|L|U|E| +0&#ffffff0|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E| +0&&@15
+|r+0#ff0000255&|e|╔+0#8b008b255#ffffff255|═@40|╗| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|║+0#8b008b255#ffffff255|P|o+0&#ff9999255|p|u|p+0&#ffffff255|g+0#99ff99255&|P+0#8b008b255&|o|p|u|p|G+0#999999255#99ff99255|P+0#8b008b255&|o|p|u|p+0&#ffffff255|b+0#9999ff255&|P+0#8b008b255&|o|p|u|p+0&#9999ff255|L+0#999999255&|P+0#8b008b255&|o|p+0&#ffffff255|u|p|r+0#999999255&|P+0#8b008b255&|o|p|u|p|E+1#999999255&|P+0#8b008b255&|o|p|u|p|║| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|║+0#8b008b255#ffffff255| +0#999999255&|R+0&#ff9999255|E|D| +0&#ffffff255|g+0#99ff99255&|r|e@1|n| +0#999999255&|G+0&#99ff99255|R|E@1|N| +0&#ffffff255|b+0#9999ff255&|l|u|e| +0#999999255&|B+0&#9999ff255|L|U|E| +0&#ffffff255|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E|║+0#8b008b255&| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|╚+0#8b008b255#ffffff255|═@40|╝| +0#0000000#ffffff0@14
+|~+0#0000ff255&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_7.dump b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_7.dump
new file mode 100644
index 000000000..c90dcb7d0
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_7.dump
@@ -0,0 +1,12 @@
+>r+0#ff0000255#ffffff0|e|d| +0#0000000&|R+0&#ff0000255|E|D| +0&#ffffff0|g+0#00ff00255&|r|e@1|n| +0#0000000&|G+0&#00ff00255|R|E@1|N| +0&#ffffff0|b+0#0000ff255&|l|u|e| +0#0000000&|B+0&#0000ff255|L|U|E| +0&#ffffff0|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E| +0&&@15
+|r+0#ff0000255&|e|╔+0#000000255#66b9b9255|═@40|╗| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|║+0#000000255#66b9b9255|P|o+0&#665454255|p|u|p+0&#66b9b9255|g+0#00b954255&|P+0#000000255&|o|p|u|p|G+0#005454255#00b954255|P+0#000000255&|o|p|u|p+0&#66b9b9255|b+0#0054b9255&|P+0#000000255&|o|p|u|p+0&#0054b9255|L+0#005454255&|P+0#000000255&|o|p+0&#66b9b9255|u|p|r+0#005454255&|P+0#000000255&|o|p|u|p|E+1#005454255&|P+0#000000255&|o|p|u|p|║| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|║+0#000000255#66b9b9255| +0#005454255&|R+0&#665454255|E|D| +0&#66b9b9255|g+0#00b954255&|r|e@1|n| +0#005454255&|G+0&#00b954255|R|E@1|N| +0&#66b9b9255|b+0#0054b9255&|l|u|e| +0#005454255&|B+0&#0054b9255|L|U|E| +0&#66b9b9255|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E|║+0#000000255&| +0#0000000#ffffff0@14
+|r+0#ff0000255&|e|╚+0#000000255#66b9b9255|═@40|╝| +0#0000000#ffffff0@14
+|~+0#0000ff255&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|:+0#0000000&|h|i|g|h|l|i|g|h|t| |P|o|p|u|p|C|o|l|o|r| |c|t|e|r|m|b|g|=|D|a|r|k|C|y|a|n| |g|u|i|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_8.dump b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_8.dump
new file mode 100644
index 000000000..c6e3ac5cf
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_opacity_undefined_popup_highlight_8.dump
@@ -0,0 +1,12 @@
+>r+0#ff404010#ffffff0|e|d| +0#0000000&|R+0&#ff404010|E|D| +0&#ffffff0|g+0#40ff4011&|r|e@1|n| +0#0000000&|G+0&#40ff4011|R|E@1|N| +0&#ffffff0|b+0#4040ff13&|l|u|e| +0#0000000&|B+0&#4040ff13|L|U|E| +0&#ffffff0|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E| +0&&@15
+|r+0#ff404010&|e|╔+0#0000001#5fafaf255|═@40|╗| +0#0000000#ffffff0@14
+|r+0#ff404010&|e|║+0#0000001#5fafaf255|P|o+0&#585858255|p|u|p+0&#5fafaf255|g+0#00af5f255&|P+0#0000001&|o|p|u|p|G+0#005f5f255#00af5f255|P+0#0000001&|o|p|u|p+0&#5fafaf255|b+0#005faf255&|P+0#0000001&|o|p|u|p+0&#005faf255|L+0#005f5f255&|P+0#0000001&|o|p+0&#5fafaf255|u|p|r+0#005f5f255&|P+0#0000001&|o|p|u|p|E+1#005f5f255&|P+0#0000001&|o|p|u|p|║| +0#0000000#ffffff0@14
+|r+0#ff404010&|e|║+0#0000001#5fafaf255| +0#005f5f255&|R+0&#585858255|E|D| +0&#5fafaf255|g+0#00af5f255&|r|e@1|n| +0#005f5f255&|G+0&#00af5f255|R|E@1|N| +0&#5fafaf255|b+0#005faf255&|l|u|e| +0#005f5f255&|B+0&#005faf255|L|U|E| +0&#5fafaf255|n|o|r|m|a|l| |R+1&&|E|V|E|R|S|E|║+0#0000001&| +0#0000000#ffffff0@14
+|r+0#ff404010&|e|╚+0#0000001#5fafaf255|═@40|╝| +0#0000000#ffffff0@14
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+|~| @58
+| +0#0000000&@41|1|,|1| @10|A|l@1|
diff --git a/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_1.dump b/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_1.dump
index 120ab9615..9997dc6f3 100644
--- a/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_1.dump
+++ b/src/testdir/dumps/Test_popupwin_opacity_fade_to_background_1.dump
@@ -1,5 +1,5 @@
>X+0&#ffffff0| @2|X| @2|X| @2|X| @2|X| @42
-|X| |P+0#ffffff16#5f5fff255|o|p|u|p| +0#000087255&|X| @2|X+0#0000000#ffffff0| @2|X| @42
+|X| |P+0#0000001#5f5fff255|o|p|u|p| +0#000087255&|X| @2|X+0#0000000#ffffff0| @2|X| @42
|X| | +0#000087255#5f5fff255@1|X| @2|X| @2|X+0#0000000#ffffff0| @2|X| @42
|X| @2|X| @2|X| @2|X| @2|X| @42
|~+0#4040ff13&| @58
diff --git a/src/testdir/dumps/Test_popupwin_opacity_hl_80.dump b/src/testdir/dumps/Test_popupwin_opacity_hl_80.dump
index 932ebb724..c57365eaa 100644
--- a/src/testdir/dumps/Test_popupwin_opacity_hl_80.dump
+++ b/src/testdir/dumps/Test_popupwin_opacity_hl_80.dump
@@ -1,7 +1,7 @@
>1+0&#ffffff0| @73
|2| @73
-|3| @7|f+0#ff404010#87d7ff255|o@1| +0#5fafd7255&@1|b+0#ffffff16&|a|r| +0#0000000#ffffff0@57
-|4| @7|b+0#ffffff16#87d7ff255|a|z| +0#5fafd7255&@4| +0#0000000#ffffff0@57
+|3| @7|f+0#ff404010#87d7ff255|o@1| +0#5fafd7255&@1|b+0#0000001&|a|r| +0#0000000#ffffff0@57
+|4| @7|b+0#0000001#87d7ff255|a|z| +0#5fafd7255&@4| +0#0000000#ffffff0@57
|5| @73
|6| @73
|7| @73
diff --git a/src/testdir/dumps/Test_popupwin_opacity_zero_01.dump b/src/testdir/dumps/Test_popupwin_opacity_zero_01.dump
index 8028c98c2..9b11b5c0e 100644
--- a/src/testdir/dumps/Test_popupwin_opacity_zero_01.dump
+++ b/src/testdir/dumps/Test_popupwin_opacity_zero_01.dump
@@ -1,7 +1,7 @@
>b+0&#ffffff0|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54
|b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54
-|b|a|c|k|b+0#ffffff16#8787d7255|l|u|e|n+0#00005f255&|p+0#ffffff16&|o|p|u|p|t+0#0000000#ffffff0| |h|e|r|e| @54
-|b|a|c|k|g|r|o|r+0#ffffff16#ffffff255|e|d| +0#0000000#ffffff0|p+0#ffffff16#ffffff255|o|p|u|p|h+0#0000000#ffffff0|e|r|e| @54
+|b|a|c|k|b+0#0000001#8787d7255|l|u|e|n+0#00005f255&|p+0#0000001&|o|p|u|p|t+0#0000000#ffffff0| |h|e|r|e| @54
+|b|a|c|k|g|r|o|r+0#0000001#ffffff255|e|d| +0#0000000#ffffff0|p+0#0000001#ffffff255|o|p|u|p|h+0#0000000#ffffff0|e|r|e| @54
|b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54
|b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54
|b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54
diff --git a/src/testdir/dumps/Test_popupwin_opacity_zero_02.dump b/src/testdir/dumps/Test_popupwin_opacity_zero_02.dump
index d09818da5..f790559ef 100644
--- a/src/testdir/dumps/Test_popupwin_opacity_zero_02.dump
+++ b/src/testdir/dumps/Test_popupwin_opacity_zero_02.dump
@@ -1,7 +1,7 @@
>b+0&#ffffff0|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54
|b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54
-|b|a|c|k|b+0#ffffff16#8787d7255|l|u|e|n+0#00005f255&|p+0#ffffff16&|o|p|u|p|t+0#0000000#ffffff0| |h|e|r|e| @54
-|b|a|c|k|g|r|o|r+0#ffffff16#ffffff255|e|d| +0#0000000#ffffff0|p+0#ffffff16#ffffff255|o|p|u|p|h+0#0000000#ffffff0|e|r|e| @54
+|b|a|c|k|b+0#0000001#8787d7255|l|u|e|n+0#00005f255&|p+0#0000001&|o|p|u|p|t+0#0000000#ffffff0| |h|e|r|e| @54
+|b|a|c|k|g|r|o|r+0#0000001#ffffff255|e|d| +0#0000000#ffffff0|p+0#0000001#ffffff255|o|p|u|p|h+0#0000000#ffffff0|e|r|e| @54
|b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54
|b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54
|b|a|c|k|g|r|o|u|n|d| |t|e|x|t| |h|e|r|e| @54
diff --git a/src/testdir/dumps/Test_pumopt_opacity_text_attrs.dump b/src/testdir/dumps/Test_pumopt_opacity_text_attrs.dump
index 1ae8db5a1..62e7df726 100644
--- a/src/testdir/dumps/Test_pumopt_opacity_text_attrs.dump
+++ b/src/testdir/dumps/Test_pumopt_opacity_text_attrs.dump
@@ -1,7 +1,7 @@
|ほ*0&#ffffff0|げ> +&@70
-|ほ*0#0000001#ffd787255|げ|ほ*0#875f00255&|げ|ほ|げ|漢*4#ff875f255&| +&| +4#e000e06#ffffff0|テ*&|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
-|ふ*0#ffffff16#87afaf255|が|漢|字|ほ*0#00005f255&|げ|漢*4#875faf255&| +&| +4#e000e06#ffffff0|テ*&|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
-|カ*0#ffffff16#87afaf255|タ|カ|ナ|候|補|漢*4#875faf255&| +&| +4#e000e06#ffffff0|テ*&|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*0#0000001#ffd787255|げ|ほ*0#875f00255&|げ|ほ|げ|漢*4#ff875f255&| +&| +4#e000e06#ffffff255|テ*4&#ffffff0|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ふ*0#ffffff16#87afaf255|が|漢|字|ほ*0#00005f255&|げ|漢*4#875faf255&| +&| +4#e000e06#ffffff255|テ*4&#ffffff0|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|カ*0#ffffff16#87afaf255|タ|カ|ナ|候|補|漢*4#875faf255&| +&| +4#e000e06#ffffff255|テ*4&#ffffff0|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index 077c08f61..2850ce08b 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -5506,8 +5506,6 @@ endfunc
func Test_popup_opacity_fade_to_background()
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(['X X X X X'], 4))
hi PopupColor guibg=blue
@@ -5515,7 +5513,7 @@ func Test_popup_opacity_fade_to_background()
\ line: 2, col: 3,
\ minwidth: 10,
\ minheight: 2,
- \ highlight: 'PopupColor',
+ \ highlights: 'Normal:PopupColor',
\ opacity: 60,
\ zindex: 50,
\})
@@ -5542,4 +5540,143 @@ func Test_popup_opacity_fade_to_background()
call StopVimInTerminal(buf)
endfunc

+func Test_popup_opacity_undefined_popup_highlight()
+ CheckScreendump
+
+ let lines =<< trim END
+ highlight clear PopupColor
+ highlight red ctermfg=red guifg=red
+ highlight revred ctermbg=red guibg=red
+ highlight blue ctermfg=blue guifg=blue
+ highlight revblue ctermbg=blue guibg=blue
+ highlight green ctermfg=green guifg=green
+ highlight revgreen ctermbg=green guibg=green
+ highlight reverse cterm=reverse
+ call matchadd('red', 'red')
+ call matchadd('revred', 'RED')
+ call matchadd('blue', 'blue')
+ call matchadd('revblue', 'BLUE')
+ call matchadd('green', 'green')
+ call matchadd('revgreen', 'GREEN')
+ call matchadd('reverse', 'REVERSE')
+ call setline(1, repeat(['red RED green GREEN blue BLUE normal REVERSE'], 5))
+ call popup_create('Popup Popup Popup Popup Popup Popup Popup', #{
+ \ line: 2, col: 3,
+ \ border: [1, 1, 1, 1],
+ \ minwidth: 10,
+ \ minheight: 2,
+ \ highlights: 'Normal:PopupColor',
+ \ opacity: 60,
+ \ })
+ END
+ call writefile(lines, 'XtestPopupOpacityUndefinedPopupHighlight', 'D')
+ let buf = RunVimInTerminal('-S XtestPopupOpacityUndefinedPopupHighlight', #{rows: 12, cols: 60})
+ " light background without Normal color set
+ call VerifyScreenDump(buf, 'Test_popup_opacity_undefined_popup_highlight_1', {})
+
+ " dark background without Normal color set
+ call term_sendkeys(buf, ":set background=dark\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_opacity_undefined_popup_highlight_2', {})
+
+ " dark termguicolors
+ call term_sendkeys(buf, ":set termguicolors\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_opacity_undefined_popup_highlight_3', {})
+
+ " light termguicolors
+ call term_sendkeys(buf, ":set background=light\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_opacity_undefined_popup_highlight_4', {})
+
+ " PopupColor only have fg color defined
+ call term_sendkeys(buf, ":highlight PopupColor ctermfg=DarkMagenta guifg=DarkMagenta\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_opacity_undefined_popup_highlight_5', {})
+
+ " termguicolors PopupColor only have fg color defined
+ call term_sendkeys(buf, ":set termguicolors\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_opacity_undefined_popup_highlight_6', {})
+
+ " termguicolors PopupColor only have bg color defined
+ call term_sendkeys(buf, ":highlight clear PopupColor\<CR>")
+ call TermWait(buf, 25)
+ call term_sendkeys(buf, ":highlight PopupColor ctermbg=DarkCyan guibg=DarkCyan\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_opacity_undefined_popup_highlight_7', {})
+
+ " PopupColor only have bg color defined
+ call term_sendkeys(buf, ":set notermguicolors\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_opacity_undefined_popup_highlight_8', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
+func Test_popup_opacity_only_cterm_or_gui_set()
+ CheckScreendump
+
+ let lines =<< trim END
+ call setline(1, repeat(['X X X X X'], 4))
+ highlight clear PopupColor
+ let g:pop_id = popup_create(['Popup'], #{
+ \ line: 2, col: 3,
+ \ minwidth: 10,
+ \ minheight: 2,
+ \ highlights: 'Normal:PopupColor',
+ \ opacity: 60,
+ \ zindex: 50,
+ \})
+ highlight PopupColor ctermbg=red
+ END
+ call writefile(lines, 'XtestPopupOpacityOnlyCtermOrGuiSet', 'D')
+ let buf = RunVimInTerminal('-S XtestPopupOpacityOnlyCtermOrGuiSet', #{rows: 12, cols: 60})
+ " cterm set and notermguicolors
+ call VerifyScreenDump(buf, 'Test_popup_opacity_only_cterm_or_gui_set_1', {})
+
+ " ctermbg set and termguicolors
+ call term_sendkeys(buf, ":set termguicolors\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_opacity_only_cterm_or_gui_set_2', {})
+
+ " guibg set and termguicolors
+ call term_sendkeys(buf, ":highlight PopupColor ctermbg=NONE guibg=red\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_opacity_only_cterm_or_gui_set_3', {})
+
+ " guibg set and notermguicolors
+ call term_sendkeys(buf, ":set notermguicolors\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_opacity_only_cterm_or_gui_set_4', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
+func Test_popup_opacity_attr()
+ CheckScreendump
+
+ let lines =<< trim END
+ highlight PopupBold cterm=bold gui=bold
+ highlight PopupBoldColor cterm=bold gui=bold ctermfg=red guifg=red
+ call setline(1, repeat(['X X X X X X X X X X'], 10))
+ call popup_create('bold', #{
+ \ line: 2, col: 3,
+ \ border: [1, 1, 1, 1],
+ \ minwidth: 20,
+ \ minheight: 2,
+ \ opacity: 60,
+ \ highlights: 'Normal:PopupBold',
+ \ })
+ call popup_create('boldcolor', #{
+ \ line: 6, col: 3,
+ \ border: [1, 1, 1, 1],
+ \ minwidth: 20,
+ \ minheight: 2,
+ \ opacity: 60,
+ \ highlights: 'Normal:PopupBoldColor',
+ \ })
+ END
+ call writefile(lines, 'XtestPopupOpacityAttr', 'D')
+ let buf = RunVimInTerminal('-S XtestPopupOpacityAttr', #{rows: 12, cols: 60})
+ " cterm set and notermguicolors
+ call VerifyScreenDump(buf, 'Test_popup_opacity_attr_1', {})
+
+ " ctermbg set and termguicolors
+ call term_sendkeys(buf, ":set termguicolors\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_opacity_attr_2', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
" vim: shiftwidth=2 sts=2
diff --git a/src/version.c b/src/version.c
index 9d7170c20..c9032621c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 602,
/**/
601,
/**/
Reply all
Reply to author
Forward
0 new messages