-/* $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 <nicholas.marriott@gmail.com>
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. */
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;
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;
- else
- table = key_bindings_get_table(name, 1);
- if (wp == NULL)
- log_debug("key table %s (no pane)", table->name);
+ 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
- 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
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);
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
}
/*
- * 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;
-/* $OpenBSD: tmux.h,v 1.746 2017/04/21 14:09:44 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.747 2017/04/21 16:04:18 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
void server_client_clear_identify(struct client *, struct window_pane *);
void server_client_set_key_table(struct client *, const char *);
const char *server_client_get_key_table(struct client *);
-int server_client_is_default_key_table(struct client *);
int server_client_check_nested(struct client *);
void server_client_handle_key(struct client *, key_code);
void server_client_create(int);