mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
This commit is contained in:
		@@ -119,6 +119,7 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		c->session = s;
 | 
			
		||||
		server_client_set_key_table(c, NULL);
 | 
			
		||||
		status_timer_start(c);
 | 
			
		||||
		notify_attached_session_changed(c);
 | 
			
		||||
		session_update_activity(s, NULL);
 | 
			
		||||
@@ -150,6 +151,7 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		c->session = s;
 | 
			
		||||
		server_client_set_key_table(c, NULL);
 | 
			
		||||
		status_timer_start(c);
 | 
			
		||||
		notify_attached_session_changed(c);
 | 
			
		||||
		session_update_activity(s, NULL);
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	key = key_string_lookup_string(args->argv[0]);
 | 
			
		||||
	if (key == KEYC_NONE) {
 | 
			
		||||
	if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
 | 
			
		||||
		cmdq_error(cmdq, "unknown key: %s", args->argv[0]);
 | 
			
		||||
		return (CMD_RETURN_ERROR);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -262,6 +262,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
		} else if (c->session != NULL)
 | 
			
		||||
			c->last_session = c->session;
 | 
			
		||||
		c->session = s;
 | 
			
		||||
		server_client_set_key_table(c, NULL);
 | 
			
		||||
		status_timer_start(c);
 | 
			
		||||
		notify_attached_session_changed(c);
 | 
			
		||||
		session_update_activity(s, NULL);
 | 
			
		||||
 
 | 
			
		||||
