Repository navigation
Share one dual-tap detector between the Wall and the iframe shim - #1372
Merged
Merged
Conversation
The shim's dual-tap detector never reset between Shift or Meta taps, so typing a left-Shift capital, a word, then a right-Shift capital inside a proxied iframe posted 'leader' and dropped the pane out of passthrough. The Wall's own detector already resets on any other key.
Deploying mouseterm with
|
| Latest commit: |
bbd3626
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://84388cc2.mouseterm.pages.dev |
| Branch Preview URL: | https://fix-iframe-shim-leader-reset.mouseterm.pages.dev |
The shim hand-copied the Wall's left-then-right detector and drifted: it never cancelled a pending tap. `dualTap` in lib/src/lib/dual-tap.ts now owns the whole rule, the Wall calls it on every keydown, and the shim embeds its source. A test runs it from source in an empty context so it stays self-contained. The other modifier now cancels a pending tap too: left Shift, left Meta, right Shift is no longer the gesture. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Typing in a proxied iframe Surface could drop the pane out of passthrough. The injected shim posts
leaderon a left-then-right Shift (or Meta) tap within 500 ms, but its detector never cleared a pending tap when another key came in between. So typing "I Am" into a text field in the frame (left Shift for theI, right Shift for theA) read as the chord, and the Wall calledexitTerminalMode()mid-sentence. The Wall's own detector already reset on any other key; the shim was a hand copy that had drifted.The root fix is one detector.
dualTapinlib/src/lib/dual-tap.tsowns the whole rule: left-then-right on the same modifier under 500 ms, and any other key cancels a pending tap.dispatchinuse-wall-keyboard.ts, before the terminal-context branch, so context keys still cancel.handleDualTapshrinks to exiting passthrough on a completed gesture and consuming bare Meta/Shift; the four refs andDualTapStateinkeyboard/types.tsare gone.var dualTap=${dualTap}), bound by position because the website's Vite build minifies it and can rename the function.dual-tap.tsdocuments the self-containment constraint this puts on it.Behaviour change: the other modifier now cancels a pending tap too. Left Shift, left Meta, right Shift used to fire because the two modifiers had independent tracks; it no longer does.
docs/specs/layout.md→ "Mode switching" is updated to match.Verification:
lib/src/lib/dual-tap.test.tsruns one table of key sequences (the gesture, the 500 ms boundary, right-then-left, mixed modifiers, "I Am", the other modifier between taps) twice: against the function, and against its source evaluated in an emptynode:vmcontext, so a closure over module scope fails.iframe-proxy-rewrite.test.tsdrives the shipped shim'skeydownlistener.iframe-proxy-rewrite.tswith esbuild--minify --keep-namesand ran the resulting shim: the function came out renamed and still posted one leader for a clean ⇧⇧ and none for "⇧ I ⇧".tsc -b,lint:specs, andlint:mdpass locally.🤖 Generated with Claude Code