Add a way (refresh-client -r) for control mode clients to provide OSC 10
authornicm <nicm@openbsd.org>
Mon, 24 Jun 2024 08:30:50 +0000 (08:30 +0000)
committernicm <nicm@openbsd.org>
Mon, 24 Jun 2024 08:30:50 +0000 (08:30 +0000)
and 11 responses to tmux so they can set the default foreground and
background colours, from George Nachman in GitHub issue 4014.

usr.bin/tmux/cmd-refresh-client.c
usr.bin/tmux/input.c
usr.bin/tmux/tmux.1
usr.bin/tmux/tmux.h
usr.bin/tmux/tty-keys.c
usr.bin/tmux/window.c

index e1af3e8..04e5178 100644 (file)
@@ -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)
index 6d67917..7ee8113 100644 (file)
@@ -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;
        }
index 2185dc7..351208a 100644 (file)
@@ -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
index 0a9a557..fa84e9f 100644 (file)
@@ -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);
index 9bb1840..5027876 100644 (file)
@@ -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);
index e9a9a1e..5aebeed 100644 (file)
@@ -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);