From 188fd23e85b2f8e75c7e6cdc9bc7b2e109d13346 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 7 Apr 2021 07:30:02 +0000 Subject: [PATCH] Fixes for extended keys: 1) allow C-x and C-X to be bound separately since some terminals report them differently 2) use the "backspace" option to translate backspace 3) map ctrl which are have the ctrl implied (such as C-x) properly when the terminal reports both the key and the modifier. Note that any key bindings for C-X where C-x is meant must now be changed. --- usr.bin/tmux/key-string.c | 20 +++++++------- usr.bin/tmux/tty-keys.c | 55 ++++++++++++++++++++++++++++----------- 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/usr.bin/tmux/key-string.c b/usr.bin/tmux/key-string.c index 74cdad1621b..eb72dc04665 100644 --- a/usr.bin/tmux/key-string.c +++ b/usr.bin/tmux/key-string.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key-string.c,v 1.63 2020/07/06 07:27:39 nicm Exp $ */ +/* $OpenBSD: key-string.c,v 1.64 2021/04/07 07:30:02 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -45,9 +45,9 @@ static const struct { { "F11", KEYC_F11|KEYC_IMPLIED_META }, { "F12", KEYC_F12|KEYC_IMPLIED_META }, { "IC", KEYC_IC|KEYC_IMPLIED_META }, - { "Insert", KEYC_IC|KEYC_IMPLIED_META }, + { "Insert", KEYC_IC|KEYC_IMPLIED_META }, { "DC", KEYC_DC|KEYC_IMPLIED_META }, - { "Delete", KEYC_DC|KEYC_IMPLIED_META }, + { "Delete", KEYC_DC|KEYC_IMPLIED_META }, { "Home", KEYC_HOME|KEYC_IMPLIED_META }, { "End", KEYC_END|KEYC_IMPLIED_META }, { "NPage", KEYC_NPAGE|KEYC_IMPLIED_META }, @@ -70,7 +70,7 @@ static const struct { { "Right", KEYC_RIGHT|KEYC_CURSOR|KEYC_IMPLIED_META }, /* Numeric keypad. */ - { "KP/", KEYC_KP_SLASH|KEYC_KEYPAD }, + { "KP/", KEYC_KP_SLASH|KEYC_KEYPAD }, { "KP*", KEYC_KP_STAR|KEYC_KEYPAD }, { "KP-", KEYC_KP_MINUS|KEYC_KEYPAD }, { "KP7", KEYC_KP_SEVEN|KEYC_KEYPAD }, @@ -164,7 +164,7 @@ key_string_get_modifiers(const char **string) key_code key_string_lookup_string(const char *string) { - static const char *other = "!#()+,-.0123456789:;<=>'\r\t"; + static const char *other = "!#()+,-.0123456789:;<=>'\r\t\177"; key_code key, modifiers; u_int u, i; struct utf8_data ud, *udp; @@ -181,8 +181,8 @@ key_string_lookup_string(const char *string) /* Is this a hexadecimal value? */ if (string[0] == '0' && string[1] == 'x') { - if (sscanf(string + 2, "%x", &u) != 1) - return (KEYC_UNKNOWN); + if (sscanf(string + 2, "%x", &u) != 1) + return (KEYC_UNKNOWN); mlen = wctomb(m, u); if (mlen <= 0 || mlen > MB_LEN_MAX) return (KEYC_UNKNOWN); @@ -238,11 +238,11 @@ key_string_lookup_string(const char *string) } /* Convert the standard control keys. */ - if (key < KEYC_BASE && (modifiers & KEYC_CTRL) && !strchr(other, key)) { + if (key < KEYC_BASE && (modifiers & KEYC_CTRL) && + strchr(other, key) == NULL && + (key < 64 || key > 95)) { if (key >= 97 && key <= 122) key -= 96; - else if (key >= 64 && key <= 95) - key -= 64; else if (key == 32) key = 0; else if (key == 63) diff --git a/usr.bin/tmux/tty-keys.c b/usr.bin/tmux/tty-keys.c index bf56cc25e4b..d3db07ecd98 100644 --- a/usr.bin/tmux/tty-keys.c +++ b/usr.bin/tmux/tty-keys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-keys.c,v 1.142 2020/09/23 14:57:33 nicm Exp $ */ +/* $OpenBSD: tty-keys.c,v 1.143 2021/04/07 07:30:02 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -61,7 +61,7 @@ static int tty_keys_extended_device_attributes(struct tty *, const char *, /* Default raw keys. */ struct tty_default_key_raw { const char *string; - key_code key; + key_code key; }; static const struct tty_default_key_raw tty_default_raw_keys[] = { /* Application escape. */ @@ -262,7 +262,7 @@ static const key_code tty_default_xterm_modifiers[] = { */ struct tty_default_key_code { enum tty_code_code code; - key_code key; + key_code key; }; static const struct tty_default_key_code tty_default_code_keys[] = { /* Function keys. */ @@ -420,7 +420,7 @@ tty_keys_add(struct tty *tty, const char *s, key_code key) { struct tty_key *tk; size_t size; - const char *keystr; + const char *keystr; keystr = key_string_lookup_key(key, 1); if ((tk = tty_keys_find(tty, s, strlen(s), &size)) == NULL) { @@ -477,7 +477,7 @@ tty_keys_build(struct tty *tty) const struct tty_default_key_raw *tdkr; const struct tty_default_key_xterm *tdkx; const struct tty_default_key_code *tdkc; - u_int i, j; + u_int i, j; const char *s; struct options_entry *o; struct options_array_item *a; @@ -869,6 +869,8 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len, size_t end; u_int number, modifiers; char tmp[64]; + cc_t bspace; + key_code nkey; *size = 0; @@ -911,38 +913,61 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len, } *size = end + 1; - /* Store the key and modifiers. */ - *key = number; + /* Store the key. */ + bspace = tty->tio.c_cc[VERASE]; + if (bspace != _POSIX_VDISABLE && number == bspace) + nkey = KEYC_BSPACE; + else + nkey = number; + + /* Update the modifiers. */ switch (modifiers) { case 2: - (*key) |= KEYC_SHIFT; + nkey |= KEYC_SHIFT; break; case 3: - (*key) |= (KEYC_META|KEYC_IMPLIED_META); + nkey |= (KEYC_META|KEYC_IMPLIED_META); break; case 4: - (*key) |= (KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META); + nkey |= (KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META); break; case 5: - (*key) |= KEYC_CTRL; + nkey |= KEYC_CTRL; break; case 6: - (*key) |= (KEYC_SHIFT|KEYC_CTRL); + nkey |= (KEYC_SHIFT|KEYC_CTRL); break; case 7: - (*key) |= (KEYC_META|KEYC_CTRL); + nkey |= (KEYC_META|KEYC_CTRL); break; case 8: - (*key) |= (KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL); + nkey |= (KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL); break; default: *key = KEYC_NONE; break; } + + /* Don't allow both KEYC_CTRL and implied. */ + if ((nkey & KEYC_CTRL) && (nkey & KEYC_MASK_KEY) < 32) + nkey &= ~KEYC_CTRL; + if ((nkey & KEYC_MASK_MODIFIERS) == KEYC_CTRL) { + nkey &= KEYC_MASK_KEY; + if (nkey >= 97 && nkey <= 122) + nkey -= 96; + else if (nkey == 32) + nkey = 0; + else if (nkey == 63) + nkey = 127; + else + nkey |= KEYC_CTRL; + } + if (log_get_level() != 0) { log_debug("%s: extended key %.*s is %llx (%s)", c->name, - (int)*size, buf, *key, key_string_lookup_key(*key, 1)); + (int)*size, buf, nkey, key_string_lookup_key(nkey, 1)); } + *key = nkey; return (0); } -- 2.20.1