fix(tui): use Kitty flag 1 on Windows to fix Shift+letter input
WezTerm/ConPTY on Windows drops Shift+letter keypresses entirely when Kitty keyboard protocol flag 4 (report alternate keys) is set. Fall back to flag 1 (disambiguate only) on Windows so shifted printable keys are delivered as raw characters instead of being silently eaten. Also adds a defensive SHIFT_MAP fallback in decodeKittyPrintable for terminals that send CSI-u sequences with the shift modifier but omit the shifted_key secondary codepoint.
This commit is contained in:
@@ -307,6 +307,32 @@ const KITTY_MOD_CTRL = 4;
|
||||
const KITTY_MOD_SUPER = 8;
|
||||
const KITTY_MOD_NUM_LOCK = 128;
|
||||
const KITTY_LOCK_MASK = 64 + KITTY_MOD_NUM_LOCK; // Caps Lock + Num Lock
|
||||
const SHIFT_MAP: Record<number, number> = {
|
||||
// US layout: unshifted codepoint → shifted codepoint
|
||||
// digits
|
||||
48: 41, // 0 → )
|
||||
49: 33, // 1 → !
|
||||
50: 64, // 2 → @
|
||||
51: 35, // 3 → #
|
||||
52: 36, // 4 → $
|
||||
53: 37, // 5 → %
|
||||
54: 94, // 6 → ^
|
||||
55: 38, // 7 → &
|
||||
56: 42, // 8 → *
|
||||
57: 40, // 9 → (
|
||||
// symbols
|
||||
45: 95, // - → _
|
||||
61: 43, // = → +
|
||||
91: 123, // [ → {
|
||||
93: 125, // ] → }
|
||||
92: 124, // \ → |
|
||||
59: 58, // ; → :
|
||||
39: 34, // ' → "
|
||||
96: 126, // ` → ~
|
||||
44: 60, // , → <
|
||||
46: 62, // . → >
|
||||
47: 63, // / → ?
|
||||
};
|
||||
const MODIFY_OTHER_KEYS_PATTERN = /^\x1b\[27;(\d+);(\d+)~$/;
|
||||
const KITTY_KEYPAD_OPERATOR_TEXT: Record<number, string> = {
|
||||
57410: "/",
|
||||
@@ -430,8 +456,15 @@ function decodeKittyPrintable(data: string): string | undefined {
|
||||
}
|
||||
|
||||
let effectiveCodepoint = codepoint;
|
||||
if (effectiveMod & KITTY_MOD_SHIFT && typeof shiftedKey === "number") {
|
||||
effectiveCodepoint = shiftedKey;
|
||||
if (effectiveMod & KITTY_MOD_SHIFT) {
|
||||
if (typeof shiftedKey === "number") {
|
||||
effectiveCodepoint = shiftedKey;
|
||||
} else if (codepoint >= 97 && codepoint <= 122) {
|
||||
effectiveCodepoint = codepoint - 32;
|
||||
} else {
|
||||
const shifted = SHIFT_MAP[codepoint];
|
||||
if (shifted !== undefined) effectiveCodepoint = shifted;
|
||||
}
|
||||
}
|
||||
|
||||
if (effectiveCodepoint >= 0xe000 && effectiveCodepoint <= 0xf8ff) {
|
||||
|
||||
@@ -1105,6 +1105,12 @@ export class ProcessTerminal implements Terminal {
|
||||
// Push level-2 to keep its shortcuts reporting consistently.
|
||||
this.#kittyEnableSeq = "\x1b[>7u";
|
||||
this.#safeWrite(this.#kittyEnableSeq);
|
||||
} else if (process.platform === "win32") {
|
||||
// WezTerm/ConPTY on Windows drops Shift+letter keypresses entirely
|
||||
// when flag 4 (report alternate keys) is set. Use flag 1
|
||||
// (disambiguate only) to keep shifted printable keys working.
|
||||
this.#kittyEnableSeq = "\x1b[>1u";
|
||||
this.#safeWrite(this.#kittyEnableSeq);
|
||||
} else {
|
||||
// Disambiguate escape codes and report base-layout keys for physical
|
||||
// shortcut matching, without event reporting that caused regression #3259.
|
||||
|
||||
Reference in New Issue
Block a user