Skip to content

Commit 7a02784

Browse files
shadowwachrisbra
authored andcommitted
patch 9.2.0545: popup: blending uses hardcoded fallback colors
Problem: Popup with opacity fades to black regardless of the colorscheme or 'background' option. With a light colorscheme (or the default with background=light), lower opacity values darken the popup and it no longer matches the Normal background. Solution: Compute fallback foreground and background colors from guifg/guibg, ctermfg/ctermbg, or deduce from the 'background' option, and use them in the popup blending paths instead of hardcoded white/black (Shad). closes: #20285 Signed-off-by: Shad <shadow.walker@free.fr> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent f85892e commit 7a02784

22 files changed

Lines changed: 204 additions & 64 deletions

src/globals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,8 @@ EXTERN guicolor_T cterm_normal_fg_gui_color INIT(= INVALCOLOR);
853853
EXTERN guicolor_T cterm_normal_bg_gui_color INIT(= INVALCOLOR);
854854
EXTERN guicolor_T cterm_normal_ul_gui_color INIT(= INVALCOLOR);
855855
#endif
856+
EXTERN guicolor_T fallback_fg_rgb INIT(= INVALCOLOR); // RGB fallback foreground color from guifg, ctermfg or deduced from 'background'
857+
EXTERN guicolor_T fallback_bg_rgb INIT(= INVALCOLOR); // RGB fallback background color from guibg, ctermbg or deduced from 'background'
856858
#ifdef FEAT_TERMRESPONSE
857859
EXTERN int is_mac_terminal INIT(= FALSE); // recognized Terminal.app
858860
#endif

src/highlight.c

Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,9 @@ highlight_link_id(int id)
533533
}
534534
#endif
535535

536+
static void resolve_fallback_fg_to_rgb(void);
537+
static void resolve_fallback_bg_to_rgb(void);
538+
536539
void
537540
init_highlight(
538541
int both, // include groups where 'bg' doesn't matter
@@ -616,6 +619,8 @@ init_highlight(
616619
}
617620
}
618621
#endif
622+
resolve_fallback_fg_to_rgb();
623+
resolve_fallback_bg_to_rgb();
619624
}
620625

621626
#if defined(FEAT_EVAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS))
@@ -1977,6 +1982,8 @@ do_highlight(
19771982
redraw_all_later(UPD_NOT_VALID);
19781983
}
19791984
#endif
1985+
resolve_fallback_fg_to_rgb();
1986+
resolve_fallback_bg_to_rgb();
19801987
#ifdef FEAT_VTP
19811988
control_console_color_rgb();
19821989
#endif
@@ -2091,6 +2098,8 @@ restore_cterm_colors(void)
20912098
cterm_normal_bg_gui_color = INVALCOLOR;
20922099
cterm_normal_ul_gui_color = INVALCOLOR;
20932100
# endif
2101+
fallback_fg_rgb = INVALCOLOR;
2102+
fallback_bg_rgb = INVALCOLOR;
20942103
#endif
20952104
}
20962105

@@ -3259,6 +3268,53 @@ resolve_color_to_rgb(int cterm_c, guicolor_T rgb UNUSED, int *r, int *g, int *b)
32593268
return false;
32603269
}
32613270

