Improve fix for shifted keys so it works for all the keys it should,

Stanislav Kljuhhin in GitHub issue 4146.
This commit is contained in:
nicm 2024-10-03 05:41:59 +00:00
parent 05116cefe6
commit 780a87be9a
2 changed files with 22 additions and 12 deletions

View File

@ -557,10 +557,6 @@ input_key_mode1(struct bufferevent *bev, key_code key)
(onlykey >= '@' && onlykey <= '~'))) (onlykey >= '@' && onlykey <= '~')))
return (input_key_vt10x(bev, key)); 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 * A regular key + Meta. In the absence of a standard to back this, we
* mimic what iTerm 2 does. * mimic what iTerm 2 does.

View File

@ -1016,7 +1016,7 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
u_int number, modifiers; u_int number, modifiers;
char tmp[64]; char tmp[64];
cc_t bspace; cc_t bspace;
key_code nkey; key_code nkey, onlykey;
struct utf8_data ud; struct utf8_data ud;
utf8_char uc; utf8_char uc;
@ -1080,13 +1080,7 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
/* Update the modifiers. */ /* Update the modifiers. */
if (modifiers > 0) { if (modifiers > 0) {
modifiers--; modifiers--;
/* if (modifiers & 1)
* 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'))
nkey |= KEYC_SHIFT; nkey |= KEYC_SHIFT;
if (modifiers & 2) if (modifiers & 2)
nkey |= (KEYC_META|KEYC_IMPLIED_META); /* Alt */ 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)) if ((nkey & KEYC_MASK_KEY) == '\011' && (nkey & KEYC_SHIFT))
nkey = KEYC_BTAB | (nkey & ~KEYC_MASK_KEY & ~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) { if (log_get_level() != 0) {
log_debug("%s: extended key %.*s is %llx (%s)", c->name, log_debug("%s: extended key %.*s is %llx (%s)", c->name,
(int)*size, buf, nkey, key_string_lookup_key(nkey, 1)); (int)*size, buf, nkey, key_string_lookup_key(nkey, 1));