On Tue, May 07, 2019 at 11:55:51AM +0100, Nicholas Marriott wrote:
> 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);
Works for me!
ok solene@