3271+
/*
3272+
* get a RGB fallback color from gui, cterm or default color
3273+
*/
3274+
static guicolor_T
3275+
resolve_fallback_color(int cterm_c, guicolor_T rgb, guicolor_T default_rgb)
3276+
{
3277+
int red, green, blue;
3278+
if (!resolve_color_to_rgb(cterm_c, rgb, &red, &green, &blue))
3279+
return default_rgb;
3280+
else
3281+
return (red << 16) | (green << 8) | blue;
3282+
}
3283+
3284+
/*
3285+
* get a RGB fallback foreground color from guifg, ctermfg or deduced from background
3286+
*/
3287+
static void
3288+
resolve_fallback_fg_to_rgb(void)
3289+
{
3290+
guicolor_T fgcolor_or_gui_fgcolor = INVALCOLOR;
3291+
#ifdef FEAT_TERMGUICOLORS
3292+
fgcolor_or_gui_fgcolor = cterm_normal_fg_gui_color;
3293+
#endif
3294+
#ifdef FEAT_GUI
3295+
if (gui.in_use)
3296+
fgcolor_or_gui_fgcolor = gui.norm_pixel;
3297+
#endif
3298+
fallback_fg_rgb = resolve_fallback_color(cterm_normal_fg_color, fgcolor_or_gui_fgcolor, (*p_bg == 'l') ? 0x000000 : 0xFFFFFF);
3299+
}
3300+
3301+
/*
3302+
* get a RGB fallback background color from guifg, ctermbg or deduced from background
3303+
*/
3304+
static void
3305+
resolve_fallback_bg_to_rgb(void)
3306+
{
3307+
guicolor_T bgcolor_or_gui_bgcolor = INVALCOLOR;
3308+
#ifdef FEAT_TERMGUICOLORS
3309+
bgcolor_or_gui_bgcolor = cterm_normal_bg_gui_color;
3310+
#endif
3311+
#ifdef FEAT_GUI
3312+
if (gui.in_use)
3313+
bgcolor_or_gui_bgcolor = gui.back_pixel;
3314+
#endif
3315+
fallback_bg_rgb = resolve_fallback_color(cterm_normal_bg_color, bgcolor_or_gui_bgcolor, (*p_bg == 'l') ? 0xFFFFFF : 0x000000);
3316+
}
3317+
32623318
/*
32633319
* Blend two colors expressed as (cterm 256 index, gui RGB) pairs and
32643320
* return the nearest 1-based cterm 256-color index. Prefers the gui
@@ -3325,14 +3381,7 @@ blend_colors(guicolor_T popup_color, guicolor_T bg_color, int blend_val)
33253381
b1 = popup_color & 0xFF;
33263382

33273383
if (COLOR_INVALID(bg_color))
3328-
{
3329-
// Background color unknown: fade popup color to black as blend increases
3330-
// This makes background text more visible at high blend values
3331-
r = r1 * (100 - blend_val) / 100;
3332-
g = g1 * (100 - blend_val) / 100;
3333-
b = b1 * (100 - blend_val) / 100;
3334-
return (r << 16) | (g << 8) | b;
3335-
}
3384+
bg_color = fallback_bg_rgb;
33363385

33373386
r2 = (bg_color >> 16) & 0xFF;
33383387
g2 = (bg_color >> 8) & 0xFF;
@@ -3392,7 +3441,7 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
33923441
// blend_fg=TRUE: fade underlying text toward popup bg.
33933442
if (popup_aep->ae_u.gui.bg_color != INVALCOLOR)
33943443
{
3395-
int base_fg = 0xFFFFFF;
3444+
int base_fg = fallback_fg_rgb;
33963445
if (char_aep != NULL
33973446
&& char_aep->ae_u.gui.fg_color != INVALCOLOR)
33983447
base_fg = char_aep->ae_u.gui.fg_color;
@@ -3414,7 +3463,7 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
34143463
// Blend background color: blend popup bg toward underlying bg
34153464
if (popup_aep->ae_u.gui.bg_color != INVALCOLOR)
34163465
{
3417-
guicolor_T underlying_bg = INVALCOLOR;
3466+
guicolor_T underlying_bg = fallback_bg_rgb;
34183467
if (char_aep != NULL)
34193468
underlying_bg = char_aep->ae_u.gui.bg_color;
34203469
new_en.ae_u.gui.bg_color = blend_colors(
@@ -3489,7 +3538,7 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
34893538
#endif
34903539
new_en.ae_u.cterm.fg_color = blend_cterm_colors(
34913540
popup_aep->ae_u.cterm.bg_color, popup_bg_rgb,
3492-
under_fg, under_fg_rgb, 0xFFFFFF, blend);
3541+
under_fg, under_fg_rgb, fallback_fg_rgb, blend);
34933542
}
34943543
// Approximate cterm bg by blending with the underlying bg
34953544
// in the 256-color palette and mapping to the nearest entry.
@@ -3505,7 +3554,7 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
35053554
#endif
35063555
new_en.ae_u.cterm.bg_color = blend_cterm_colors(
35073556
popup_aep->ae_u.cterm.bg_color, popup_bg_rgb,
3508-
under_bg, under_bg_rgb, 0x000000, blend);
3557+
under_bg, under_bg_rgb, fallback_bg_rgb, blend);
35093558
}
35103559
#ifdef FEAT_TERMGUICOLORS
35113560
// Blend RGB colors for termguicolors mode.
@@ -3529,7 +3578,7 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
35293578
// blend_fg=TRUE: fade underlying text toward popup bg.
35303579
if (popup_bg != INVALCOLOR)
35313580
{
3532-
int base_fg = 0xFFFFFF;
3581+
int base_fg = fallback_fg_rgb;
35333582
// CTERMCOLOR is a sentinel meaning "use the cterm
35343583
// color"; treat it as no underlying color so it is
35353584
// not blended in as a real near-white pixel.
@@ -3554,12 +3603,12 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
35543603
else if (!COLOR_INVALID(cterm_normal_fg_gui_color))
35553604
new_en.ae_u.cterm.fg_rgb = cterm_normal_fg_gui_color;
35563605
else
3557-
new_en.ae_u.cterm.fg_rgb = 0xFFFFFF;
3606+
new_en.ae_u.cterm.fg_rgb = fallback_fg_rgb;
35583607
}
35593608
if (popup_bg != INVALCOLOR)
35603609
{
35613610
// Blend popup bg toward underlying bg
3562-
guicolor_T underlying_bg = INVALCOLOR;
3611+
guicolor_T underlying_bg = fallback_bg_rgb;
35633612
if (char_aep != NULL
35643613
&& !COLOR_INVALID(char_aep->ae_u.cterm.bg_rgb))
35653614
underlying_bg = char_aep->ae_u.cterm.bg_rgb;
@@ -3626,7 +3675,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
36263675
// blend=100 (transparent): fg = underlying_fg (text visible)
36273676
if (popup_aep->ae_u.gui.bg_color != INVALCOLOR)
36283677
{
3629-
int base_fg = 0xFFFFFF;
3678+
int base_fg = fallback_fg_rgb;
36303679
if (char_aep != NULL
36313680
&& char_aep->ae_u.gui.fg_color != INVALCOLOR)
36323681
base_fg = char_aep->ae_u.gui.fg_color;
@@ -3636,7 +3685,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
36363685
// Blend bg: popup bg toward underlying bg.
36373686
if (popup_aep->ae_u.gui.bg_color != INVALCOLOR)
36383687
{
3639-
guicolor_T underlying_bg = INVALCOLOR;
3688+
guicolor_T underlying_bg = fallback_bg_rgb;
36403689
if (char_aep != NULL)
36413690
underlying_bg = char_aep->ae_u.gui.bg_color;
36423691
new_en.ae_u.gui.bg_color = blend_colors(
@@ -3685,7 +3734,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
36853734
#endif
36863735
new_en.ae_u.cterm.fg_color = blend_cterm_colors(
36873736
popup_aep->ae_u.cterm.bg_color, popup_bg_rgb,
3688-
under_fg, under_fg_rgb, 0xFFFFFF, blend);
3737+
under_fg, under_fg_rgb, fallback_fg_rgb, blend);
36893738
}
36903739
// Approximate cterm bg by blending with the underlying bg
36913740
// in the 256-color palette and mapping to the nearest entry.
@@ -3701,7 +3750,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
37013750
#endif
37023751
new_en.ae_u.cterm.bg_color = blend_cterm_colors(
37033752
popup_aep->ae_u.cterm.bg_color, popup_bg_rgb,
3704-
under_bg, under_bg_rgb, 0x000000, blend);
3753+
under_bg, under_bg_rgb, fallback_bg_rgb, blend);
37053754
}
37063755
#ifdef FEAT_TERMGUICOLORS
37073756
// Blend fg_rgb: pum_bg toward underlying_fg.
@@ -3710,7 +3759,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
37103759
// as a real near-white pixel.
37113760
if (popup_aep->ae_u.cterm.bg_rgb != INVALCOLOR)
37123761
{
3713-
int base_fg = 0xFFFFFF;
3762+
int base_fg = fallback_fg_rgb;
37143763
if (char_aep != NULL
37153764
&& !COLOR_INVALID(char_aep->ae_u.cterm.fg_rgb))
37163765
base_fg = char_aep->ae_u.cterm.fg_rgb;
@@ -3720,7 +3769,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
37203769
// Blend bg_rgb.
37213770
if (popup_aep->ae_u.cterm.bg_rgb != INVALCOLOR)
37223771
{
3723-
guicolor_T underlying_bg = INVALCOLOR;
3772+
guicolor_T underlying_bg = fallback_bg_rgb;
37243773
if (char_aep != NULL
37253774
&& !COLOR_INVALID(char_aep->ae_u.cterm.bg_rgb))
37263775
underlying_bg = char_aep->ae_u.cterm.bg_rgb;

src/testdir/dumps/Test_popup_opacity_move_after_close.dump

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/testdir/dumps/Test_popupwin_opacity_fade_to_background_1.dump

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/testdir/dumps/Test_popupwin_opacity_fade_to_background_2.dump

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/testdir/dumps/Test_popupwin_opacity_fade_to_background_3.dump

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/testdir/dumps/Test_popupwin_opacity_fade_to_background_4.dump

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/testdir/dumps/Test_popupwin_opacity_hl_80.dump

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/testdir/dumps/Test_popupwin_opacity_textprop_undercurl.dump

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/testdir/dumps/Test_popupwin_opacity_vsplit_1.dump

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)