Skip to content

Report the character a key types with each key down - #705

Open
benface wants to merge 1 commit into
not-fl3:masterfrom
benface:key-down-character
Open

benface wants to merge 1 commit into
not-fl3:masterfrom
benface:key-down-character

Conversation

@benface

@benface benface commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

KeyCode is the key's place on macOS (the hardware key code), the web (event.code) and Windows (the scan code): the key a US QWERTY layout has there. That's right for keys picked for where they sit, like WASD, but a letter shortcut such as Cmd+Z should follow the key labelled Z, as macOS menus and browsers do. On a French AZERTY layout, Z is where QWERTY has W, so an app matching KeyCode::Z undoes from the key labelled W. char_event can't fill the gap: it's for typing, so Ctrl turns letters into control characters, Alt into other characters, and the web sends no keypress with Ctrl.

This adds EventHandler::key_down_with_character_event, which carries, with each key going down, the character it types on the keyboard's current layout as Shift (and Command on macOS) change it, but not Control: 'z' for Ctrl+Z, and for Cmd+Z on AZERTY. It's None when the key types no character, or several, or the platform doesn't say. Unless implemented, it hands the key on to key_down_event, so existing handlers are unchanged. Every platform now calls it for every key down, modifier keys included (with None), so a handler implementing only the new method misses no key.

  • macOS: charactersByApplyingModifiers: with only Shift and Command kept, so a layout that types QWERTY's letters while Command is held (Dvorak – QWERTY ⌘) is followed, as macOS menus follow it. charactersIgnoringModifiers before macOS 10.15.
  • Web: event.key, when it's one character, passed to key_down as a code point.
  • Windows: ToUnicodeEx with a keyboard state holding only Shift, and flag 0x4 so the dead-key state is left for WM_CHAR.
  • X11 and Wayland: the keysym they already look up for char_event.
  • Android and iOS: None for now.

Checked with cargo check for macOS, iOS, tvOS, Android, Linux, Windows (GNU) and wasm32. On macOS, a key event on the U.S. layout reads z for Cmd+Z, Ctrl+Cmd+Z, Shift+Cmd+Z and Ctrl+Z. In a browser, key: "m", code: "Semicolon" (AZERTY's M) reaches the handler as KeyCode::Semicolon with Some('m').

Add EventHandler::key_down_with_character_event, which carries what the
key types on the keyboard's layout alongside its KeyCode, the key's place.
It hands the key on to key_down_event unless implemented, so existing
handlers are unchanged. macOS, the web, Windows, X11 and Wayland report the
character; Android and iOS report None.

This lets an app match letter shortcuts by the letter on the key, as
macOS and browsers do, so Cmd+Z undoes from the key labelled Z on AZERTY,
QWERTZ or Dvorak, rather than from the key in QWERTY's Z place.
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