Skip to content

Record and send printable keys by character, resolved against the active keyboard layout - #21

Open
DParent10 wants to merge 1 commit into
mainfrom
fix/layout-aware-keys
Open

DParent10 wants to merge 1 commit into
mainfrom
fix/layout-aware-keys

Conversation

@DParent10

Copy link
Copy Markdown
Owner

What does this PR do?

Fixes the keyboard-layout half of #10 ("cut becomes quit on Dvorak").

Mappings stored a physical key code and recording used a QWERTY table keyed by key code, so on any non-QWERTY layout both halves were wrong: pressing the key that types x on Dvorak was recorded as b, and a mapping recorded as Cmd+X on QWERTY sent Cmd+Q on Dvorak.

  • New KeyboardLayout resolves a printable character to the key that produces it on the current input source (TISCopyCurrentKeyboardLayoutInputSource + UCKeyTranslate), including whether Shift is needed (digits on AZERTY). Cached per input source ID, rebuilt on layout change.
  • KeyStroke.canonicalKeyString now records printable keys by the character produced. Special keys (Return, arrows, F-keys, Delete…) still come from the key-code table; their characters are controls or private-use code points.
  • ButtonMapper resolves single-character keys through KeyboardLayout at send time and unions any required Shift into the event flags; falls back to the recorded key code, then the static table. Modifier-only keys and special keys are unaffected.

Existing profiles keep working: a stored "x" with keyCode 7 now resolves by the character first, so it types x on every layout.

Testing

Unit tests added (KeyboardLayoutTests): printable classification, capture preferring the character, and a live resolution on the current layout. Hardware check pending on Dvorak: existing Cmd+X mapping cuts rather than quits; recording a key while on Dvorak stores the right letter.

🤖 Generated with Claude Code

…e active layout

Mappings stored a physical key code, and recording used a QWERTY table keyed
by key code, so on Dvorak (or any non-QWERTY layout) both halves were wrong:
pressing the key that types "x" was recorded as "b", and a mapping recorded
as Cmd+X on QWERTY sent Cmd+Q. Fixes the layout half of #10.

- KeyboardLayout resolves a printable character to the key (and whether Shift
  is needed) on the current input source via UCKeyTranslate, cached per source.
- canonicalKeyString records printable keys by the character produced; special
  keys (Return, arrows, F-keys) still use the key-code table.
- ButtonMapper resolves single-character keys through KeyboardLayout at send
  time and adds Shift when the layout requires it (digits on AZERTY), falling
  back to the recorded key code or the static table.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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