aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd-copy-mode.c8
-rw-r--r--server-client.c40
-rw-r--r--tmux.h2
-rw-r--r--tty-keys.c6
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)
diff --git a/tmux.h b/tmux.h
index e6ed8c87..55c24531 100644
--- a/tmux.h
+++ b/tmux.h
@@ -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 *);
diff --git a/tty-keys.c b/tty-keys.c
index 90f34877..3ab7f184 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -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);