key-bindings: add bindings to switch between color themes

* color-theme-switch-1: select the primary color theme
* color-theme-switch-2: select the alternative color theme
* color-theme-toggle: toggle between the primary and alternative color themes
This commit is contained in:
Daniel Eklöf 2025-04-20 07:58:02 +02:00
parent 1423babc35
commit 6bc91b5e28
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
8 changed files with 102 additions and 11 deletions

View file

@ -63,6 +63,16 @@
## Unreleased ## Unreleased
### Added ### Added
* `colors2` config section. This section duplicates the `colors`
section, and lets you define an alternative color theme.
* `key-bindings.color-theme-switch-1`,
`key-bindings.color-theme-switch-2` and
`key-bindings.color-theme-toggle` key bindings. These can be used to
switch between the primary and alternative color themes. They are
not bound by default.
### Changed ### Changed
* `cursor.color` moved to `colors.cursor`. * `cursor.color` moved to `colors.cursor`.

View file

@ -142,6 +142,9 @@ static const char *const binding_action_map[] = {
[BIND_ACTION_QUIT] = "quit", [BIND_ACTION_QUIT] = "quit",
[BIND_ACTION_REGEX_LAUNCH] = "regex-launch", [BIND_ACTION_REGEX_LAUNCH] = "regex-launch",
[BIND_ACTION_REGEX_COPY] = "regex-copy", [BIND_ACTION_REGEX_COPY] = "regex-copy",
[BIND_ACTION_THEME_SWITCH_1] = "color-theme-switch-1",
[BIND_ACTION_THEME_SWITCH_2] = "color-theme-switch-2",
[BIND_ACTION_THEME_TOGGLE] = "color-theme-toggle",
/* Mouse-specific actions */ /* Mouse-specific actions */
[BIND_ACTION_SCROLLBACK_UP_MOUSE] = "scrollback-up-mouse", [BIND_ACTION_SCROLLBACK_UP_MOUSE] = "scrollback-up-mouse",
@ -3479,6 +3482,7 @@ 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));
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

@ -1396,6 +1396,22 @@ e.g. *search-start=none*.
Default: _Control+Shift+u_. Default: _Control+Shift+u_.
*color-theme-switch-1*, *color-theme-switch-2*, *color-theme-toggle*
Switch between the primary color theme (defined in the *colors*
section), and the alternative color theme (defined in the
*colors2* section).
*color-theme-switch-1* applies the primary color theme regardless
of which color theme is currently active.
*color-theme-switch-2* applies the alternative color theme regardless
of which color theme is currently active.
*color-theme-toggle* toggles between the primary and alternative
color themes.
Default: _none_
*quit* *quit*
Quit foot. Default: _none_. Quit foot. Default: _none_.

View file

@ -212,6 +212,9 @@
# prompt-prev=Control+Shift+z # prompt-prev=Control+Shift+z
# prompt-next=Control+Shift+x # prompt-next=Control+Shift+x
# unicode-input=Control+Shift+u # unicode-input=Control+Shift+u
# color-theme-switch-1=none
# color-theme-switch-2=none
# color-theme-toggle=none
# noop=none # noop=none
# quit=none # quit=none

45
input.c
View file

