From b6be437bab89fb73cb9dda208321cf3d1263f71c Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 11 Jun 2026 19:13:34 +0000 Subject: [PATCH] Change send-keys -K to insert keys in the right place in the queue, like we already do for key bindings. GitHub issue 3476. --- cmd-send-keys.c | 17 +++++++++++++---- server-client.c | 38 ++++++++++++++++++++++++++++++++++---- tmux.h | 4 ++++ 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/cmd-send-keys.c b/cmd-send-keys.c index 86e7daed..6be3f2ea 100644 --- a/cmd-send-keys.c +++ b/cmd-send-keys.c @@ -70,6 +70,7 @@ cmd_send_keys_inject_key(struct cmdq_item *item, struct cmdq_item *after, struct key_table *table = NULL; struct key_binding *bd; struct key_event *event; + struct cmdq_item *new_after = after; if (args_has(args, 'K')) { if (tc == NULL) @@ -77,10 +78,16 @@ cmd_send_keys_inject_key(struct cmdq_item *item, struct cmdq_item *after, event = xcalloc(1, sizeof *event); event->key = key|KEYC_SENT; memset(&event->m, 0, sizeof event->m); - if (server_client_handle_key(tc, event) == 0) { - free(event->buf); - free(event); + if (after == NULL) { + if (server_client_handle_key(tc, event) != 0) + return (item); + } else { + if (server_client_handle_key_after(tc, event, after, + &new_after) != 0) + return (new_after); } + free(event->buf); + free(event); return (item); } @@ -229,8 +236,10 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item) if (count == 0) { if (args_has(args, 'N') || args_has(args, 'R')) return (CMD_RETURN_NORMAL); + after = args_has(args, 'K') ? item : NULL; for (; np != 0; np--) - cmd_send_keys_inject_key(item, NULL, args, event->key); + after = cmd_send_keys_inject_key(item, after, args, + event->key); return (CMD_RETURN_NORMAL); } diff --git a/server-client.c b/server-client.c index 7b141dce..9d180d0e 100644 --- a/server-client.c +++ b/server-client.c @@ -1168,11 +1168,11 @@ server_client_repeat_time(struct client *c, struct key_binding *bd) static enum cmd_retval server_client_key_callback(struct cmdq_item *item, void *data) { - struct client *c = cmdq_get_client(item); struct key_event *event = data; + struct client *c, *ec = event->client; key_code key = event->key; struct mouse_event *m = &event->m; - struct session *s = c->session; + struct session *s; struct winlink *wl; struct window_pane *wp; struct window_mode_entry *wme; @@ -1184,6 +1184,12 @@ server_client_key_callback(struct cmdq_item *item, void *data) struct cmd_find_state fs; key_code key0, prefix, prefix2; + if (ec != NULL) + c = ec; + else + c = cmdq_get_client(item); + s = c->session; + /* Check the client is good to accept input. */ if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS)) goto out; @@ -1430,14 +1436,17 @@ paste_key: out: if (s != NULL && key != KEYC_FOCUS_OUT) server_client_update_latest(c); + if (ec != NULL) + server_client_unref(ec); free(event->buf); free(event); return (CMD_RETURN_NORMAL); } /* Handle a key event. */ -int -server_client_handle_key(struct client *c, struct key_event *event) +static int +server_client_handle_key0(struct client *c, struct key_event *event, + struct cmdq_item *after, struct cmdq_item **next) { struct session *s = c->session; struct cmdq_item *item; @@ -1491,10 +1500,31 @@ server_client_handle_key(struct client *c, struct key_event *event) * previous keys. */ item = cmdq_get_callback(server_client_key_callback, event); + if (after != NULL) { + event->client = c; + c->references++; + item = cmdq_insert_after(after, item); + if (next != NULL) + *next = item; + return (1); + } cmdq_append(c, item); return (1); } +int +server_client_handle_key(struct client *c, struct key_event *event) +{ + return (server_client_handle_key0(c, event, NULL, NULL)); +} + +int +server_client_handle_key_after(struct client *c, struct key_event *event, + struct cmdq_item *after, struct cmdq_item **next) +{ + return (server_client_handle_key0(c, event, after, next)); +} + /* Client functions that need to happen every loop. */ void server_client_loop(void) diff --git a/tmux.h b/tmux.h index 82197751..48f7c59f 100644 --- a/tmux.h +++ b/tmux.h @@ -1585,6 +1585,8 @@ struct mouse_event { /* Key event. */ struct key_event { + struct client *client; + key_code key; struct mouse_event m; @@ -3036,6 +3038,8 @@ 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 *); int server_client_handle_key(struct client *, struct key_event *); +int server_client_handle_key_after(struct client *, struct key_event *, + struct cmdq_item *, struct cmdq_item **); struct client *server_client_create(int); int server_client_open(struct client *, char **); void server_client_unref(struct client *);