-/* $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 <nicholas.marriott@gmail.com>
(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.
-/* $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 <nicholas.marriott@gmail.com>
u_int number, modifiers;
char tmp[64];
cc_t bspace;
- key_code nkey;
+ key_code nkey, onlykey;
struct utf8_data ud;
utf8_char uc;
/* 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 */
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));