@ -484,6 +484,51 @@ execute_binding(struct seat *seat, struct terminal *term,
return true; return true;
case BIND_ACTION_THEME_SWITCH_1:
if (term->colors.active_theme != COLOR_THEME1) {
term_theme_apply(term, &term->conf->colors);
term->colors.active_theme = COLOR_THEME1;
wayl_win_alpha_changed(term->window);
term_font_subpixel_changed(term);
term_damage_view(term);
term_damage_margins(term);
render_refresh(term);
}
return true;
case BIND_ACTION_THEME_SWITCH_2:
if (term->colors.active_theme != COLOR_THEME2) {
term_theme_apply(term, &term->conf->colors2);
term->colors.active_theme = COLOR_THEME2;
wayl_win_alpha_changed(term->window);
term_font_subpixel_changed(term);
term_damage_view(term);
term_damage_margins(term);
render_refresh(term);
}
return true;
case BIND_ACTION_THEME_TOGGLE:
if (term->colors.active_theme == COLOR_THEME1) {
term_theme_apply(term, &term->conf->colors2);
term->colors.active_theme = COLOR_THEME2;
} else {
term_theme_apply(term, &term->conf->colors);
term->colors.active_theme = COLOR_THEME1;
}
wayl_win_alpha_changed(term->window);
term_font_subpixel_changed(term);
term_damage_view(term);
term_damage_margins(term);
render_refresh(term);
return true;
case BIND_ACTION_SELECT_BEGIN: case BIND_ACTION_SELECT_BEGIN:
selection_start( selection_start(
term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE, false); term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE, false);

View file

@ -43,6 +43,9 @@ enum bind_action_normal {
BIND_ACTION_QUIT, BIND_ACTION_QUIT,
BIND_ACTION_REGEX_LAUNCH, BIND_ACTION_REGEX_LAUNCH,
BIND_ACTION_REGEX_COPY, BIND_ACTION_REGEX_COPY,
BIND_ACTION_THEME_SWITCH_1,
BIND_ACTION_THEME_SWITCH_2,
BIND_ACTION_THEME_TOGGLE,
/* Mouse specific actions - i.e. they require a mouse coordinate */ /* Mouse specific actions - i.e. they require a mouse coordinate */
BIND_ACTION_SCROLLBACK_UP_MOUSE, BIND_ACTION_SCROLLBACK_UP_MOUSE,
@ -56,7 +59,7 @@ enum bind_action_normal {
BIND_ACTION_SELECT_QUOTE, BIND_ACTION_SELECT_QUOTE,
BIND_ACTION_SELECT_ROW, BIND_ACTION_SELECT_ROW,
BIND_ACTION_KEY_COUNT = BIND_ACTION_REGEX_COPY + 1, BIND_ACTION_KEY_COUNT = BIND_ACTION_THEME_TOGGLE + 1,
BIND_ACTION_COUNT = BIND_ACTION_SELECT_ROW + 1, BIND_ACTION_COUNT = BIND_ACTION_SELECT_ROW + 1,
}; };

View file

@ -1303,6 +1303,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
.selection_fg = conf->colors.selection_fg, .selection_fg = conf->colors.selection_fg,
.selection_bg = conf->colors.selection_bg, .selection_bg = conf->colors.selection_bg,
.use_custom_selection = conf->colors.use_custom.selection, .use_custom_selection = conf->colors.use_custom.selection,
.active_theme = COLOR_THEME1,
}, },
.color_stack = { .color_stack = {
.stack = NULL, .stack = NULL,
@ -2150,16 +2151,8 @@ term_reset(struct terminal *term, bool hard)
term->flash.active = false; term->flash.active = false;
term->blink.state = BLINK_ON; term->blink.state = BLINK_ON;
fdm_del(term->fdm, term->blink.fd); term->blink.fd = -1; fdm_del(term->fdm, term->blink.fd); term->blink.fd = -1;
term->colors.fg = term->conf->colors.fg; term_theme_apply(term, &term->conf->colors);
term->colors.bg = term->conf->colors.bg; term->colors.active_theme = COLOR_THEME1;
term->colors.alpha = term->conf->colors.alpha;
term->colors.cursor_fg = (term->conf->colors.use_custom.cursor ? 1u << 31 : 0) | term->conf->colors.cursor.text;
term->colors.cursor_bg = (term->conf->colors.use_custom.cursor ? 1u << 31 : 0) | term->conf->colors.cursor.cursor;
term->colors.selection_fg = term->conf->colors.selection_fg;
term->colors.selection_bg = term->conf->colors.selection_bg;
term->colors.use_custom_selection = term->conf->colors.use_custom.selection;
memcpy(term->colors.table, term->conf->colors.table,
sizeof(term->colors.table));
free(term->color_stack.stack); free(term->color_stack.stack);
term->color_stack.stack = NULL; term->color_stack.stack = NULL;
term->color_stack.size = 0; term->color_stack.size = 0;
@ -4693,3 +4686,17 @@ term_send_size_notification(struct terminal *term)
term->rows, term->cols, height, width); term->rows, term->cols, height, width);
term_to_slave(term, buf, n); term_to_slave(term, buf, n);
} }
void
term_theme_apply(struct terminal *term, const struct color_theme *theme)
{
term->colors.fg = theme->fg;
term->colors.bg = theme->bg;
term->colors.alpha = theme->alpha;
term->colors.cursor_fg = (theme->use_custom.cursor ? 1u << 31 : 0) | theme->cursor.text;
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

@ -405,6 +405,7 @@ struct colors {
uint32_t selection_fg; uint32_t selection_fg;
uint32_t selection_bg; uint32_t selection_bg;
bool use_custom_selection; bool use_custom_selection;
enum { COLOR_THEME1, COLOR_THEME2 } active_theme;
}; };
struct terminal { struct terminal {
@ -982,6 +983,8 @@ void term_enable_size_notifications(struct terminal *term);
void term_disable_size_notifications(struct terminal *term); void term_disable_size_notifications(struct terminal *term);
void term_send_size_notification(struct terminal *term); void term_send_size_notification(struct terminal *term);
void term_theme_apply(struct terminal *term, const struct color_theme *theme);
static inline void term_reset_grapheme_state(struct terminal *term) static inline void term_reset_grapheme_state(struct terminal *term)
{ {
#if defined(FOOT_GRAPHEME_CLUSTERING) #if defined(FOOT_GRAPHEME_CLUSTERING)