Skip to content

Fix numpad vs non-numpad key ambiguity in shortcut binding#10576

Draft
ivandrofly wants to merge 1 commit intoSubtitleEdit:mainfrom
ivandrofly:fix-numpad-shortcut-key-ambiguity
Draft

Fix numpad vs non-numpad key ambiguity in shortcut binding#10576
ivandrofly wants to merge 1 commit intoSubtitleEdit:mainfrom
ivandrofly:fix-numpad-shortcut-key-ambiguity

Conversation

@ivandrofly
Copy link
Copy Markdown
Member

Summary

  • Numpad navigation keys with NumLock off (e.g. NumPad7 → Key.Home) were indistinguishable from their non-numpad counterparts, making it impossible to bind different shortcuts to the two keys
  • Added GetEffectiveKeyName(Key, PhysicalKey) helper in ShortcutManager that returns the PhysicalKey name when the physical key is a numpad key (all Avalonia numpad physical keys are prefixed with "NumPad"), falling back to the logical Key name otherwise
  • ShortcutManager now tracks a parallel _activeEffectiveNames: HashSet<string> using the physical override; shortcut hash lookup in CheckShortcuts iterates this set instead of _activeKeys, while _activeKeys is preserved so existing callers (count checks, AllowedSingleKeyShortcuts filtering) are unaffected
  • GetKeyViewModel uses GetEffectiveKeyName() when recording a key press so that numpad 7 (either NumLock state) is saved as "NumPad7" rather than "Home", matching what CheckShortcuts sees at runtime

Test plan

  • Open Options → Shortcuts, click a shortcut, press the regular Home key — confirm it is recorded as Home
  • With NumLock off, press NumPad 7 — confirm it is recorded as NumPad7 (not Home)
  • With NumLock on, press NumPad 7 — confirm it is still recorded as NumPad7
  • Bind one shortcut to Home and a different shortcut to NumPad7; confirm each fires its own action independently
  • Verify shortcuts using non-numpad keys (letters, F-keys, arrows) still work as before

🤖 Generated with Claude Code

Previously, Avalonia's logical Key enum could not distinguish between
numpad keys (with NumLock off) and their non-numpad counterparts. For
example, pressing NumPad7 with NumLock off would produce Key.Home —
identical to the regular Home key — making it impossible to bind
different shortcuts to the two keys.

Root cause:
Avalonia's Key enum represents *logical* keys. When NumLock is off,
numpad 7 fires Key.Home, numpad 1 fires Key.End, numpad 0 fires
Key.Insert, NumPadDecimal fires Key.Delete, etc. The logical key alone
carries no information about whether the key originated from the numpad.

Fix:
Use KeyEventArgs.PhysicalKey, which reflects the actual hardware key
regardless of NumLock state. All numpad physical keys in Avalonia are
named with the "NumPad" prefix (NumPad0–NumPad9, NumPadDecimal, etc.),
while their logical counterparts are not (Home, End, Insert, Delete,
etc.). The new GetEffectiveKeyName() helper returns the PhysicalKey name
when the physical key is a numpad key, and the logical Key name
otherwise.

Concretely:
  - Regular Home:          PhysicalKey.Home    → "Home"
  - NumPad7 (NumLock ON):  PhysicalKey.NumPad7 → "NumPad7"
  - NumPad7 (NumLock OFF): PhysicalKey.NumPad7 → "NumPad7"  ← was "Home"

Changes:
- ShortcutManager: added GetEffectiveKeyName(Key, PhysicalKey) static
  helper and a parallel _activeEffectiveNames: HashSet<string> that
  tracks pressed keys using the physical override for numpad. The
  existing _activeKeys: HashSet<Key> is preserved unchanged so callers
  that rely on the logical Key enum (e.g. AllowedSingleKeyShortcuts
  filtering, GetActiveKeys().Count checks) continue to work. The
  shortcut hash lookup in CheckShortcuts now iterates
  _activeEffectiveNames instead of _activeKeys.

- GetKeyViewModel: when the user presses a key to record a shortcut
  binding, the stored key name is now derived via GetEffectiveKeyName()
  so that numpad 7 (either NumLock state) is recorded as "NumPad7"
  rather than "Home", matching what CheckShortcuts will see at runtime.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ivandrofly ivandrofly marked this pull request as draft April 9, 2026 20:47
@ivandrofly
Copy link
Copy Markdown
Member Author

#10485
#10486

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.

1 participant