diff options
-rw-r--r-- | cmd-copy-mode.c | 8 | ||||
-rw-r--r-- | server-client.c | 40 | ||||
-rw-r--r-- | tmux.h | 2 | ||||
-rw-r--r-- | tty-keys.c | 6 |
4 files changed, 46 insertions, 10 deletions
diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index bd05f8a2..b35d0af1 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -73,10 +73,10 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_NORMAL); } - if (window_pane_set_mode(wp, &window_copy_mode, NULL, args) != 0) - return (CMD_RETURN_NORMAL); - if (args_has(args, 'M')) - window_copy_start_drag(c, &shared->mouse); + if (!window_pane_set_mode(wp, &window_copy_mode, NULL, args)) { + if (args_has(args, 'M')) + window_copy_start_drag(c, &shared->mouse); + } if (args_has(self->args, 'u')) window_copy_pageup(wp, 0); diff --git a/server-client.c b/server-client.c index 13a589ef..2840ba60 100644 --- a/server-client.c +++ b/server-client.c @@ -986,7 +986,7 @@ server_client_assume_paste(struct session *s) * 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; @@ -1206,6 +1206,44 @@ out: 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 be 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. */ void server_client_loop(void) @@ -2012,7 +2012,7 @@ void server_client_set_identify(struct client *, u_int); 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 *); @@ -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); |