Treat keys in identify mode (display-panes) specially and handle them

immediately rather than queuing them (the command can block the queue
which means they were not being seen until it finished which was too
late). Reported by denis@ and solene@, ok solene@.
This commit is contained in:
nicm 2019-05-07 11:24:03 +00:00
parent 69440d19b7
commit 85a9c2f52b
4 changed files with 46 additions and 10 deletions

View File

@ -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);

View File

@ -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)

2
tmux.h
View File

@ -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 *);

View File

@ -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);