Do not send theme unless it has changed, and do not send immediately

when updates are enabled. GitHub issue 5787.
This commit is contained in:
nicm
2026-01-06 20:05:57 +00:00
parent 035a2f35d4
commit f226804149
4 changed files with 36 additions and 24 deletions

View File

@@ -314,12 +314,6 @@ static struct input_key_entry input_key_defaults[] = {
{ .key = KEYC_DC|KEYC_BUILD_MODIFIERS, { .key = KEYC_DC|KEYC_BUILD_MODIFIERS,
.data = "\033[3;_~" .data = "\033[3;_~"
}, },
{ .key = KEYC_REPORT_DARK_THEME,
.data = "\033[?997;1n"
},
{ .key = KEYC_REPORT_LIGHT_THEME,
.data = "\033[?997;2n"
},
}; };
static const key_code input_key_modifiers[] = { static const key_code input_key_modifiers[] = {
0, 0,

15
input.c
View File

@@ -1898,6 +1898,8 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
break; break;
case 2031: case 2031:
screen_write_mode_clear(sctx, MODE_THEME_UPDATES); screen_write_mode_clear(sctx, MODE_THEME_UPDATES);
if (ictx->wp != NULL)
ictx->wp->flags &= ~PANE_THEMECHANGED;
break; break;
case 2026: /* synchronized output */ case 2026: /* synchronized output */
screen_write_stop_sync(ictx->wp); screen_write_stop_sync(ictx->wp);
@@ -2001,6 +2003,10 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
break; break;
case 2031: case 2031:
screen_write_mode_set(sctx, MODE_THEME_UPDATES); screen_write_mode_set(sctx, MODE_THEME_UPDATES);
if (ictx->wp != NULL) {
ictx->wp->last_theme = window_pane_get_theme(ictx->wp);
ictx->wp->flags &= ~PANE_THEMECHANGED;
}
break; break;
case 2026: /* synchronized output */ case 2026: /* synchronized output */
screen_write_start_sync(ictx->wp); screen_write_start_sync(ictx->wp);
@@ -3397,9 +3403,11 @@ input_report_current_theme(struct input_ctx *ictx)
{ {
struct window_pane *wp = ictx->wp; struct window_pane *wp = ictx->wp;
if (wp == NULL) if (wp != NULL) {
return; wp->last_theme = window_pane_get_theme(wp);
switch (window_pane_get_theme(wp)) { wp->flags &= ~PANE_THEMECHANGED;
switch (wp->last_theme) {
case THEME_DARK: case THEME_DARK:
log_debug("%s: %%%u dark theme", __func__, wp->id); log_debug("%s: %%%u dark theme", __func__, wp->id);
input_reply(ictx, 0, "\033[?997;1n"); input_reply(ictx, 0, "\033[?997;1n");
@@ -3411,5 +3419,6 @@ input_report_current_theme(struct input_ctx *ictx)
case THEME_UNKNOWN: case THEME_UNKNOWN:
log_debug("%s: %%%u unknown theme", __func__, wp->id); log_debug("%s: %%%u unknown theme", __func__, wp->id);
break; break;
}
} }
} }

21
tmux.h
View File

@@ -1135,6 +1135,16 @@ struct window_pane_resize {
}; };
TAILQ_HEAD(window_pane_resizes, window_pane_resize); TAILQ_HEAD(window_pane_resizes, window_pane_resize);
/*
* Client theme, this is worked out from the background colour if not reported
* by terminal.
*/
enum client_theme {
THEME_UNKNOWN,
THEME_LIGHT,
THEME_DARK
};
/* Child window structure. */ /* Child window structure. */
struct window_pane { struct window_pane {
u_int id; u_int id;
@@ -1198,6 +1208,7 @@ struct window_pane {
struct grid_cell cached_gc; struct grid_cell cached_gc;
struct grid_cell cached_active_gc; struct grid_cell cached_active_gc;
struct colour_palette palette; struct colour_palette palette;
enum client_theme last_theme;
int pipe_fd; int pipe_fd;
struct bufferevent *pipe_event; struct bufferevent *pipe_event;
@@ -1876,16 +1887,6 @@ struct overlay_ranges {
u_int nx[OVERLAY_MAX_RANGES]; u_int nx[OVERLAY_MAX_RANGES];
}; };
/*
* Client theme, this is worked out from the background colour if not reported
* by terminal.
*/
enum client_theme {
THEME_UNKNOWN,
THEME_LIGHT,
THEME_DARK
};
/* Client connection. */ /* Client connection. */
typedef int (*prompt_input_cb)(struct client *, void *, const char *, int); typedef int (*prompt_input_cb)(struct client *, void *, const char *, int);
typedef void (*prompt_free_cb)(void *); typedef void (*prompt_free_cb)(void *);

View File

@@ -926,7 +926,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp = xcalloc(1, sizeof *wp); wp = xcalloc(1, sizeof *wp);
wp->window = w; wp->window = w;
wp->options = options_create(w->options); wp->options = options_create(w->options);
wp->flags = (PANE_STYLECHANGED|PANE_THEMECHANGED); wp->flags = PANE_STYLECHANGED;
wp->id = next_window_pane_id++; wp->id = next_window_pane_id++;
RB_INSERT(window_pane_tree, &all_window_panes, wp); RB_INSERT(window_pane_tree, &all_window_panes, wp);
@@ -1926,24 +1926,32 @@ window_pane_get_theme(struct window_pane *wp)
void void
window_pane_send_theme_update(struct window_pane *wp) window_pane_send_theme_update(struct window_pane *wp)
{ {
enum client_theme theme;
if (wp == NULL || window_pane_exited(wp)) if (wp == NULL || window_pane_exited(wp))
return; return;
if (~wp->flags & PANE_THEMECHANGED) if (~wp->flags & PANE_THEMECHANGED)
return; return;
if (~wp->screen->mode & MODE_THEME_UPDATES) if (~wp->screen->mode & MODE_THEME_UPDATES)
return; return;
switch (window_pane_get_theme(wp)) {
theme = window_pane_get_theme(wp);
if (theme == wp->last_theme)
return;
wp->last_theme = theme;
wp->flags &= ~PANE_THEMECHANGED;
switch (theme) {
case THEME_LIGHT: case THEME_LIGHT:
log_debug("%s: %%%u light theme", __func__, wp->id); log_debug("%s: %%%u light theme", __func__, wp->id);
input_key_pane(wp, KEYC_REPORT_LIGHT_THEME, NULL); bufferevent_write(wp->event, "\033[?997;2n", 9);
break; break;
case THEME_DARK: case THEME_DARK:
log_debug("%s: %%%u dark theme", __func__, wp->id); log_debug("%s: %%%u dark theme", __func__, wp->id);
input_key_pane(wp, KEYC_REPORT_DARK_THEME, NULL); bufferevent_write(wp->event, "\033[?997;1n", 9);
break; break;
case THEME_UNKNOWN: case THEME_UNKNOWN:
log_debug("%s: %%%u unknown theme", __func__, wp->id); log_debug("%s: %%%u unknown theme", __func__, wp->id);
break; break;
} }
wp->flags &= ~PANE_THEMECHANGED;
} }