config: add colors.dim-blend-towards=black|white

Before this patch, we always blended towards black when dimming
text. However, with light color themes, it usually looks better if we
dim towards white instead.

This option allows you to choose which color to blend towards.

The default is 'black' in '[colors]', and 'white' in '[colors2]'.

Closes #2187
This commit is contained in:
Daniel Eklöf 2025-10-10 11:10:38 +02:00
parent 371837ef7b
commit 7ed36c1033
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
7 changed files with 51 additions and 4 deletions

View file

@ -71,8 +71,12 @@
* Performance increased and input latency decreased on compositors * Performance increased and input latency decreased on compositors
that do not release SHM buffers immediately ([#2188][2188]). that do not release SHM buffers immediately ([#2188][2188]).
* `colors{,2}.dim-blend-towards=black|white` option, allowing you to
select towards which color to blend when dimming text. Defaults to
`black` in `[colors]`, and `white` in `[colors2]` ([#2187][2187]).
[2188]: https://codeberg.org/dnkl/foot/issues/2188 [2188]: https://codeberg.org/dnkl/foot/issues/2188
[2187]: https://codeberg.org/dnkl/foot/issues/2187
### Changed ### Changed

View file

@ -1519,7 +1519,7 @@ parse_color_theme(struct context *ctx, struct color_theme *theme)
return true; return true;
} }
else if (strcmp(key, "alpha-mode") == 0) { else if (streq(key, "alpha-mode")) {
_Static_assert(sizeof(theme->alpha_mode) == sizeof(int), _Static_assert(sizeof(theme->alpha_mode) == sizeof(int),
"enum is not 32-bit"); "enum is not 32-bit");
@ -1529,6 +1529,16 @@ parse_color_theme(struct context *ctx, struct color_theme *theme)
(int *)&theme->alpha_mode); (int *)&theme->alpha_mode);
} }
else if (streq(key, "dim-blend-towards")) {
_Static_assert(sizeof(theme->dim_blend_towards) == sizeof(int),
"enum is not 32-bit");
return value_to_enum(
ctx,
(const char *[]){"black", "white", NULL},
(int *)&theme->dim_blend_towards);
}
else { else {
LOG_CONTEXTUAL_ERR("not valid option"); LOG_CONTEXTUAL_ERR("not valid option");
return false; return false;
@ -3428,6 +3438,7 @@ config_load(struct config *conf, const char *conf_path,
.flash_alpha = 0x7fff, .flash_alpha = 0x7fff,
.alpha = 0xffff, .alpha = 0xffff,
.alpha_mode = ALPHA_MODE_DEFAULT, .alpha_mode = ALPHA_MODE_DEFAULT,
.dim_blend_towards = DIM_BLEND_TOWARDS_BLACK,
.selection_fg = 0x80000000, /* Use default bg */ .selection_fg = 0x80000000, /* Use default bg */
.selection_bg = 0x80000000, /* Use default fg */ .selection_bg = 0x80000000, /* Use default fg */
.cursor = { .cursor = {
@ -3523,6 +3534,8 @@ config_load(struct config *conf, const char *conf_path,
memcpy(conf->colors.table, default_color_table, sizeof(default_color_table)); memcpy(conf->colors.table, default_color_table, sizeof(default_color_table));
memcpy(conf->colors.sixel, default_sixel_colors, sizeof(default_sixel_colors)); memcpy(conf->colors.sixel, default_sixel_colors, sizeof(default_sixel_colors));
memcpy(&conf->colors2, &conf->colors, sizeof(conf->colors)); memcpy(&conf->colors2, &conf->colors, sizeof(conf->colors));
conf->colors2.dim_blend_towards = DIM_BLEND_TOWARDS_WHITE;
parse_modifiers(XKB_MOD_NAME_SHIFT, 5, &conf->mouse.selection_override_modifiers); parse_modifiers(XKB_MOD_NAME_SHIFT, 5, &conf->mouse.selection_override_modifiers);
tokenize_cmdline( tokenize_cmdline(

View file

@ -145,6 +145,11 @@ struct color_theme {
uint32_t dim[8]; uint32_t dim[8];
uint32_t sixel[16]; uint32_t sixel[16];
enum {
DIM_BLEND_TOWARDS_BLACK,
DIM_BLEND_TOWARDS_WHITE,
} dim_blend_towards;
enum { enum {
ALPHA_MODE_DEFAULT, ALPHA_MODE_DEFAULT,
ALPHA_MODE_MATCHING, ALPHA_MODE_MATCHING,

View file

@ -1031,7 +1031,8 @@ dark theme (since the default theme is dark).
a color value, and a "dim" attribute. a color value, and a "dim" attribute.
By default, foot implements this by blending the current color By default, foot implements this by blending the current color
with black. This is a generic approach that applies to both with black or white, depending on what the *dim-blend-towards*
option is set to . This is a generic approach that applies to both
colors from the 256-color palette, as well as 24-bit RGB colors. colors from the 256-color palette, as well as 24-bit RGB colors.
You can change this behavior by setting the *dimN* options. When You can change this behavior by setting the *dimN* options. When
@ -1086,6 +1087,14 @@ dark theme (since the default theme is dark).
Default: _default_ Default: _default_
*dim-blend-towards*
Which color to blend towards when "auto" dimming a color (see
*dim0*..*dim7* above). One of *black* or *white*. Blending towards
black makes the text darker, while blending towards white makes it
whiter (but still dimmer than normal text).
Default: _black_ (*colors*), _white_ (*colors2*)
*selection-foreground*, *selection-background* *selection-foreground*, *selection-background*
Foreground (text) and background color to use in selected Foreground (text) and background color to use in selected
text. Default: _inverse foreground/background_. text. Default: _inverse foreground/background_.
@ -1124,7 +1133,8 @@ dark theme (since the default theme is dark).
# SECTION: colors2 # SECTION: colors2
This section defines an alternative color theme. It has the exact same This section defines an alternative color theme. It has the exact same
keys as the *colors* section. The default values are the same. keys as the *colors* section. The default values are the same, except
for *dim-blend-towards*, which defaults to *white* instead.
Note that values are not inherited. That is, if you set a value in Note that values are not inherited. That is, if you set a value in
*colors*, but not in *colors2*, the value from *colors* is not *colors*, but not in *colors2*, the value from *colors* is not

View file

@ -132,6 +132,7 @@
# bright7=ffffff # bright white # bright7=ffffff # bright white
## dimmed colors (see foot.ini(5) man page) ## dimmed colors (see foot.ini(5) man page)
# dim-blend-towards=black
# dim0=<not set> # dim0=<not set>
# ... # ...
# dim7=<not-set> # dim7=<not-set>
@ -170,6 +171,8 @@
[colors2] [colors2]
# Alternative color theme, see man page foot.ini(5) # Alternative color theme, see man page foot.ini(5)
# Same builtin defaults as [color], except for:
# dim-blend-towards=white
[csd] [csd]
# preferred=server # preferred=server

View file

@ -312,7 +312,14 @@ color_dim(const struct terminal *term, uint32_t color)
} }
} }
return color_blend_towards(color, 0x00000000, conf->dim.amount); const struct color_theme *theme = term->colors.active_theme == COLOR_THEME1
? &conf->colors
: &conf->colors2;
return color_blend_towards(
color,
theme->dim_blend_towards == DIM_BLEND_TOWARDS_BLACK ? 0x00000000 : 0x00ffffff,
conf->dim.amount);
} }
static inline uint32_t static inline uint32_t

View file

@ -753,6 +753,11 @@ test_section_colors(void)
(int []){ALPHA_MODE_DEFAULT, ALPHA_MODE_MATCHING, ALPHA_MODE_ALL}, (int []){ALPHA_MODE_DEFAULT, ALPHA_MODE_MATCHING, ALPHA_MODE_ALL},
(int *)&conf.colors.alpha_mode); (int *)&conf.colors.alpha_mode);
test_enum(&ctx, &parse_section_colors, "dim-blend-towards", 2,
(const char *[]){"black", "white"},
(int []){DIM_BLEND_TOWARDS_BLACK, DIM_BLEND_TOWARDS_WHITE},
(int *)&conf.colors.dim_blend_towards);
for (size_t i = 0; i < 255; i++) { for (size_t i = 0; i < 255; i++) {
char key_name[4]; char key_name[4];
sprintf(key_name, "%zu", i); sprintf(key_name, "%zu", i);