=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/server-client.c,v retrieving revision 1.222 retrieving revision 1.223 diff -u -r1.222 -r1.223 --- src/usr.bin/tmux/server-client.c 2017/04/21 14:01:19 1.222 +++ src/usr.bin/tmux/server-client.c 2017/04/21 16:04:18 1.223 @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.222 2017/04/21 14:01:19 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.223 2017/04/21 16:04:18 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -138,11 +138,11 @@ return (name); } -/* Is this client using the default key table? */ -int -server_client_is_default_key_table(struct client *c) +/* Is this table the default key table? */ +static int +server_client_is_default_key_table(struct client *c, struct key_table *table) { - return (strcmp(c->keytable->name, server_client_get_key_table(c)) == 0); + return (strcmp(table->name, server_client_get_key_table(c)) == 0); } /* Create a new client. */ @@ -793,8 +793,7 @@ struct window *w; struct window_pane *wp; struct timeval tv; - const char *name; - struct key_table *table; + struct key_table *table, *first; struct key_binding bd_find, *bd; int xtimeout; struct cmd_find_state fs; @@ -870,22 +869,18 @@ if (!KEYC_IS_MOUSE(key) && server_client_assume_paste(s)) goto forward; -retry: /* * Work out the current key table. If the pane is in a mode, use * the mode table instead of the default key table. */ - name = NULL; - if (wp != NULL && wp->mode != NULL && wp->mode->key_table != NULL) - name = wp->mode->key_table(wp); - if (name == NULL || !server_client_is_default_key_table(c)) - table = c->keytable; + if (server_client_is_default_key_table(c, c->keytable) && + wp != NULL && + wp->mode != NULL && + wp->mode->key_table != NULL) + table = key_bindings_get_table(wp->mode->key_table(wp), 1); else - table = key_bindings_get_table(name, 1); - if (wp == NULL) - log_debug("key table %s (no pane)", table->name); - else - log_debug("key table %s (pane %%%u)", table->name, wp->id); + table = c->keytable; + first = table; /* * The prefix always takes precedence and forces a switch to the prefix @@ -899,6 +894,13 @@ return; } +retry: + /* Log key table. */ + if (wp == NULL) + log_debug("key table %s (no pane)", table->name); + else + log_debug("key table %s (pane %%%u)", table->name, wp->id); + /* Try to see if there is a key binding in the current table. */ bd_find.key = key; bd = RB_FIND(key_bindings, &table->key_bindings, &bd_find); @@ -913,8 +915,10 @@ server_client_set_key_table(c, NULL); c->flags &= ~CLIENT_REPEAT; server_status_client(c); + table = c->keytable; goto retry; } + log_debug("found in key table %s", table->name); /* * Take a reference to this table to make sure the key binding @@ -959,19 +963,24 @@ } /* - * No match in this table. If repeating, switch the client back to the - * root table and try again. + * No match in this table. If not in the root table or if repeating, + * switch the client back to the root table and try again. */ - if (c->flags & CLIENT_REPEAT) { + log_debug("not found in key table %s", table->name); + if (!server_client_is_default_key_table(c, table) || + (c->flags & CLIENT_REPEAT)) { server_client_set_key_table(c, NULL); c->flags &= ~CLIENT_REPEAT; server_status_client(c); + table = c->keytable; goto retry; } - /* If no match and we're not in the root table, that's it. */ - if (name == NULL && !server_client_is_default_key_table(c)) { - log_debug("no key in key table %s", table->name); + /* + * No match in the root table either. If this wasn't the first table + * tried, don't pass the key to the pane. + */ + if (first != table) { server_client_set_key_table(c, NULL); server_status_client(c); return;