From 664499c92e838f36a0ff8187bc2cd95d7b8ef9d5 Mon Sep 17 00:00:00 2001 From: Aditya Garud <153842990+yashranaway@users.noreply.github.com> Date: Sat, 15 Aug 2026 18:03:52 +0530 Subject: [PATCH] Limit physical key fallback to non-Latin layout output (#4469) --- apps/web/src/keybindings.test.ts | 29 +++++++++++++++++++++++++++++ apps/web/src/keybindings.ts | 10 ++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/apps/web/src/keybindings.test.ts b/apps/web/src/keybindings.test.ts index da76e13d56e32430b9418656a840defc6e849460..6ac53a52f18af05e60008dab76752175212e2142 100644 --- a/apps/web/src/keybindings.test.ts +++ b/apps/web/src/keybindings.test.ts @@ -728,6 +728,35 @@ describe("resolveShortcutCommand", () => { "rightPanel.toggle", ); }); + + it("matches non-Latin layout letters using the physical key code", () => { + const keybindings = compile([{ shortcut: modShortcut("d"), command: "diff.toggle" }]); + + assert.strictEqual( + resolveShortcutCommand(event({ key: "в", code: "KeyD", metaKey: true }), keybindings, { + platform: "MacIntel", + }), + "diff.toggle", + ); + }); + + it("ignores the physical key code when the layout types a different Latin letter", () => { + const keybindings = compile([{ shortcut: modShortcut("d"), command: "diff.toggle" }]); + + // On a remapped layout the physical D key types "a"; only the physical + // key whose layout output is "d" may trigger the shortcut. + assert.isNull( + resolveShortcutCommand(event({ key: "a", code: "KeyD", metaKey: true }), keybindings, { + platform: "MacIntel", + }), + ); + assert.strictEqual( + resolveShortcutCommand(event({ key: "d", code: "KeyL", metaKey: true }), keybindings, { + platform: "MacIntel", + }), + "diff.toggle", + ); + }); }); describe("formatShortcutLabel", () => { diff --git a/apps/web/src/keybindings.ts b/apps/web/src/keybindings.ts index 9d6109a7780654557d165d9b2bd9a6246573b2f1..6ec9a6fab858a7f8cb940755d124367defd3a05d 100644 --- a/apps/web/src/keybindings.ts +++ b/apps/web/src/keybindings.ts @@ -71,9 +71,15 @@ function normalizeEventKey(key: string): string { } function resolveEventKeys(event: ShortcutEventLike): Set { - const keys = new Set([normalizeEventKey(event.key)]); + const layoutKey = normalizeEventKey(event.key); + const keys = new Set([layoutKey]); + // The physical-position fallback exists for layouts that type non-Latin + // letters (Cyrillic, Greek) and for Option-modified symbols on macOS. + // When the layout already produces a Latin letter, match on it alone; + // otherwise a remapped physical key triggers shortcuts for two different + // letters at once and shadows system shortcuts on non-QWERTY layouts. const letterCode = event.code?.match(/^Key([A-Z])$/)?.[1]; - if (letterCode) { + if (letterCode && !/^[a-z]$/.test(layoutKey)) { keys.add(letterCode.toLowerCase()); } const aliases = event.code ? EVENT_CODE_KEY_ALIASES[event.code] : undefined; -- 2.54.0