Skip to content

feat(osk): modern touch press model + backspace auto-repeat#166

Draft
doodlewind wants to merge 1 commit into
feat/virtual-listfrom
feat/osk-touch-model
Draft

feat(osk): modern touch press model + backspace auto-repeat#166
doodlewind wants to merge 1 commit into
feat/virtual-listfrom
feat/osk-touch-model

Conversation

@doodlewind

Copy link
Copy Markdown
Collaborator

Part 5/6 of the touch-input series (stacked on #165; uses the gesture layer from #161 and tape/sim touch from #164).

What

framework/src/osk.tsx touch input goes from contact-edge tap (key fires the instant a finger lands) to the modern keyboard press model, via createGesture:

gesture behavior
down press-highlight (native focus:/active: variants — no new class literals)
drag retargets across keys; sliding off the panel cancels
release inside commits the key
backspace down fires immediately + auto-repeats while held (0.4 s / 0.1 s in virtual frames); held □ chord repeats identically
two thumbs each contact arms its own key

Modality: the panel now pushes pushTouchBlock() next to the button block — app gestures under the keyboard are cancelled the frame it opens; the OSK's own recognizer is allowWhenBlocked. D-pad spatial nav, PSP chords, and cursor modes byte-untouched.

Tests

  • OskScripter.tap() — touch-taps at key centers computed from the real layout math.
  • New im-sim Journey E: opens a thread, types "hi" entirely by touch through the built bundle, sends it, and replays hash-identical.
  • Journeys A–D (d-pad/chord driven) green unchanged; devtools + sim suites green; tsc --noEmit clean.

🤖 Generated with Claude Code

The OSK's touch path was a contact-edge tap: a key fired the instant a
finger landed, with no visual press state, no way to slide off a fat-
fingered key, and no drag retargeting. Replace it with the gesture layer's
press model:

- down press-highlights the key under the finger (the existing native
  focus:/active: class variants — zero new class literals),
- dragging retargets across keys, sliding off the panel cancels,
- the key commits on release-inside (the modern-keyboard contract),
- backspace is the exception: fires on the down and auto-repeats while held
  (0.4 s delay, 0.1 s interval, in virtual frames via simulationHz()) — and
  the held □ chord repeats the same way,
- multi-contact: each finger arms its own key (two-thumb typing).

While the panel is up it now pushes a touch block alongside the button
block, so app gestures underneath (a list) are cancelled the frame the
keyboard opens; the OSK's own recognizer is exempt via allowWhenBlocked.
D-pad, chords, and cursor modes are untouched.

tests/osk-script.ts grows tap(): touch-taps at key centers computed from the
real layout (dock-at-bottom convention). New im-sim Journey E types "hi" by
touch through the built bundle and replays hash-identical; Journeys A–D
(button-driven) stay green unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@doodlewind
doodlewind force-pushed the feat/osk-touch-model branch from 095d242 to 0025104 Compare July 23, 2026 13:04
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