Skip to content

Feat/respect keyboard layout in code fallback#53

Open
dmontagu wants to merge 2 commits intoTanStack:mainfrom
dmontagu:feat/respect-keyboard-layout-in-code-fallback
Open

Feat/respect keyboard layout in code fallback#53
dmontagu wants to merge 2 commits intoTanStack:mainfrom
dmontagu:feat/respect-keyboard-layout-in-code-fallback

Conversation

@dmontagu
Copy link

@dmontagu dmontagu commented Mar 7, 2026

🎯 Changes

Fixes #17

The matchesKeyboardEvent function falls back to event.code (physical key position) when event.key doesn't match the registered hotkey. This fallback exists to handle cases where modifier keys cause the OS to report a special character instead of the expected letter (e.g., macOS Option+T producing instead of T).

However, the fallback currently activates even when event.key is a standard ASCII letter — which means it matches based on physical key position rather than the keyboard layout's logical mapping. This breaks all non-QWERTY keyboard layouts (Dvorak, Colemak, AZERTY, etc.):

Example on Dvorak (macOS with "Use keyboard layout for shortcuts" enabled):

  1. User presses Cmd + physical B key → OS reports event.key='x', event.code='KeyB'
  2. A hotkey registered as Mod+B checks: 'x' === 'b'? No.
  3. Fallback kicks in: event.code = 'KeyB''B' === 'B'? Yes → hotkey fires incorrectly
  4. The user's Cmd+X (cut) is hijacked by the sidebar toggle bound to Mod+B

The fix: When event.key is already a standard ASCII letter (a-z), trust the keyboard layout and return false immediately. The event.code fallback is still used when event.key produces a non-letter character (e.g., , ´, dead keys).

(To be clear, this "example" was a real issue in our Pydantic Logfire app, and is precisely how I noticed this bug, as I am a Dvorak user myself. I have applied the diff from this PR in our own frontend build via pnpm patches, and the problem is now fixed for me.)

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

dmontagu added 2 commits March 6, 2026 16:57
…youts

The `matchesKeyboardEvent` function falls back to `event.code` (physical
key position) when `event.key` doesn't match the hotkey. This fallback
exists to handle cases like macOS Option+T producing '†' instead of 'T'.

However, when `event.key` is already a standard ASCII letter, this
fallback incorrectly matches based on physical key position, breaking
all non-QWERTY keyboard layouts (Dvorak, Colemak, AZERTY, etc.).

For example, on Dvorak with macOS "Use keyboard layout for shortcuts":
- Pressing Cmd + physical B key produces event.key='x', event.code='KeyB'
- A hotkey registered as 'Mod+B' would incorrectly match via the code
  fallback, even though the user pressed Cmd+X in their layout

The fix: when event.key is a standard ASCII letter (a-z), trust the
keyboard layout mapping and skip the event.code fallback. The fallback
is still used when event.key is a non-letter character (like '†') or
a dead key.

Fixes TanStack#17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hotkey registering both for the key and code fields for normal characters

1 participant