From 97d87c44d0163b1de2326144f293013aca7a3f93 Mon Sep 17 00:00:00 2001 From: Daniil <116022124+TheMelbine@users.noreply.github.com> Date: Wed, 1 Jul 2026 20:21:18 +0300 Subject: [PATCH] fix(shortcuts): make keyboard shortcuts layout-agnostic Shortcuts were matched against event.key, which returns a layout-dependent character. On non-Latin layouts (Cyrillic, Greek, ...) the physical letter keys produce non-Latin characters, so single-letter shortcuts (c, j, k, r, e, ...) never fire and users must switch layout to use them. Derive the letter from event.code (KeyA..KeyZ) instead, which is layout-independent. Non-letter keys keep event.key (arrows/Enter are already layout-independent; #, !, ?, / stay symbol-based). --- hooks/use-keyboard-shortcuts.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hooks/use-keyboard-shortcuts.ts b/hooks/use-keyboard-shortcuts.ts index 18840ff5..227fb26e 100644 --- a/hooks/use-keyboard-shortcuts.ts +++ b/hooks/use-keyboard-shortcuts.ts @@ -55,6 +55,19 @@ 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 (#, !, ?, /). +function physicalShortcutKey(event: KeyboardEvent): string { + const code = event.code; + if (code && code.length === 4 && code.startsWith("Key")) { + return code.charAt(3).toLowerCase(); + } + return event.key.toLowerCase(); +} + export function useKeyboardShortcuts({ enabled = true, emails, @@ -75,7 +88,7 @@ export function useKeyboardShortcuts({ if (isInputFocused()) return; const h = handlersRef.current; - const key = event.key.toLowerCase(); + const key = physicalShortcutKey(event); const hasModifier = event.ctrlKey || event.metaKey || event.altKey; // Shortcuts that work with modifiers