From 3835afffd9e0c4fae7ff4211e466db358c7cba53 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 3 Oct 2024 05:41:59 +0000 Subject: [PATCH] Improve fix for shifted keys so it works for all the keys it should, Stanislav Kljuhhin in GitHub issue 4146. --- usr.bin/tmux/input-keys.c | 6 +----- usr.bin/tmux/tty-keys.c | 32 +++++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/usr.bin/tmux/input-keys.c b/usr.bin/tmux/input-keys.c index f7756858760..fc6cf7f82d1 100644 --- a/usr.bin/tmux/input-keys.c +++ b/usr.bin/tmux/input-keys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input-keys.c,v 1.100 2024/10/02 08:06:45 nicm Exp $ */ +/* $OpenBSD: input-keys.c,v 1.101 2024/10/03 05:41:59 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -557,10 +557,6 @@ input_key_mode1(struct bufferevent *bev, key_code key) (onlykey >= '@' && onlykey <= '~'))) return (input_key_vt10x(bev, key)); - /* Avoid reporting A as Shift-A, which is not expected in mode 1. */ - if ((key & KEYC_MASK_MODIFIERS) == KEYC_SHIFT) - return (input_key_vt10x(bev, key)); - /* * A regular key + Meta. In the absence of a standard to back this, we * mimic what iTerm 2 does. diff --git a/usr.bin/tmux/tty-keys.c b/usr.bin/tmux/tty-keys.c index e01f52ac53a..d95ded39361 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.180 2024/10/01 06:15:47 nicm Exp $ */ +/* $OpenBSD: tty-keys.c,v 1.181 2024/10/03 05:41:59 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1016,7 +1016,7 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len, u_int number, modifiers; char tmp[64]; cc_t bspace; - key_code nkey; + key_code nkey, onlykey; struct utf8_data ud; utf8_char uc; @@ -1080,13 +1080,7 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len, /* Update the modifiers. */ if (modifiers > 0) { modifiers--; - /* - * The Shift modifier may not be reported in some input modes, - * which is unfortunate, as in general case determining if a - * character is shifted or not requires knowing the input - * keyboard layout. So we only fix up the trivial case. - */ - if (modifiers & 1 || (nkey >= 'A' && nkey <= 'Z')) + if (modifiers & 1) nkey |= KEYC_SHIFT; if (modifiers & 2) nkey |= (KEYC_META|KEYC_IMPLIED_META); /* Alt */ @@ -1100,6 +1094,26 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len, if ((nkey & KEYC_MASK_KEY) == '\011' && (nkey & KEYC_SHIFT)) nkey = KEYC_BTAB | (nkey & ~KEYC_MASK_KEY & ~KEYC_SHIFT); + /* + * Deal with the Shift modifier when present alone. The problem is that + * in mode 2 some terminals would report shifted keys, like S-a, as + * just A, and some as S-A. + * + * Because we need an unambiguous internal representation, and because + * restoring the Shift modifier when it's missing would require knowing + * the keyboard layout, and because S-A would cause a lot of issues + * downstream, we choose to lose the Shift for all printable + * characters. + * + * That still leaves some ambiguity, such as C-S-A vs. C-A, but that's + * OK, and applications can handle that. + */ + onlykey = nkey & KEYC_MASK_KEY; + if (((onlykey > 0x20 && onlykey < 0x7f) || + KEYC_IS_UNICODE(nkey)) && + (nkey & KEYC_MASK_MODIFIERS) == KEYC_SHIFT) + nkey &= ~KEYC_SHIFT; + if (log_get_level() != 0) { log_debug("%s: extended key %.*s is %llx (%s)", c->name, (int)*size, buf, nkey, key_string_lookup_key(nkey, 1)); -- 2.20.1