diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2024-06-24 08:30:51 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2024-06-24 08:30:51 +0000 |
commit | 132f85ccf7097bf15f5ce65ae98945cfac3bddbd (patch) | |
tree | eed845ac5b9d5a83f60fda2bb105907a97b47cd5 /usr.bin/tmux | |
parent | 2a7a8adb5207815aa587adf240e8ea8a74d5aca3 (diff) |
Add a way (refresh-client -r) for control mode clients to provide OSC 10
and 11 responses to tmux so they can set the default foreground and
background colours, from George Nachman in GitHub issue 4014.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r-- | usr.bin/tmux/cmd-refresh-client.c | 37 | ||||
-rw-r--r-- | usr.bin/tmux/input.c | 66 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 11 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 7 | ||||
-rw-r--r-- | usr.bin/tmux/tty-keys.c | 24 | ||||
-rw-r--r-- | usr.bin/tmux/window.c | 5 |
6 files changed, 123 insertions, 27 deletions
diff --git a/usr.bin/tmux/cmd-refresh-client.c b/usr.bin/tmux/cmd-refresh-client.c index e1af3e859e4..04e5178bd8a 100644 --- a/usr.bin/tmux/cmd-refresh-client.c +++ b/usr.bin/tmux/cmd-refresh-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-refresh-client.c,v 1.48 2022/05/30 12:55:25 nicm Exp $ */ +/* $OpenBSD: cmd-refresh-client.c,v 1.49 2024/06/24 08:30:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -34,9 +34,10 @@ const struct cmd_entry cmd_refresh_client_entry = { .name = "refresh-client", .alias = "refresh", - .args = { "A:B:cC:Df:F:l::LRSt:U", 0, 1, NULL }, + .args = { "A:B:cC:Df:r:F:l::LRSt:U", 0, 1, NULL }, .usage = "[-cDlLRSU] [-A pane:state] [-B name:what:format] " - "[-C XxY] [-f flags] " CMD_TARGET_CLIENT_USAGE " [adjustment]", + "[-C XxY] [-f flags] [-r pane:report]" CMD_TARGET_CLIENT_USAGE + " [adjustment]", .flags = CMD_AFTERHOOK|CMD_CLIENT_TFLAG, .exec = cmd_refresh_client_exec @@ -193,6 +194,34 @@ cmd_refresh_client_clipboard(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_NORMAL); } +static void +cmd_refresh_report(struct tty *tty, const char *value) +{ + struct window_pane *wp; + u_int pane; + size_t size = 0; + char *copy, *split; + + if (*value != '%') + return; + copy = xstrdup(value); + if ((split = strchr(copy, ':')) == NULL) + goto out; + *split++ = '\0'; + + if (sscanf(copy, "%%%u", &pane) != 1) + goto out; + wp = window_pane_find_by_id(pane); + if (wp == NULL) + goto out; + + tty_keys_colours(tty, split, strlen(split), &size, &wp->control_fg, + &wp->control_bg); + +out: + free(copy); +} + static enum cmd_retval cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item) { @@ -262,6 +291,8 @@ cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item) server_client_set_flags(tc, args_get(args, 'F')); if (args_has(args, 'f')) server_client_set_flags(tc, args_get(args, 'f')); + if (args_has(args, 'r')) + cmd_refresh_report(tty, args_get(args, 'r')); if (args_has(args, 'A')) { if (~tc->flags & CLIENT_CONTROL) diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c index 6d67917f47d..7ee811379d8 100644 --- a/usr.bin/tmux/input.c +++ b/usr.bin/tmux/input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input.c,v 1.224 2024/04/10 07:36:25 nicm Exp $ */ +/* $OpenBSD: input.c,v 1.225 2024/06/24 08:30:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -2652,6 +2652,44 @@ input_get_bg_client(struct window_pane *wp) return (-1); } +/* + * If any control mode client exists that has provided a bg color, return it. + * Otherwise, return -1. + */ +static int +input_get_bg_control_client(struct window_pane *wp) +{ + struct client *c; + + if (wp->control_bg == -1) + return (-1); + + TAILQ_FOREACH(c, &clients, entry) { + if (c->flags & CLIENT_CONTROL) + return (wp->control_bg); + } + return (-1); +} + +/* + * If any control mode client exists that has provided a fg color, return it. + * Otherwise, return -1. + */ +static int +input_get_fg_control_client(struct window_pane *wp) +{ + struct client *c; + + if (wp->control_fg == -1) + return (-1); + + TAILQ_FOREACH(c, &clients, entry) { + if (c->flags & CLIENT_CONTROL) + return (wp->control_fg); + } + return (-1); +} + /* Handle the OSC 10 sequence for setting and querying foreground colour. */ static void input_osc_10(struct input_ctx *ictx, const char *p) @@ -2663,11 +2701,14 @@ input_osc_10(struct input_ctx *ictx, const char *p) if (strcmp(p, "?") == 0) { if (wp == NULL) return; - tty_default_colours(&defaults, wp); - if (COLOUR_DEFAULT(defaults.fg)) - c = input_get_fg_client(wp); - else - c = defaults.fg; + c = input_get_fg_control_client(wp); + if (c == -1) { + tty_default_colours(&defaults, wp); + if (COLOUR_DEFAULT(defaults.fg)) + c = input_get_fg_client(wp); + else + c = defaults.fg; + } input_osc_colour_reply(ictx, 10, c); return; } @@ -2711,11 +2752,14 @@ input_osc_11(struct input_ctx *ictx, const char *p) if (strcmp(p, "?") == 0) { if (wp == NULL) return; - tty_default_colours(&defaults, wp); - if (COLOUR_DEFAULT(defaults.bg)) - c = input_get_bg_client(wp); - else - c = defaults.bg; + c = input_get_bg_control_client(wp); + if (c == -1) { + tty_default_colours(&defaults, wp); + if (COLOUR_DEFAULT(defaults.bg)) + c = input_get_bg_client(wp); + else + c = defaults.bg; + } input_osc_colour_reply(ictx, 11, c); return; } diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 2185dc7cfc8..351208a70f6 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.945 2024/05/24 12:39:06 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.946 2024/06/24 08:30:50 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: May 24 2024 $ +.Dd $Mdocdate: June 24 2024 $ .Dt TMUX 1 .Os .Sh NAME @@ -1357,6 +1357,7 @@ specified multiple times. .Op Fl B Ar name:what:format .Op Fl C Ar size .Op Fl f Ar flags +.Op Fl r Ar pane:report .Op Fl l Op Ar target-pane .Op Fl t Ar target-client .Op Ar adjustment @@ -1467,6 +1468,12 @@ for all windows in the attached session. .Fl f sets a comma-separated list of client flags, see .Ic attach-session . +.Fl r +allows a control mode client to provide information about a pane via a report +(such as the response to OSC 10). +The argument is a pane ID (with a leading +.Ql % ) , +a colon, then a report escape sequence. .Pp .Fl l requests the clipboard from the client using the diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 0a9a557ff6c..fa84e9f6bfe 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1217 2024/05/19 03:27:58 jsg Exp $ */ +/* $OpenBSD: tmux.h,v 1.1218 2024/06/24 08:30:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -1100,6 +1100,9 @@ struct window_pane { int border_gc_set; struct grid_cell border_gc; + int control_bg; + int control_fg; + TAILQ_ENTRY(window_pane) entry; /* link in list of all panes */ TAILQ_ENTRY(window_pane) sentry; /* link in list of last visited */ RB_ENTRY(window_pane) tree_entry; @@ -2407,6 +2410,8 @@ const struct utf8_data *tty_acs_rounded_borders(int); void tty_keys_build(struct tty *); void tty_keys_free(struct tty *); int tty_keys_next(struct tty *); +int tty_keys_colours(struct tty *, const char *, size_t, size_t *, + int *, int *); /* arguments.c */ void args_set(struct args *, u_char, struct args_value *, int); diff --git a/usr.bin/tmux/tty-keys.c b/usr.bin/tmux/tty-keys.c index 9bb18406660..5027876bb3b 100644 --- a/usr.bin/tmux/tty-keys.c +++ b/usr.bin/tmux/tty-keys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-keys.c,v 1.173 2024/03/21 11:47:55 nicm Exp $ */ +/* $OpenBSD: tty-keys.c,v 1.174 2024/06/24 08:30:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -59,7 +59,6 @@ static int tty_keys_device_attributes2(struct tty *, const char *, size_t, size_t *); static int tty_keys_extended_device_attributes(struct tty *, const char *, size_t, size_t *); -static int tty_keys_colours(struct tty *, const char *, size_t, size_t *); /* A key tree entry. */ struct tty_key { @@ -721,7 +720,7 @@ tty_keys_next(struct tty *tty) } /* Is this a colours response? */ - switch (tty_keys_colours(tty, buf, len, &size)) { + switch (tty_keys_colours(tty, buf, len, &size, &tty->fg, &tty->bg)) { case 0: /* yes */ key = KEYC_UNKNOWN; goto complete_key; @@ -1490,8 +1489,9 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf, * Handle foreground or background input. Returns 0 for success, -1 for * failure, 1 for partial. */ -static int -tty_keys_colours(struct tty *tty, const char *buf, size_t len, size_t *size) +int +tty_keys_colours(struct tty *tty, const char *buf, size_t len, size_t *size, + int *fg, int *bg) { struct client *c = tty->client; u_int i; @@ -1542,11 +1542,17 @@ tty_keys_colours(struct tty *tty, const char *buf, size_t len, size_t *size) n = colour_parseX11(tmp); if (n != -1 && buf[3] == '0') { - log_debug("%s: foreground is %s", c->name, colour_tostring(n)); - tty->fg = n; + if (c != NULL) + log_debug("%s fg is %s", c->name, colour_tostring(n)); + else + log_debug("fg is %s", colour_tostring(n)); + *fg = n; } else if (n != -1) { - log_debug("%s: background is %s", c->name, colour_tostring(n)); - tty->bg = n; + if (c != NULL) + log_debug("%s bg is %s", c->name, colour_tostring(n)); + else + log_debug("bg is %s", colour_tostring(n)); + *bg = n; } return (0); diff --git a/usr.bin/tmux/window.c b/usr.bin/tmux/window.c index e9a9a1ef202..5aebeedaa52 100644 --- a/usr.bin/tmux/window.c +++ b/usr.bin/tmux/window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window.c,v 1.290 2024/04/10 07:15:21 nicm Exp $ */ +/* $OpenBSD: window.c,v 1.291 2024/06/24 08:30:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -937,6 +937,9 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit) wp->pipe_fd = -1; + wp->control_bg = -1; + wp->control_fg = -1; + colour_palette_init(&wp->palette); colour_palette_from_option(&wp->palette, wp->options); |