diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c03555d..e2ed7fd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,8 @@ * `[csd].border-width` and `[csd].border-color`, allowing you to configure the width and color of the CSD border. * Support for `XTMODKEYS` with `Pp=4` and `Pv=2` (_modifyOtherKeys=2_). +* `[colors].dim0-7` options, allowing you to configure custom “dim” + colors (https://codeberg.org/dnkl/foot/issues/776). ### Changed diff --git a/config.c b/config.c index 028c91bc..265f9379 100644 --- a/config.c +++ b/config.c @@ -1290,6 +1290,14 @@ parse_section_colors(struct context *ctx) else if (key_len == 7 && str_has_prefix(key, "bright") && last_digit < 8) color = &conf->colors.table[8 + last_digit]; + else if (key_len == 4 && str_has_prefix(key, "dim") && last_digit < 8) { + if (!value_to_color(ctx, &conf->colors.dim[last_digit], false)) + return false; + + conf->colors.use_custom.dim |= 1 << last_digit; + return true; + } + else if (strcmp(key, "foreground") == 0) color = &conf->colors.fg; else if (strcmp(key, "background") == 0) color = &conf->colors.bg; else if (strcmp(key, "selection-foreground") == 0) color = &conf->colors.selection_fg; diff --git a/config.h b/config.h index f0f95035..652f8422 100644 --- a/config.h +++ b/config.h @@ -158,6 +158,8 @@ struct config { uint32_t selection_bg; uint32_t url; + uint32_t dim[8]; + struct { uint32_t fg; uint32_t bg; @@ -173,6 +175,7 @@ struct config { bool jump_label:1; bool scrollback_indicator:1; bool url:1; + uint8_t dim; } use_custom; } colors; diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 1e38b036..9f5c429b 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -499,6 +499,36 @@ can configure the background transparency with the _alpha_ option. _bfebbf_, _f0dfaf_, _8cd0d3_, _fcace3_, _b3ffff_ and _ffffff_ (a variant of the _zenburn_ theme). +*dim0*, *dim1* *..* *dim7* + Custom colors to use with dimmed colors. Dimmed colors do not have + an entry in the color palette. Applications emit them by combining + a color value, and a "dim" attribute. + + By default, foot implements this by reducing the luminance of the + current color. This is a generic approach that applies to both + colors from the 256-color palette, as well as 24-bit RGB colors. + + You can change this behavior by setting the *dimN* options. When + set, foot will match the current color against the color palette, + and if it matches one of the *regularN* colors, the corresponding + *dimN* color will be used. + + If instead the current color matches one of the *brightN* colors, + the corresponding *regularn* color will be used. + + If the current color does not match any known colors, it is dimmed + by reducing the luminance (i.e. the same behavior as if the *dimN* + options are unconfigured). 24-bit RGB colors will typically fall + into this category. + + Note that applications can change the *regularN* and *brighN* + colors at runtime. However, they have no way of changing the + *dimN* colors. If an application has changed the *regularN* + colors, foot will still use the corresponding *dimN* color, as + configured in foot.ini. + + Default: _not set_. + *0* *..* *255* Arbitrary colors in the 256-color palette. Default: for *0* *..* *15*, see regular and bright defaults above; see diff --git a/foot.ini b/foot.ini index acd066a7..09049b68 100644 --- a/foot.ini +++ b/foot.ini @@ -68,6 +68,8 @@ # alpha=1.0 # foreground=dcdccc # background=111111 + +## Normal/regular colors (color palette 0-7) # regular0=222222 # black # regular1=cc9393 # red # regular2=7f9f7f # green @@ -76,6 +78,8 @@ # regular5=dc8cc3 # magenta # regular6=93e0e3 # cyan # regular7=dcdccc # white + +## Bright colors (color palette 8-15) # bright0=666666 # bright black # bright1=dca3a3 # bright red # bright2=bfebbf # bright green @@ -84,9 +88,18 @@ # bright5=fcace3 # bright magenta # bright6=b3ffff # bright cyan # bright7=ffffff # bright white + +## dimmed colors (see foot.ini(5) man page) +# dim0= +# ... +# dim7= + +## The remaining 256-color palette # 16 = <256-color palette #16> # ... # 255 = <256-color palette #255> + +## Misc colors # selection-foreground= # selection-background= # jump-labels= diff --git a/render.c b/render.c index 39957de8..46cc0f75 100644 --- a/render.c +++ b/render.c @@ -244,7 +244,7 @@ color_hex_to_pixman(uint32_t color) } static inline uint32_t -color_dim(uint32_t color) +color_decrease_luminance(uint32_t color) { uint32_t alpha = color & 0xff000000; int hue, sat, lum; @@ -252,6 +252,33 @@ color_dim(uint32_t color) return alpha | hsl_to_rgb(hue, sat, lum / 1.5); } +static inline uint32_t +color_dim(const struct terminal *term, uint32_t color) +{ + const struct config *conf = term->conf; + const uint8_t custom_dim = conf->colors.use_custom.dim; + + if (likely(custom_dim == 0)) + return color_decrease_luminance(color); + + for (size_t i = 0; i < 8; i++) { + if (((custom_dim >> i) & 1) == 0) + continue; + + if (term->colors.table[0 + i] == color) { + /* “Regular” color, return the corresponding “dim” */ + return conf->colors.dim[i]; + } + + else if (term->colors.table[8 + i] == color) { + /* “Bright” color, return the corresponding “regular” */ + return term->colors.table[i]; + } + } + + return color_decrease_luminance(color); +} + static inline uint32_t color_brighten(const struct terminal *term, uint32_t color) { @@ -485,12 +512,12 @@ render_cell(struct terminal *term, pixman_image_t *pix, } if (cell->attrs.dim) - _fg = color_dim(_fg); + _fg = color_dim(term, _fg); if (term->conf->bold_in_bright.enabled && cell->attrs.bold) _fg = color_brighten(term, _fg); if (cell->attrs.blink && term->blink.state == BLINK_OFF) - _fg = color_dim(_fg); + _fg = color_decrease_luminance(_fg); pixman_color_t fg = color_hex_to_pixman(_fg); pixman_color_t bg = color_hex_to_pixman_with_alpha(_bg, alpha); @@ -779,7 +806,7 @@ render_urgency(struct terminal *term, struct buffer *buf) { uint32_t red = term->colors.table[1]; if (term->is_searching) - red = color_dim(red); + red = color_decrease_luminance(red); pixman_color_t bg = color_hex_to_pixman(red); @@ -1685,8 +1712,8 @@ render_csd_title(struct terminal *term, const struct csd_data *info, : term->conf->colors.bg; if (!term->visual_focus) { - bg = color_dim(bg); - fg = color_dim(fg); + bg = color_dim(term, bg); + fg = color_dim(term, fg); } const wchar_t *title_text = L""; @@ -2001,7 +2028,7 @@ render_csd_button(struct terminal *term, enum csd_surface surf_idx, } if (!term->visual_focus) - _color = color_dim(_color); + _color = color_dim(term, _color); pixman_color_t color = color_hex_to_pixman_with_alpha(_color, alpha); render_csd_part(term, surf, buf, info->width, info->height, &color); diff --git a/terminal.c b/terminal.c index 55c29f40..df8128fc 100644 --- a/terminal.c +++ b/terminal.c @@ -1253,8 +1253,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, term->scale = it->item.scale; } - memcpy(term->colors.table, term->conf->colors.table, - sizeof(term->colors.table)); + memcpy(term->colors.table, term->conf->colors.table, sizeof(term->colors.table)); /* Initialize the Wayland window backend */ if ((term->window = wayl_win_init(term, token)) == NULL)