Skip to content

🐛 fix(keymap): punctuation shortcuts by US position on non-Latin layouts (#131) - #138

Merged
Cemoche merged 4 commits into
mainfrom
issue-131-nonlatin-positions
Oct 21, 2026
Merged

Cemoche merged 4 commits into
mainfrom
issue-131-nonlatin-positions

Conversation

@Cemoche

@Cemoche Cemoche commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Closes #131

Summary

Since #105, the matcher names a punctuation key by the character it types. That is right for AZERTY, QWERTZ and Dvorak. On non-Latin layouts (Russian, Hebrew, Greek), though, keycaps carry US legends, and browsers and GTK match punctuation shortcuts by US position. This PR restores that on non-Latin layouts.

  • Layout tracker (installLayoutTracker in src/lib/shortcuts.ts):
    • It is a window keydown listener in the capture phase, installed once, before every shortcut listener and the Settings recorder.
    • It learns the layout's script from the last plain letter press: KeyA–KeyZ, no Shift, Alt, AltGr or Meta. Ctrl presses count.
    • A letter outside \p{Script=Latin} switches to the non-Latin state. Turkish ı and ß stay Latin.
  • Non-Latin state: the typed-punctuation and shifted-symbol steps are skipped, so punctuation goes by US position.
    • Russian Ctrl+/ is back on the "/" keycap.
    • Hebrew Ctrl+[ and Ctrl+] are no longer swapped.
    • Hebrew Ctrl+/ is no longer on the Q key.
  • Latin state: the Keyboard: punctuation shortcuts and letter keys that type ASCII (AZERTY ',', Dvorak, Hebrew) #105 rule is unchanged. This departs from the issue's proposal to drop the step-5 letter-position fallback, and keeps it.
    • Without it, Hebrew Ctrl+W has no key in the Latin state, both at startup and after switching from a Latin layout to Hebrew before typing a letter.
    • The cost is cosmetic: Dvorak's "'" key and QWERTZ Ctrl+AltGr+Q also read as Ctrl+Q, which has no default.
  • Limit: the webview cannot ask which layout is active. Right after a layout switch, the previous layout's rule applies until a letter is typed. Example: on Dvorak right after Russian, Ctrl+, and Ctrl+/ have no key until then. On macOS, Cmd presses don't update the tracker (not verified); plain typing does.
  • Tests:
    • The every-key-of-every-layout sweeps (one match at most, Ctrl+Alt matches nothing, recorder round trip) run on all 7 layouts in both states.
    • "Every default has a key" runs in each layout's own state and in the Latin startup state with no letter typed.
    • Explicit tables cover Russian, Hebrew and Greek. Other tests cover which presses update the tracker, an end-to-end switch through useShortcut, and recorder cases.
    • src/test/setup.ts resets the tracker after each test.
  • Docs: amendment Keyboard: keep US positions for punctuation shortcuts on non-Latin layouts (Russian, Hebrew) #131 in spec §5.3 (Keyboard: punctuation shortcuts and letter keys that type ASCII (AZERTY ',', Dvorak, Hebrew) #105's "provisional" note now points to it), the README paragraph under the shortcut table, and the manual check note.

AZERTY behaviour is unchanged. No Rust change.

How it was tested

$ pnpm exec vitest run --maxWorkers=1     # 1375 tests passed; after the review round: shortcuts + SettingsDialog, 85 passed
$ pnpm exec tsc --noEmit                  # clean

Manual check list (GNOME, with Russian, Hebrew and French AZERTY input sources; Super+Space to switch)

  1. AZERTY, after typing any letter:
    • Ctrl+, (the "," key) opens Settings; Ctrl+; does nothing.
    • Ctrl+! and Ctrl+Shift+: comment in the editor.
    • Ctrl+& / Ctrl+é go to tabs 1 and 2; the "-" key gives tab 6.
    • Ctrl+W (the key labelled W) closes the tab.
  2. Switch to Russian and type one letter in the editor (e.g. "ф"):
    • Ctrl + the "/" keycap comments.
    • Ctrl + the "[" / "]" keycaps go to the previous / next tab.
    • Ctrl + the "," keycap opens Settings.
    • Ctrl + the W keycap closes the tab.
  3. Still on Russian, Settings → Keymap → record Ctrl + the "/" keycap: it reports the comment conflict.
  4. Switch to Hebrew and type one letter: Ctrl + the "/" keycap comments, Ctrl + the Q keycap does not, and Ctrl+[ / Ctrl+] are not swapped.
  5. Switch to Hebrew and, without typing a letter, press Ctrl + the W keycap: the tab closes (step-5 fallback, fix round 1).
  6. Switch back to AZERTY and type one letter: step 1 behaviour is back. Before you type the letter, the "," key would still be read by position (Ctrl+M) — that is the stale limit.
  7. Greek, after a letter: Ctrl + the "/" keycap comments, and Ctrl + the W keycap closes the tab.

Checklist

  • pnpm test green
  • pnpm lint green (tsc; no Rust change, clippy in CI)
  • pnpm test:rust green (not applicable: no src-tauri/ change)
  • No secret, token, real password or private key in the diff
  • User-visible strings in src/lib/strings.ts
  • Commits follow <emoji> <type>(<scope>): <description>

🤖 Generated with Claude Code

Cemoche and others added 4 commits October 21, 2026 05:06
A capture-phase window listener learns the layout's script from plain
letter presses (KeyA–KeyZ without Shift, Alt, AltGr or Meta; Ctrl counts).
When the last letter typed is not Latin (Russian, Hebrew, Greek…),
keyPressOf skips the typed-punctuation steps and names keys by US
position again: Ctrl+/ is the "/" keycap, Hebrew brackets are not
swapped. On Latin layouts the #105 rule stays, minus the letter-position
name for plain ASCII (Dvorak's "'" key and QWERTZ Ctrl+AltGr+Q are no
Ctrl+Q). The recorder reads the same state.

Refs #131

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…DME, manual check)

Refs #131

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Without it Hebrew's "'" key (KeyW) had no name in the Latin state, so
Ctrl+W did nothing at startup or right after a switch from a Latin
layout. Dvorak's "'" key and QWERTZ Ctrl+AltGr+Q read as Ctrl+Q again
(cosmetic). New sweep: every default has a key on every layout in the
Latin startup state, no letter typed.

Refs #131

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Refs #131

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Cemoche
Cemoche merged commit 144e58a into main Oct 21, 2026
6 checks passed
@Cemoche
Cemoche deleted the issue-131-nonlatin-positions branch October 21, 2026 03:24
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.

Keyboard: keep US positions for punctuation shortcuts on non-Latin layouts (Russian, Hebrew)

1 participant