From d259168bd728531f26f09bca5ff282ec667e73aa Mon Sep 17 00:00:00 2001 From: Daniil <116022124+TheMelbine@users.noreply.github.com> Date: Wed, 1 Jul 2026 20:48:03 +0300 Subject: [PATCH] fix(shortcuts): also map /, ?, #, ! by physical position Extend the layout-agnostic handling to the symbol shortcuts. On non-Latin layouts the characters '/', '?', '#', '!' are often unreachable or on different keys, so map them from their US-QWERTY physical codes (Slash, shifted Digit1 / Digit3). Fixes e.g. '?' (open shortcuts help) on a Cyrillic layout. --- hooks/use-keyboard-shortcuts.ts | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/hooks/use-keyboard-shortcuts.ts b/hooks/use-keyboard-shortcuts.ts index 227fb26e..a203ecca 100644 --- a/hooks/use-keyboard-shortcuts.ts +++ b/hooks/use-keyboard-shortcuts.ts @@ -55,16 +55,26 @@ function isInputFocused(): boolean { return isInput || isContentEditable; } -// Latin letter shortcuts must fire regardless of the active keyboard layout -// (e.g. Cyrillic, Greek): derive the physical letter from event.code -// (KeyA..KeyZ) instead of the layout-dependent event.key. Non-letter keys keep -// event.key, which is either layout-independent (arrows, Enter, Escape) or -// intentionally symbol-based (#, !, ?, /). +// Shortcuts must fire regardless of the active keyboard layout (e.g. Cyrillic, +// Greek). Derive the key from the PHYSICAL key (event.code) instead of the +// layout-dependent event.key: letters from KeyA..KeyZ, and the symbol shortcuts +// (/, ?, #, !) from their US-QWERTY positions so they stay reachable on non-Latin +// layouts. Arrows/Enter/Escape keep event.key, which is already layout-neutral. function physicalShortcutKey(event: KeyboardEvent): string { const code = event.code; if (code && code.length === 4 && code.startsWith("Key")) { return code.charAt(3).toLowerCase(); } + switch (code) { + case "Slash": + return event.shiftKey ? "?" : "/"; + case "Digit1": + if (event.shiftKey) return "!"; + break; + case "Digit3": + if (event.shiftKey) return "#"; + break; + } return event.key.toLowerCase(); }