@@ -52,8 +52,8 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
	struct mouse_event	*m = &cmdq->item->mouse;
 | 
			
		||||
	struct window_pane	*wp;
 | 
			
		||||
	struct session		*s;
 | 
			
		||||
	const u_char		*str;
 | 
			
		||||
	int			 i;
 | 
			
		||||
	int			 i, literal;
 | 
			
		||||
	const u_char		*keystr;
 | 
			
		||||
	key_code		 key;
 | 
			
		||||
 | 
			
		||||
	if (args_has(args, 'M')) {
 | 
			
		||||
@@ -82,14 +82,17 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
		input_reset(wp);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < args->argc; i++) {
 | 
			
		||||
		str = args->argv[i];
 | 
			
		||||
 | 
			
		||||
		if (!args_has(args, 'l') &&
 | 
			
		||||
		    (key = key_string_lookup_string(str)) != KEYC_NONE) {
 | 
			
		||||
			window_pane_key(wp, NULL, s, key, NULL);
 | 
			
		||||
		} else {
 | 
			
		||||
			for (; *str != '\0'; str++)
 | 
			
		||||
				window_pane_key(wp, NULL, s, *str, NULL);
 | 
			
		||||
		literal = args_has(args, 'l');
 | 
			
		||||
		if (!literal) {
 | 
			
		||||
			key = key_string_lookup_string(args->argv[i]);
 | 
			
		||||
			if (key != KEYC_NONE && key != KEYC_UNKNOWN)
 | 
			
		||||
				window_pane_key(wp, NULL, s, key, NULL);
 | 
			
		||||
			else
 | 
			
		||||
				literal = 1;
 | 
			
		||||
		}
 | 
			
		||||
		if (literal) {
 | 
			
		||||
			for (keystr = args->argv[i]; *keystr != '\0'; keystr++)
 | 
			
		||||
				window_pane_key(wp, NULL, s, *keystr, NULL);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -183,6 +183,10 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
				w->active->flags |= PANE_CHANGED;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (strcmp(oe->name, "key-table") == 0) {
 | 
			
		||||
		TAILQ_FOREACH(c, &clients, entry)
 | 
			
		||||
			server_client_set_key_table(c, NULL);
 | 
			
		||||
	}
 | 
			
		||||
	if (strcmp(oe->name, "status") == 0 ||
 | 
			
		||||
	    strcmp(oe->name, "status-interval") == 0)
 | 
			
		||||
		status_timer_start_all();
 | 
			
		||||
@@ -396,7 +400,8 @@ cmd_set_option_key(__unused struct cmd *self, struct cmd_q *cmdq,
 | 
			
		||||
{
 | 
			
		||||
	key_code	key;
 | 
			
		||||
 | 
			
		||||
	if ((key = key_string_lookup_string(value)) == KEYC_NONE) {
 | 
			
		||||
	key = key_string_lookup_string(value);
 | 
			
		||||
	if (key == KEYC_UNKNOWN) {
 | 
			
		||||
		cmdq_error(cmdq, "bad key: %s", value);
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -65,6 +65,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
		table->references++;
 | 
			
		||||
		key_bindings_unref_table(c->keytable);
 | 
			
		||||
		c->keytable = table;
 | 
			
		||||
		return (CMD_RETURN_NORMAL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tflag = args_get(args, 't');
 | 
			
		||||
@@ -123,6 +124,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
	if (c->session != NULL && c->session != s)
 | 
			
		||||
		c->last_session = c->session;
 | 
			
		||||
	c->session = s;
 | 
			
		||||
	server_client_set_key_table(c, NULL);
 | 
			
		||||
	status_timer_start(c);
 | 
			
		||||
	session_update_activity(s, NULL);
 | 
			
		||||
	gettimeofday(&s->last_attached_time, NULL);
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,7 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
			return (CMD_RETURN_ERROR);
 | 
			
		||||
		}
 | 
			
		||||
		key = key_string_lookup_string(args->argv[0]);
 | 
			
		||||
		if (key == KEYC_NONE) {
 | 
			
		||||
		if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
 | 
			
		||||
			cmdq_error(cmdq, "unknown key: %s", args->argv[0]);
 | 
			
		||||
			return (CMD_RETURN_ERROR);
 | 
			
		||||
		}
 | 
			
		||||
@@ -60,13 +60,13 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
			cmdq_error(cmdq, "key given with -a");
 | 
			
		||||
			return (CMD_RETURN_ERROR);
 | 
			
		||||
		}
 | 
			
		||||
		key = KEYC_NONE;
 | 
			
		||||
		key = KEYC_UNKNOWN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (args_has(args, 't'))
 | 
			
		||||
		return (cmd_unbind_key_mode_table(self, cmdq, key));
 | 
			
		||||
 | 
			
		||||
	if (key == KEYC_NONE) {
 | 
			
		||||
	if (key == KEYC_UNKNOWN) {
 | 
			
		||||
		tablename = args_get(args, 'T');
 | 
			
		||||
		if (tablename == NULL) {
 | 
			
		||||
			key_bindings_remove_table("root");
 | 
			
		||||
@@ -109,7 +109,7 @@ cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key)
 | 
			
		||||
		return (CMD_RETURN_ERROR);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (key == KEYC_NONE) {
 | 
			
		||||
	if (key == KEYC_UNKNOWN) {
 | 
			
		||||
		while (!RB_EMPTY(mtab->tree)) {
 | 
			
		||||
			mbind = RB_ROOT(mtab->tree);
 | 
			
		||||
			RB_REMOVE(mode_key_tree, mtab->tree, mbind);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								format.c
									
									
									
									
									
								
							@@ -1052,6 +1052,7 @@ void
 | 
			
		||||
format_defaults_client(struct format_tree *ft, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
	const char	*name;
 | 
			
		||||
 | 
			
		||||
	if (ft->s == NULL)
 | 
			
		||||
		ft->s = c->session;
 | 
			
		||||
@@ -1069,7 +1070,8 @@ format_defaults_client(struct format_tree *ft, struct client *c)
 | 
			
		||||
	format_add_tv(ft, "client_created", &c->creation_time);
 | 
			
		||||
	format_add_tv(ft, "client_activity", &c->activity_time);
 | 
			
		||||
 | 
			
		||||
	if (strcmp(c->keytable->name, "root") == 0)
 | 
			
		||||
	name = server_client_get_key_table(c);
 | 
			
		||||
	if (strcmp(c->keytable->name, name) == 0)
 | 
			
		||||
		format_add(ft, "client_prefix", "%d", 0);
 | 
			
		||||
	else
 | 
			
		||||
		format_add(ft, "client_prefix", "%d", 1);
 | 
			
		||||
 
 | 
			
		||||
@@ -160,14 +160,14 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
 | 
			
		||||
	 * if necessary. If it is a UTF-8 key, split it and send it.
 | 
			
		||||
	 */
 | 
			
		||||
	justkey = (key & ~KEYC_ESCAPE);
 | 
			
		||||
	if (key != KEYC_NONE && justkey <= 0x7f) {
 | 
			
		||||
	if (justkey <= 0x7f) {
 | 
			
		||||
		if (key & KEYC_ESCAPE)
 | 
			
		||||
			bufferevent_write(wp->event, "\033", 1);
 | 
			
		||||
		ud.data[0] = justkey;
 | 
			
		||||
		bufferevent_write(wp->event, &ud.data[0], 1);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (key != KEYC_NONE && justkey > 0x7f && justkey < KEYC_BASE) {
 | 
			
		||||
	if (justkey > 0x7f && justkey < KEYC_BASE) {
 | 
			
		||||
		if (utf8_split(justkey, &ud) != UTF8_DONE)
 | 
			
		||||
			return;
 | 
			
		||||
		if (key & KEYC_ESCAPE)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								key-string.c
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								key-string.c
									
									
									
									
									
								
							@@ -22,8 +22,8 @@
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
key_code	key_string_search_table(const char *);
 | 
			
		||||
key_code	key_string_get_modifiers(const char **);
 | 
			
		||||
static key_code	key_string_search_table(const char *);
 | 
			
		||||
static key_code	key_string_get_modifiers(const char **);
 | 
			
		||||
 | 
			
		||||
const struct {
 | 
			
		||||
	const char     *string;
 | 
			
		||||
@@ -98,7 +98,7 @@ const struct {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Find key string in table. */
 | 
			
		||||
key_code
 | 
			
		||||
static key_code
 | 
			
		||||
key_string_search_table(const char *string)
 | 
			
		||||
{
 | 
			
		||||
	u_int	i;
 | 
			
		||||
@@ -107,11 +107,11 @@ key_string_search_table(const char *string)
 | 
			
		||||
		if (strcasecmp(string, key_string_table[i].string) == 0)
 | 
			
		||||
			return (key_string_table[i].key);
 | 
			
		||||
	}
 | 
			
		||||
	return (KEYC_NONE);
 | 
			
		||||
	return (KEYC_UNKNOWN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find modifiers. */
 | 
			
		||||
key_code
 | 
			
		||||
static key_code
 | 
			
		||||
key_string_get_modifiers(const char **string)
 | 
			
		||||
{
 | 
			
		||||
	key_code	modifiers;
 | 
			
		||||
@@ -150,10 +150,14 @@ key_string_lookup_string(const char *string)
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
	enum utf8_state		 more;
 | 
			
		||||
 | 
			
		||||
	/* Is this no key? */
 | 
			
		||||
	if (strcasecmp(string, "None") == 0)
 | 
			
		||||
		return (KEYC_NONE);
 | 
			
		||||
 | 
			
		||||
	/* Is this a hexadecimal value? */
 | 
			
		||||
	if (string[0] == '0' && string[1] == 'x') {
 | 
			
		||||
	        if (sscanf(string + 2, "%hx%n", &u, &size) != 1 || size > 4)
 | 
			
		||||
	                return (KEYC_NONE);
 | 
			
		||||
	                return (KEYC_UNKNOWN);
 | 
			
		||||
	        return (u);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -165,30 +169,30 @@ key_string_lookup_string(const char *string)
 | 
			
		||||
	}
 | 
			
		||||
	modifiers |= key_string_get_modifiers(&string);
 | 
			
		||||
	if (string[0] == '\0')
 | 
			
		||||
		return (KEYC_NONE);
 | 
			
		||||
		return (KEYC_UNKNOWN);
 | 
			
		||||
 | 
			
		||||
	/* Is this a standard ASCII key? */
 | 
			
		||||
	if (string[1] == '\0' && (u_char)string[0] <= 127) {
 | 
			
		||||
		key = (u_char)string[0];
 | 
			
		||||
		if (key < 32 || key == 127)
 | 
			
		||||
			return (KEYC_NONE);
 | 
			
		||||
			return (KEYC_UNKNOWN);
 | 
			
		||||
	} else {
 | 
			
		||||
		/* Try as a UTF-8 key. */
 | 
			
		||||
		if ((more = utf8_open(&ud, (u_char)*string)) == UTF8_MORE) {
 | 
			
		||||
			if (strlen(string) != ud.size)
 | 
			
		||||
				return (KEYC_NONE);
 | 
			
		||||
				return (KEYC_UNKNOWN);
 | 
			
		||||
			for (i = 1; i < ud.size; i++)
 | 
			
		||||
				more = utf8_append(&ud, (u_char)string[i]);
 | 
			
		||||
			if (more != UTF8_DONE)
 | 
			
		||||
				return (KEYC_NONE);
 | 
			
		||||
				return (KEYC_UNKNOWN);
 | 
			
		||||
			key = utf8_combine(&ud);
 | 
			
		||||
			return (key | modifiers);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Otherwise look the key up in the table. */
 | 
			
		||||
		key = key_string_search_table(string);
 | 
			
		||||
		if (key == KEYC_NONE)
 | 
			
		||||
			return (KEYC_NONE);
 | 
			
		||||
		if (key == KEYC_UNKNOWN)
 | 
			
		||||
			return (KEYC_UNKNOWN);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Convert the standard control keys. */
 | 
			
		||||
@@ -202,7 +206,7 @@ key_string_lookup_string(const char *string)
 | 
			
		||||
		else if (key == 63)
 | 
			
		||||
			key = KEYC_BSPACE;
 | 
			
		||||
		else
 | 
			
		||||
			return (KEYC_NONE);
 | 
			
		||||
			return (KEYC_UNKNOWN);
 | 
			
		||||
		modifiers &= ~KEYC_CTRL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -222,9 +226,13 @@ key_string_lookup_key(key_code key)
 | 
			
		||||
 | 
			
		||||
	/* Handle no key. */
 | 
			
		||||
	if (key == KEYC_NONE)
 | 
			
		||||
		return ("<NONE>");
 | 
			
		||||
		return ("None");
 | 
			
		||||
 | 
			
		||||
	/* Handle special keys. */
 | 
			
		||||
	if (key == KEYC_UNKNOWN)
 | 
			
		||||
		return ("Unknown");
 | 
			
		||||
	if (key == KEYC_MOUSE)
 | 
			
		||||
		return ("<MOUSE>");
 | 
			
		||||
		return ("Mouse");
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Special case: display C-@ as C-Space. Could do this below in
 | 
			
		||||
@@ -265,7 +273,7 @@ key_string_lookup_key(key_code key)
 | 
			
		||||
 | 
			
		||||
	/* Invalid keys are errors. */
 | 
			
		||||
	if (key == 127 || key > 255) {
 | 
			
		||||
		snprintf(out, sizeof out, "<INVALID#%llx>", key);
 | 
			
		||||
		snprintf(out, sizeof out, "Invalid#%llx", key);
 | 
			
		||||
		return (out);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -210,6 +210,12 @@ const struct options_table_entry options_table[] = {
 | 
			
		||||
	  .default_num = 2000
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{ .name = "key-table",
 | 
			
		||||
	  .type = OPTIONS_TABLE_STRING,
 | 
			
		||||
	  .scope = OPTIONS_TABLE_SESSION,
 | 
			
		||||
	  .default_str = "root"
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{ .name = "lock-after-time",
 | 
			
		||||
	  .type = OPTIONS_TABLE_NUMBER,
 | 
			
		||||
	  .scope = OPTIONS_TABLE_SESSION,
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,6 @@
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
void		server_client_key_table(struct client *, const char *);
 | 
			
		||||
void		server_client_free(int, short, void *);
 | 
			
		||||
void		server_client_check_focus(struct window_pane *);
 | 
			
		||||
void		server_client_check_resize(struct window_pane *);
 | 
			
		||||
@@ -70,13 +69,32 @@ server_client_check_nested(struct client *c)
 | 
			
		||||
 | 
			
		||||
/* Set client key table. */
 | 
			
		||||
void
 | 
			
		||||
server_client_key_table(struct client *c, const char *name)
 | 
			
		||||
server_client_set_key_table(struct client *c, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	if (name == NULL)
 | 
			
		||||
		name = server_client_get_key_table(c);
 | 
			
		||||
 | 
			
		||||
	key_bindings_unref_table(c->keytable);
 | 
			
		||||
	c->keytable = key_bindings_get_table(name, 1);
 | 
			
		||||
	c->keytable->references++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get default key table. */
 | 
			
		||||
const char *
 | 
			
		||||
server_client_get_key_table(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s = c->session;
 | 
			
		||||
	const char	*name;
 | 
			
		||||
 | 
			
		||||
	if (s == NULL)
 | 
			
		||||
		return ("root");
 | 
			
		||||
 | 
			
		||||
	name = options_get_string(s->options, "key-table");
 | 
			
		||||
	if (*name == '\0')
 | 
			
		||||
		return ("root");
 | 
			
		||||
	return (name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Create a new client. */
 | 
			
		||||
void
 | 
			
		||||
server_client_create(int fd)
 | 
			
		||||
@@ -307,7 +325,7 @@ server_client_check_mouse(struct client *c)
 | 
			
		||||
		log_debug("down at %u,%u", x, y);
 | 
			
		||||
	}
 | 
			
		||||
	if (type == NOTYPE)
 | 
			
		||||
		return (KEYC_NONE);
 | 
			
		||||
		return (KEYC_UNKNOWN);
 | 
			
		||||
 | 
			
		||||
	/* Always save the session. */
 | 
			
		||||
	m->s = s->id;
 | 
			
		||||
@@ -317,7 +335,7 @@ server_client_check_mouse(struct client *c)
 | 
			
		||||
	if (m->statusat != -1 && y == (u_int)m->statusat) {
 | 
			
		||||
		w = status_get_window_at(c, x);
 | 
			
		||||
		if (w == NULL)
 | 
			
		||||
			return (KEYC_NONE);
 | 
			
		||||
			return (KEYC_UNKNOWN);
 | 
			
		||||
		m->w = w->id;
 | 
			
		||||
		where = STATUS;
 | 
			
		||||
	} else
 | 
			
		||||
@@ -350,7 +368,7 @@ server_client_check_mouse(struct client *c)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (where == NOWHERE)
 | 
			
		||||
			return (KEYC_NONE);
 | 
			
		||||
			return (KEYC_UNKNOWN);
 | 
			
		||||
		m->wp = wp->id;
 | 
			
		||||
		m->w = wp->window->id;
 | 
			
		||||
	} else
 | 
			
		||||
@@ -369,7 +387,7 @@ server_client_check_mouse(struct client *c)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Convert to a key binding. */
 | 
			
		||||
	key = KEYC_NONE;
 | 
			
		||||
	key = KEYC_UNKNOWN;
 | 
			
		||||
	switch (type) {
 | 
			
		||||
	case NOTYPE:
 | 
			
		||||
		break;
 | 
			
		||||
@@ -481,8 +499,8 @@ server_client_check_mouse(struct client *c)
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	if (key == KEYC_NONE)
 | 
			
		||||
		return (KEYC_NONE);
 | 
			
		||||
	if (key == KEYC_UNKNOWN)
 | 
			
		||||
		return (KEYC_UNKNOWN);
 | 
			
		||||
 | 
			
		||||
	/* Apply modifiers if any. */
 | 
			
		||||
	if (b & MOUSE_MASK_META)
 | 
			
		||||
@@ -570,7 +588,7 @@ server_client_handle_key(struct client *c, key_code key)
 | 
			
		||||
		if (c->flags & CLIENT_READONLY)
 | 
			
		||||
			return;
 | 
			
		||||
		key = server_client_check_mouse(c);
 | 
			
		||||
		if (key == KEYC_NONE)
 | 
			
		||||
		if (key == KEYC_UNKNOWN)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		m->valid = 1;
 | 
			
		||||
@@ -596,7 +614,7 @@ retry:
 | 
			
		||||
		 * again in the root table.
 | 
			
		||||
		 */
 | 
			
		||||
		if ((c->flags & CLIENT_REPEAT) && !bd->can_repeat) {
 | 
			
		||||
			server_client_key_table(c, "root");
 | 
			
		||||
			server_client_set_key_table(c, NULL);
 | 
			
		||||
			c->flags &= ~CLIENT_REPEAT;
 | 
			
		||||
			server_status_client(c);
 | 
			
		||||
			goto retry;
 | 
			
		||||
@@ -623,7 +641,7 @@ retry:
 | 
			
		||||
			evtimer_add(&c->repeat_timer, &tv);
 | 
			
		||||
		} else {
 | 
			
		||||
			c->flags &= ~CLIENT_REPEAT;
 | 
			
		||||
			server_client_key_table(c, "root");
 | 
			
		||||
			server_client_set_key_table(c, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		server_status_client(c);
 | 
			
		||||
 | 
			
		||||
@@ -638,15 +656,15 @@ retry:
 | 
			
		||||
	 * root table and try again.
 | 
			
		||||
	 */
 | 
			
		||||
	if (c->flags & CLIENT_REPEAT) {
 | 
			
		||||
		server_client_key_table(c, "root");
 | 
			
		||||
		server_client_set_key_table(c, NULL);
 | 
			
		||||
		c->flags &= ~CLIENT_REPEAT;
 | 
			
		||||
		server_status_client(c);
 | 
			
		||||
		goto retry;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* If no match and we're not in the root table, that's it. */
 | 
			
		||||
	if (strcmp(c->keytable->name, "root") != 0) {
 | 
			
		||||
		server_client_key_table(c, "root");
 | 
			
		||||
	if (strcmp(c->keytable->name, server_client_get_key_table(c)) != 0) {
 | 
			
		||||
		server_client_set_key_table(c, NULL);
 | 
			
		||||
		server_status_client(c);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
@@ -657,7 +675,7 @@ retry:
 | 
			
		||||
	 */
 | 
			
		||||
	if (key == (key_code)options_get_number(s->options, "prefix") ||
 | 
			
		||||
	    key == (key_code)options_get_number(s->options, "prefix2")) {
 | 
			
		||||
		server_client_key_table(c, "prefix");
 | 
			
		||||
		server_client_set_key_table(c, "prefix");
 | 
			
		||||
		server_status_client(c);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
@@ -842,7 +860,7 @@ server_client_repeat_timer(__unused int fd, __unused short events, void *data)
 | 
			
		||||
	struct client	*c = data;
 | 
			
		||||
 | 
			
		||||
	if (c->flags & CLIENT_REPEAT) {
 | 
			
		||||
		server_client_key_table(c, "root");
 | 
			
		||||
		server_client_set_key_table(c, NULL);
 | 
			
		||||
		c->flags &= ~CLIENT_REPEAT;
 | 
			
		||||
		server_status_client(c);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -385,6 +385,7 @@ server_destroy_session(struct session *s)
 | 
			
		||||
		} else {
 | 
			
		||||
			c->last_session = NULL;
 | 
			
		||||
			c->session = s_new;
 | 
			
		||||
			server_client_set_key_table(c, NULL);
 | 
			
		||||
			status_timer_start(c);
 | 
			
		||||
			notify_attached_session_changed(c);
 | 
			
		||||
			session_update_activity(s_new, NULL);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								tmux.1
									
									
									
									
									
								
							@@ -2576,6 +2576,11 @@ is in milliseconds.
 | 
			
		||||
Set the maximum number of lines held in window history.
 | 
			
		||||
This setting applies only to new windows - existing window histories are not
 | 
			
		||||
resized and retain the limit at the point they were created.
 | 
			
		||||
.It Ic key-table Ar key-table
 | 
			
		||||
Set the default key table to
 | 
			
		||||
.Ar key-table
 | 
			
		||||
instead of
 | 
			
		||||
.Em root .
 | 
			
		||||
.It Ic lock-after-time Ar number
 | 
			
		||||
Lock the session (like the
 | 
			
		||||
.Ic lock-session
 | 
			
		||||
@@ -2668,8 +2673,19 @@ See the
 | 
			
		||||
section for details.
 | 
			
		||||
.It Ic prefix Ar key
 | 
			
		||||
Set the key accepted as a prefix key.
 | 
			
		||||
In addition to the standard keys described under
 | 
			
		||||
.Sx KEY BINDINGS ,
 | 
			
		||||
.Ic prefix
 | 
			
		||||
can be set to the special key
 | 
			
		||||
.Ql None
 | 
			
		||||
to set no prefix.
 | 
			
		||||
.It Ic prefix2 Ar key
 | 
			
		||||
Set a secondary key accepted as a prefix key.
 | 
			
		||||
Like
 | 
			
		||||
.Ic prefix ,
 | 
			
		||||
.Ic prefix2
 | 
			
		||||
can be set to
 | 
			
		||||
.Ql None .
 | 
			
		||||
.It Xo Ic renumber-windows
 | 
			
		||||
.Op Ic on | off
 | 
			
		||||
.Xc
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								tmux.h
									
									
									
									
									
								
							@@ -87,6 +87,7 @@ struct tmuxproc;
 | 
			
		||||
 | 
			
		||||
/* Special key codes. */
 | 
			
		||||
#define KEYC_NONE 0xffff00000000ULL
 | 
			
		||||
#define KEYC_UNKNOWN 0xfffe00000000ULL
 | 
			
		||||
#define KEYC_BASE 0x100000000000ULL
 | 
			
		||||
 | 
			
		||||
/* Key modifier bits. */
 | 
			
		||||
@@ -1801,6 +1802,8 @@ void	 server_update_socket(void);
 | 
			
		||||
void	 server_add_accept(int);
 | 
			
		||||
 | 
			
		||||
/* server-client.c */
 | 
			
		||||
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 *);
 | 
			
		||||
void	 server_client_handle_key(struct client *, key_code);
 | 
			
		||||
void	 server_client_create(int);
 | 
			
		||||
 
 | 
			
		||||
@@ -344,7 +344,7 @@ tty_keys_add1(struct tty_key **tkp, const char *s, key_code key)
 | 
			
		||||
	if (tk == NULL) {
 | 
			
		||||
		tk = *tkp = xcalloc(1, sizeof *tk);
 | 
			
		||||
		tk->ch = *s;
 | 
			
		||||
		tk->key = KEYC_NONE;
 | 
			
		||||
		tk->key = KEYC_UNKNOWN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Find the next entry. */
 | 
			
		||||
@@ -444,7 +444,7 @@ tty_keys_find1(struct tty_key *tk, const char *buf, size_t len, size_t *size)
 | 
			
		||||
		(*size)++;
 | 
			
		||||
 | 
			
		||||
		/* At the end of the string, return the current node. */
 | 
			
		||||
		if (len == 0 || (tk->next == NULL && tk->key != KEYC_NONE))
 | 
			
		||||
		if (len == 0 || (tk->next == NULL && tk->key != KEYC_UNKNOWN))
 | 
			
		||||
			return (tk);
 | 
			
		||||
 | 
			
		||||
		/* Move into the next tree for the following character. */
 | 
			
		||||
@@ -534,7 +534,7 @@ first_key:
 | 
			
		||||
			if (tk->next != NULL)
 | 
			
		||||
				goto partial_key;
 | 
			
		||||
			key = tk->key;
 | 
			
		||||
			if (key != KEYC_NONE)
 | 
			
		||||
			if (key != KEYC_UNKNOWN)
 | 
			
		||||
				key |= KEYC_ESCAPE;
 | 
			
		||||
			goto complete_key;
 | 
			
		||||
		}
 | 
			
		||||
@@ -620,7 +620,7 @@ complete_key:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Fire the key. */
 | 
			
		||||
	if (key != KEYC_NONE)
 | 
			
		||||
	if (key != KEYC_UNKNOWN)
 | 
			
		||||
		server_client_handle_key(tty->client, key);
 | 
			
		||||
 | 
			
		||||
	return (1);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user