Skip to content

Typing broken on keyboard layouts with dead keys (es, fr, US-Intl, Nordic…): apostrophe untypable and word gets skipped #304

Description

@Ukly0

中文摘要: 在带死键(dead key)的键盘布局上(西班牙语、法语、美式国际、北欧等),打字练习完全无法输入撇号 ':浏览器把死键报告为 key='Dead',会被当成字面字符 "Dead" 进入输入内容;而把死键"落"成字符的组合空格又被当成真正的分词空格,导致正在输入的单词被跳过。现有输入管线(隐藏输入框 + keyCode 229 过滤)是为中文 IME + 美式键盘设计的,没有覆盖死键布局。


Bug description

TypeWords' keydown handling assumes a plain US-English keyboard. On layouts where ', ", ^, ~, ` are dead keys (Spanish, French AZERTY, US-International, Italian, Nordic, Polish-programmer, Turkish…), typing practice breaks in two ways:

  1. The apostrophe cannot be typed at all. To produce a literal ', users press the dead key and then Space (the composition terminator the OS consumes). Chromium/Gecko report the dead-key keydown as key='Dead', which currently enters the typing pipeline as the literal text "Dead".
  2. The word being typed gets skipped/hidden. The Space that terminates the dead-key composition is treated as a real word-separator space, so the current word is completed/advanced mid-word (e.g. typing Harry' + Space + s for Harry's jumps to the next word right after the apostrophe).

Root cause

The existing input pipeline (hidden #typing-listener input + keyCode 229 filter + keydown↔input dedup) was designed for Chinese IME users on a US physical keyboard, and has no dead-key handling:

  • Browsers report dead keys two different ways, and neither is currently handled:
    • Model 1 — key='Dead' (Chromium/Gecko on Linux/Windows/macOS): the dead-key keydown itself is forwarded to the typing handlers as a character.
    • Model 2 — base character (some environments): the dead-key keydown looks like a normal ' but inserts no character until the next key; the composition Space then arrives as a real Space keydown.
  • The composed character does arrive through the hidden input's input event (layout-agnostic), so no new plumbing is needed — only correct dead-key lifecycle handling on top of it.

Proposed solution

(implemented, PR follows)

  • Drop key='Dead' keydowns from the pipeline — the real character is already delivered by the OS composition through the hidden input's input event.
  • Swallow the Space keydown that immediately follows a dead key (it is a composition terminator consumed by the OS, not a word separator).
  • For Model 2: track a pending-composition state on apostrophe-class keydowns and clear it when a real character lands in the hidden input — so plain English layouts (real ' followed by real Space) are completely unaffected.
  • Unit tests for both reporting models + the English no-regression case.

Impact

Dead-key layouts cover hundreds of millions of typists (es, fr, it, pt, ca, Nordic, US-Intl…). Since TypeWords' audience is precisely non-English-keyboard users learning English, this affects a core audience. The app already partially acknowledges non-US keyboards (keyCode 229 handling, full-width ‘ ’ “ ” Quote mapping).

Environment

  • Verified by analysis + unit tests on Linux with the Spanish (es) layout (Chromium reports key='Dead').
  • Not yet verified on real macOS/Windows hardware — reports from users on those platforms are welcome.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions