render: refactor to allow setting only selection bg or fg

Before this, we only applied custom selection colors, if *both* the
selection bg and fg had been set.

Since the options are already split up into two separate options, and
since it makes sense to at least be able to keep the foreground colors
unchanged (i.e. only setting the selection background), let's allow
only having one of the selection colors set.

Closes #1846
This commit is contained in:
Daniel Eklöf 2025-05-05 12:43:02 +02:00
parent c037836bbd
commit 073b637d45
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
8 changed files with 68 additions and 60 deletions

View file

@ -103,6 +103,10 @@
current alpha value is, unchanged.
* `gamma-correct-blending=yes` now defaults to `16-bit` image buffers,
instead of `10-bit`.
* Allow setting either selection background, or selection foreground,
only ([#1846][1846]).
[1846]: https://codeberg.org/dnkl/foot/issues/1846
### Deprecated

View file

@ -3403,7 +3403,6 @@ config_load(struct config *conf, const char *conf_path,
.cursor = 0,
},
.use_custom = {
.selection = false,
.jump_label = false,
.scrollback_indicator = false,
.url = false,
@ -3593,10 +3592,6 @@ config_load(struct config *conf, const char *conf_path,
if (!config_override_apply(conf, overrides, errors_are_fatal))
ret = !errors_are_fatal;
conf->colors.use_custom.selection =
conf->colors.selection_fg >> 24 == 0 &&
conf->colors.selection_bg >> 24 == 0;
if (ret && conf->fonts[0].count == 0) {
struct config_font font;
if (!config_font_parse("monospace", &font)) {

View file

@ -180,7 +180,6 @@ struct color_theme {
struct {
bool cursor:1;
bool selection:1;
bool jump_label:1;
bool scrollback_indicator:1;
bool url:1;

View file

@ -1069,8 +1069,7 @@ dark theme (since the default theme is dark).
*selection-foreground*, *selection-background*
Foreground (text) and background color to use in selected
text. Note that *both* options must be set, or the default will be
used. Default: _inverse foreground/background_.
text. Default: _inverse foreground/background_.
*jump-labels*
Two color values specifying the foreground (text) and background

4
osc.c
View file

@ -1480,12 +1480,10 @@ osc_dispatch(struct terminal *term)
case 17:
term->colors.selection_bg = color;
term->colors.use_custom_selection = true;
break;
case 19:
term->colors.selection_fg = color;
term->colors.use_custom_selection = true;
break;
}
@ -1589,13 +1587,11 @@ osc_dispatch(struct terminal *term)
case 117:
LOG_DBG("resetting selection background color");
term->colors.selection_bg = term->conf->colors.selection_bg;
term->colors.use_custom_selection = term->conf->colors.use_custom.selection;
break;
case 119:
LOG_DBG("resetting selection foreground color");
term->colors.selection_fg = term->conf->colors.selection_fg;
term->colors.use_custom_selection = term->conf->colors.use_custom.selection;
break;
case 133:

108
render.c
View file

@ -694,51 +694,75 @@ render_cell(struct terminal *term, pixman_image_t *pix,
const int x = term->margins.left + col * width;
const int y = term->margins.top + row_no * height;
bool is_selected = cell->attrs.selected;
uint32_t _fg = 0;
uint32_t _bg = 0;
uint16_t alpha = 0xffff;
const bool is_selected = cell->attrs.selected;
/* Use cell specific color, if set, otherwise the default colors (possible reversed) */
switch (cell->attrs.fg_src) {
case COLOR_RGB:
_fg = cell->attrs.fg;
break;
case COLOR_BASE16:
case COLOR_BASE256:
xassert(cell->attrs.fg < ALEN(term->colors.table));
_fg = term->colors.table[cell->attrs.fg];
break;
case COLOR_DEFAULT:
_fg = term->reverse ? term->colors.bg : term->colors.fg;
break;
}
switch (cell->attrs.bg_src) {
case COLOR_RGB:
_bg = cell->attrs.bg;
break;
case COLOR_BASE16:
case COLOR_BASE256:
xassert(cell->attrs.bg < ALEN(term->colors.table));
_bg = term->colors.table[cell->attrs.bg];
break;
case COLOR_DEFAULT:
_bg = term->reverse ? term->colors.fg : term->colors.bg;
break;
}
if (unlikely(is_selected)) {
const uint32_t cell_fg = _fg;
const uint32_t cell_bg = _bg;
const bool custom_fg = term->colors.selection_fg >> 24 == 0;
const bool custom_bg = term->colors.selection_bg >> 24 == 0;
const bool custom_both = custom_fg && custom_bg;
if (custom_both) {
_fg = term->colors.selection_fg;
_bg = term->colors.selection_bg;
} else if (custom_bg) {
_bg = term->colors.selection_bg;
_fg = cell->attrs.reverse ? cell_bg : cell_fg;
} else if (custom_fg) {
_fg = term->colors.selection_fg;
_bg = cell->attrs.reverse ? cell_fg : cell_bg;
} else {
_bg = cell_fg;
_fg = cell_bg;
}
if (unlikely(_fg == _bg)) {
/* Invert bg when selected/highlighted text has same fg/bg */
_bg = ~_bg;
alpha = 0xffff;
}
if (is_selected && term->colors.use_custom_selection) {
_fg = term->colors.selection_fg;
_bg = term->colors.selection_bg;
} else {
/* Use cell specific color, if set, otherwise the default colors (possible reversed) */
switch (cell->attrs.fg_src) {
case COLOR_RGB:
_fg = cell->attrs.fg;
break;
case COLOR_BASE16:
case COLOR_BASE256:
xassert(cell->attrs.fg < ALEN(term->colors.table));
_fg = term->colors.table[cell->attrs.fg];
break;
case COLOR_DEFAULT:
_fg = term->reverse ? term->colors.bg : term->colors.fg;
break;
}
switch (cell->attrs.bg_src) {
case COLOR_RGB:
_bg = cell->attrs.bg;
break;
case COLOR_BASE16:
case COLOR_BASE256:
xassert(cell->attrs.bg < ALEN(term->colors.table));
_bg = term->colors.table[cell->attrs.bg];
break;
case COLOR_DEFAULT:
_bg = term->reverse ? term->colors.fg : term->colors.bg;
break;
}
if (cell->attrs.reverse ^ is_selected) {
if (unlikely(cell->attrs.reverse)) {
uint32_t swap = _fg;
_fg = _bg;
_bg = swap;
@ -806,12 +830,6 @@ render_cell(struct terminal *term, pixman_image_t *pix,
}
}
if (unlikely(is_selected && _fg == _bg)) {
/* Invert bg when selected/highlighted text has same fg/bg */
_bg = ~_bg;
alpha = 0xffff;
}
if (cell->attrs.dim)
_fg = color_dim(term, _fg);
if (term->conf->bold_in_bright.enabled && cell->attrs.bold)

View file

@ -1312,7 +1312,6 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
.cursor_bg = (theme->use_custom.cursor ? 1u << 31 : 0) | theme->cursor.cursor,
.selection_fg = theme->selection_fg,
.selection_bg = theme->selection_bg,
.use_custom_selection = theme->use_custom.selection,
.active_theme = conf->initial_color_theme,
},
.color_stack = {
@ -4714,6 +4713,5 @@ term_theme_apply(struct terminal *term, const struct color_theme *theme)
term->colors.cursor_bg = (theme->use_custom.cursor ? 1u << 31 : 0) | theme->cursor.cursor;
term->colors.selection_fg = theme->selection_fg;
term->colors.selection_bg = theme->selection_bg;
term->colors.use_custom_selection = theme->use_custom.selection;
memcpy(term->colors.table, theme->table, sizeof(term->colors.table));
}

View file

@ -404,7 +404,6 @@ struct colors {
uint32_t cursor_bg; /* cursor color */
uint32_t selection_fg;
uint32_t selection_bg;
bool use_custom_selection;
enum which_color_theme active_theme;
};