DocumentationDecision recordsADR-0062
The on-screen keyboard sends keystrokes to the focused editor
People who cannot use a physical keyboard, or who work on a tablet or with a pointer or eye tracker, need a way to type into the note.
accepted
Context
People who cannot use a physical keyboard, or who work on a tablet or with a pointer or eye tracker, need a way to type into the note. The workspace has two editors, ProseMirror for rendered notes and CodeMirror for raw Markdown, plus ordinary inputs such as the title and search fields. Each has its own keymaps, input rules and Vim layer. Typing by writing text into a document model would bypass all of them, and a store action per key would put the renderer store on the keystroke path that the performance contract keeps free of the application shell.
Decision
The on-screen keyboard is a dock in the shell (features/on-screen-keyboard)
that turns each press into a keystroke and delivers it to the focused editable
the way hardware would:
- It dispatches a
keydownon the editor element withkey,code,keyCodeand the latched modifiers. Editor keymaps, input rules, Vim motions and the app's own shortcuts handle it exactly as they handle a real key. - If nothing called
preventDefault, it applies the browser default for that key:execCommand("insertText"),delete,forwardDeleteandinsertParagraphandSelection.modifyfor a contenteditable, and range edits for inputs and textareas. - It dispatches the matching
keyup.
Pointer presses never take focus from the editor. The dock remembers the last focused editable and falls back to the open note's editor. A press made from the keyboard briefly focuses the editor and then returns focus to the key.
Shift, Control, Alt and Super apply to the next key only. Caps Lock, Num Lock and Scroll Lock stay until pressed again; Num Lock off turns the numpad into navigation keys and Scroll Lock scrolls the editor pane instead of moving the caret. The dock is a plain component with its own state. It does not subscribe to the renderer store, and its open state and options are device settings kept in local storage.
Motor accessibility options live in the dock: dwell click, activation on release, and a key size choice. Each key is a button with a spoken name, one tab stop moves between keys with the arrow keys, and latch changes are announced.
Consequences
- Typing through the dock reaches the editors through the same paths as a physical keyboard, so there is no second input pipeline to keep in step.
execCommandis deprecated but remains the only way to feed text to a contenteditable through the editor's own input handling. If a browser drops it, inserted text stops working and the dock needs abeforeinputbased path.Selection.modifyis non-standard, so caret movement for keys the editor does not bind depends on engine support. Chromium and WebKit provide it.- The dock toggles with
mod+alt+kor from the command palette. Some Linux desktops claimmod+alt+k, so it can be rebound. - The dock is not offered on the compact (phone-width) shell. The command is hidden and disabled there and the dock does not render, so the system keyboard and the dock never compete on a phone. A tablet in the full layout still gets the system keyboard when an editor takes focus.
On this page