fix: keyboard shortcuts not working with Russian layout (#2202)
* fix: keyboard shortcuts not working with Russian and other non-Latin layouts When a non-Latin input source (Russian, etc.) is active, event characters are non-ASCII. The ANSI keyCode fallback was blocked when the layout-based translation resolved a character, leaving no safety net. Now the keyCode fallback is always available for non-Latin layouts, matching the physical key position — similar to Ghostty's `physical:` keybinding behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add unit tests for Russian keyboard layout shortcut matching Two tests for Cmd+T with non-Latin (Russian) keyboard layout: 1. Layout provider returns "t" (normal ASCII fallback) — verifies the layout-based matching path works with Cyrillic event chars. 2. Layout provider returns nil (translation failure) — verifies the ANSI keyCode fallback catches the shortcut by physical key position. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: scope ANSI keyCode fallback to non-ASCII events, add Russian to comments Address review feedback: - Split !hasUsableEventChars into two precise conditions: (hasEventChars && !eventCharsAreASCII) for non-Latin layouts, and (!hasEventChars && layoutCharacter empty) for synthetic/empty-char events. This prevents unintended keyCode fallback on Dvorak/Colemak with empty synthetic events. - Add "Russian" to the non-Latin layout list in the guard comment at line 10626. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
66b0260442
commit
cfe6cf89d8
2 changed files with 115 additions and 4 deletions
|
|
@ -10674,7 +10674,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
|
|||
// For command-based shortcuts, trust AppKit's layout-aware characters when present.
|
||||
// Keep this strict for letter shortcuts to avoid physical-key collisions across layouts,
|
||||
// while still allowing keyCode fallback for digit/punctuation shortcuts on non-US layouts.
|
||||
// When a non-Latin input source is active (Korean, Chinese, Japanese, etc.),
|
||||
// When a non-Latin input source is active (Russian, Korean, Chinese, Japanese, etc.),
|
||||
// charactersIgnoringModifiers returns non-ASCII characters that can never match
|
||||
// a Latin shortcut key — skip this guard and fall through to layout-based matching.
|
||||
let hasEventChars = !(eventCharsIgnoringModifiers?.isEmpty ?? true)
|
||||
|
|
@ -10703,15 +10703,20 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
|
|||
// so keep ANSI keyCode fallback for control-modified shortcuts. Also allow fallback for
|
||||
// command punctuation shortcuts, since some non-US layouts report different characters
|
||||
// for the same physical key even when menu-equivalent semantics should still apply.
|
||||
// When a non-Latin input source is active, treat non-ASCII event chars the same as
|
||||
// absent chars — they carry no usable Latin key identity.
|
||||
// When a non-Latin input source is active (Russian, Korean, Chinese, Japanese, etc.),
|
||||
// event chars carry no usable Latin key identity. Always allow keyCode fallback as a
|
||||
// safety net — even when the layout-based translation resolved a character, the
|
||||
// physical key code is the definitive identifier for the intended shortcut.
|
||||
// For empty-character events (synthetic/browser key equivalents), preserve the original
|
||||
// behavior: only fall back when the layout translation also failed.
|
||||
let hasUsableEventChars = hasEventChars && eventCharsAreASCII
|
||||
let allowANSIKeyCodeFallback = flags.contains(.control)
|
||||
|| (flags.contains(.command)
|
||||
&& !flags.contains(.control)
|
||||
&& (
|
||||
!shouldRequireCharacterMatchForCommandShortcut(shortcutKey: shortcutKey)
|
||||
|| (!hasUsableEventChars && (layoutCharacter?.isEmpty ?? true))
|
||||
|| (hasEventChars && !eventCharsAreASCII)
|
||||
|| (!hasEventChars && (layoutCharacter?.isEmpty ?? true))
|
||||
))
|
||||
if allowANSIKeyCodeFallback, let expectedKeyCode = keyCodeForShortcutKey(shortcutKey) {
|
||||
return event.keyCode == expectedKeyCode
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue