Add a third state "all" to allow-passthrough to work even in invisible
authornicm <nicm@openbsd.org>
Tue, 2 Aug 2022 11:09:26 +0000 (11:09 +0000)
committernicm <nicm@openbsd.org>
Tue, 2 Aug 2022 11:09:26 +0000 (11:09 +0000)
panes, from Sergei Grechanik in GitHub issue 3274.

usr.bin/tmux/input.c
usr.bin/tmux/options-table.c
usr.bin/tmux/screen-write.c
usr.bin/tmux/tmux.1
usr.bin/tmux/tmux.h
usr.bin/tmux/tty.c

index 147a3e6..447f461 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: input.c,v 1.206 2022/06/30 09:55:53 nicm Exp $ */
+/* $OpenBSD: input.c,v 1.207 2022/08/02 11:09:26 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -2242,22 +2242,27 @@ static int
 input_dcs_dispatch(struct input_ctx *ictx)
 {
        struct window_pane      *wp = ictx->wp;
+       struct options          *oo = wp->options;
        struct screen_write_ctx *sctx = &ictx->ctx;
        u_char                  *buf = ictx->input_buf;
        size_t                   len = ictx->input_len;
        const char               prefix[] = "tmux;";
        const u_int              prefixlen = (sizeof prefix) - 1;
+       long long                allow_passthrough = 0;
 
        if (wp == NULL)
                return (0);
        if (ictx->flags & INPUT_DISCARD)
                return (0);
-       if (!options_get_number(ictx->wp->options, "allow-passthrough"))
+       allow_passthrough = options_get_number(oo, "allow-passthrough");
+       if (!allow_passthrough)
                return (0);
        log_debug("%s: \"%s\"", __func__, buf);
 
-       if (len >= prefixlen && strncmp(buf, prefix, prefixlen) == 0)
-               screen_write_rawstring(sctx, buf + prefixlen, len - prefixlen);
+       if (len >= prefixlen && strncmp(buf, prefix, prefixlen) == 0) {
+               screen_write_rawstring(sctx, buf + prefixlen, len - prefixlen,
+                   allow_passthrough == 2);
+       }
 
        return (0);
 }
index 99820aa..d16eed8 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: options-table.c,v 1.163 2022/06/14 07:29:00 nicm Exp $ */
+/* $OpenBSD: options-table.c,v 1.164 2022/08/02 11:09:26 nicm Exp $ */
 
 /*
  * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -88,6 +88,9 @@ static const char *options_table_detach_on_destroy_list[] = {
 static const char *options_table_extended_keys_list[] = {
        "off", "on", "always", NULL
 };
+static const char *options_table_allow_passthrough_list[] = {
+       "off", "on", "all", NULL
+};
 
 /* Status line format. */
 #define OPTIONS_TABLE_STATUS_FORMAT1 \
@@ -804,11 +807,14 @@ const struct options_table_entry options_table[] = {
        },
 
        { .name = "allow-passthrough",
-         .type = OPTIONS_TABLE_FLAG,
+         .type = OPTIONS_TABLE_CHOICE,
          .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
+         .choices = options_table_allow_passthrough_list,
          .default_num = 0,
          .text = "Whether applications are allowed to use the escape sequence "
-                 "to bypass tmux."
+                 "to bypass tmux. Can be 'off' (disallowed), 'on' (allowed "
+                 "if the pane is visible), or 'all' (allowed even if the pane "
+                 "is invisible)."
        },
 
        { .name = "allow-rename",
index 814a1bf..5fcb8e0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen-write.c,v 1.208 2022/06/09 09:12:55 nicm Exp $ */
+/* $OpenBSD: screen-write.c,v 1.209 2022/08/02 11:09:26 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -2100,13 +2100,15 @@ screen_write_setselection(struct screen_write_ctx *ctx, const char *flags,
 
 /* Write unmodified string. */
 void
-screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len)
+screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len,
+    int allow_invisible_panes)
 {
        struct tty_ctx  ttyctx;
 
        screen_write_initctx(ctx, &ttyctx, 0);
        ttyctx.ptr = str;
        ttyctx.num = len;
+       ttyctx.allow_invisible_panes = allow_invisible_panes;
 
        tty_write(tty_cmd_rawstring, &ttyctx);
 }
