Hi

You have the right idea general idea of the problem. display-panes
blocks the queue until it is finished, so the key press isn't processed
until then, which is too late.

But your change defeats the purpose, the idea is that new key presses
should be queued after the commands inserted by previous key presses,
not before them.

Identify mode (display-panes) can just be treated specially I think.

Please try the diff below.

Thanks!


Index: server-client.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/server-client.c,v
retrieving revision 1.279
diff -u -p -r1.279 server-client.c
--- server-client.c     3 May 2019 20:44:24 -0000       1.279
+++ server-client.c     7 May 2019 10:50:07 -0000
@@ -986,7 +986,7 @@ server_client_assume_paste(struct sessio
  * Handle data key input from client. This owns and can modify the key event it
  * is given and is responsible for freeing it.
  */
-enum cmd_retval
+static enum cmd_retval
 server_client_key_callback(struct cmdq_item *item, void *data)
 {
        struct client                   *c = item->client;
@@ -1204,6 +1204,44 @@ forward_key:
 out:
        free(event);
        return (CMD_RETURN_NORMAL);
+}
+
+/* Handle a key event. */
+int
+server_client_handle_key(struct client *c, struct key_event *event)
+{
+       struct session          *s = c->session;
+       struct window           *w;
+       struct window_pane      *wp = NULL;
+       struct cmdq_item        *item;
+
+       /* Check the client is good to accept input. */
+       if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
+               return (0);
+       w = s->curw->window;
+
+       /*
+        * Key presses in identify mode are a special case. The queue might be
+        * blocked so they need to processed immediately rather than queued.
+        */
+       if (c->flags & CLIENT_IDENTIFY) {
+               if (c->flags & CLIENT_READONLY)
+                       return (0);
+               if (event->key >= '0' && event->key <= '9') {
+                       window_unzoom(w);
+                       wp = window_pane_at_index(w, event->key - '0');
+               }
+               server_client_clear_identify(c, wp);
+               return (0);
+       }
+
+       /*
+        * Add the key to the queue so it happens after any commands queued by
+        * previous keys.
+        */
+       item = cmdq_get_callback(server_client_key_callback, event);
+       cmdq_append(c, item);
+       return (1);
 }
 
 /* Client functions that need to happen every loop. */
Index: tmux.h
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tmux.h,v
retrieving revision 1.888
diff -u -p -r1.888 tmux.h
--- tmux.h      7 May 2019 10:25:15 -0000       1.888
+++ tmux.h      7 May 2019 10:50:09 -0000
@@ -2012,7 +2012,7 @@ void       server_client_set_identify(struct 
 void    server_client_set_key_table(struct client *, const char *);
 const char *server_client_get_key_table(struct client *);
 int     server_client_check_nested(struct client *);
-enum cmd_retval server_client_key_callback(struct cmdq_item *, void *);
+int     server_client_handle_key(struct client *, struct key_event *);
 struct client *server_client_create(int);
 int     server_client_open(struct client *, char **);
 void    server_client_unref(struct client *);
Index: tty-keys.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tty-keys.c,v
retrieving revision 1.112
diff -u -p -r1.112 tty-keys.c
--- tty-keys.c  3 May 2019 18:00:19 -0000       1.112
+++ tty-keys.c  7 May 2019 10:50:09 -0000
@@ -573,7 +573,6 @@ tty_keys_next(struct tty *tty)
        cc_t                     bspace;
        int                      delay, expired = 0, n;
        key_code                 key;
-       struct cmdq_item        *item;
        struct mouse_event       m = { 0 };
        struct key_event        *event;
 
@@ -732,9 +731,8 @@ complete_key:
                event = xmalloc(sizeof *event);
                event->key = key;
                memcpy(&event->m, &m, sizeof event->m);
-
-               item = cmdq_get_callback(server_client_key_callback, event);
-               cmdq_append(c, item);
+               if (!server_client_handle_key(c, event))
+                       free(event);
        }
 
        return (1);

Reply via email to