index dcd1b10..c9f28d3 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.896 2022/08/02 08:57:01 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.897 2022/08/02 11:09:26 nicm Exp $
 .\"
 .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
 .\"
@@ -4461,11 +4461,17 @@ Available pane options are:
 .Pp
 .Bl -tag -width Ds -compact
 .It Xo Ic allow-passthrough
-.Op Ic on | off
+.Op Ic on | off | all
 .Xc
 Allow programs in the pane to bypass
 .Nm
 using a terminal escape sequence (\eePtmux;...\ee\e\e).
+If set to
+.Ic on ,
+passthrough sequences will be allowed only if the pane is visible.
+If set to
+.Ic all ,
+they will be allowed even if the pane is invisible.
 .Pp
 .It Xo Ic allow-rename
 .Op Ic on | off
index 27861fc..cabf7e4 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1178 2022/07/06 08:31:59 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1179 2022/08/02 11:09:26 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1431,38 +1431,45 @@ struct tty_ctx {
        void                    *ptr;
        void                    *ptr2;
 
+       /*
+        * Whether this command should be sent even when the pane is not
+        * visible (used for a passthrough sequence when allow-passthrough is
+        * "all").
+        */
+       int                      allow_invisible_panes;
+
        /*
         * Cursor and region position before the screen was updated - this is
         * where the command should be applied; the values in the screen have
         * already been updated.
         */
-       u_int            ocx;
-       u_int            ocy;
+       u_int                    ocx;
+       u_int                    ocy;
 
-       u_int            orupper;
-       u_int            orlower;
+       u_int                    orupper;
+       u_int                    orlower;
 
        /* Target region (usually pane) offset and size. */
-       u_int            xoff;
-       u_int            yoff;
-       u_int            rxoff;
-       u_int            ryoff;
-       u_int            sx;
-       u_int            sy;
+       u_int                    xoff;
+       u_int                    yoff;
+       u_int                    rxoff;
+       u_int                    ryoff;
+       u_int                    sx;
+       u_int                    sy;
 
        /* The background colour used for clearing (erasing). */
-       u_int            bg;
+       u_int                    bg;
 
        /* The default colours and palette. */
-       struct grid_cell defaults;
-       struct colour_palette *palette;
+       struct grid_cell         defaults;
+       struct colour_palette   *palette;
 
        /* Containing region (usually window) offset and size. */
-       int              bigger;
-       u_int            wox;
-       u_int            woy;
-       u_int            wsx;
-       u_int            wsy;
+       int                      bigger;
+       u_int                    wox;
+       u_int                    woy;
+       u_int                    wsx;
+       u_int                    wsy;
 };
 
 /* Saved message entry. */
@@ -2889,7 +2896,8 @@ void       screen_write_collect_add(struct screen_write_ctx *,
 void    screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
 void    screen_write_setselection(struct screen_write_ctx *, const char *,
             u_char *, u_int);
-void    screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
+void    screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int,
+            int);
 void    screen_write_alternateon(struct screen_write_ctx *,
             struct grid_cell *, int);
 void    screen_write_alternateoff(struct screen_write_ctx *,
index e029c9c..4077b9a 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.422 2022/07/06 07:36:36 nicm Exp $ */
+/* $OpenBSD: tty.c,v 1.423 2022/08/02 11:09:26 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1626,13 +1626,20 @@ tty_write(void (*cmdfn)(struct tty *, const struct tty_ctx *),
        if (ctx->set_client_cb == NULL)
                return;
        TAILQ_FOREACH(c, &clients, entry) {
-               if (!tty_client_ready(c))
-                       continue;
-               state = ctx->set_client_cb(ctx, c);
-               if (state == -1)
-                       break;
-               if (state == 0)
-                       continue;
+               if (ctx->allow_invisible_panes) {
+                   if (c->session == NULL ||
+                       c->tty.term == NULL ||
+                       c->flags & CLIENT_SUSPENDED)
+                           continue;
+               } else {
+                       if (!tty_client_ready(c))
+                               continue;
+                       state = ctx->set_client_cb(ctx, c);
+                       if (state == -1)
+                               break;
+                       if (state == 0)
+                               continue;
+               }
                cmdfn(&c->tty, ctx);
        }
 }