feat: repeat navigation keys when the desktop supports it - #141
Merged
Conversation
Lets the remote repeat the arrow keys, Tab, Backspace, Delete, Page Up and Page Down, matching how mouse move and scroll repeat already work. Key repeat rides the existing mouse.repeat.start nested envelope rather than a new command name, so the repeat queue, bridge arming, physical switch stop and cleanup all work unchanged and mouse.repeat.stop remains the single stop for every repeat kind. Gating is capability driven. A desktop that does not advertise keyRepeat parses as unsupported and the remote sends a single keyboard.key press, so an older PC build needs no special case. The same fallback covers key repeat disabled on the desktop and keys outside the advertised allowlist. Keys in live typing keep using the text stream so chunk sequencing is preserved, and are never repeated. Closes #140
…ht stop control Addresses the independent review of this branch. Mirroring the pointer path made any key press while a repeat was active stop the repeat and return without sending the key. For a repeatable key that is the intended toggle, but for Escape, Enter, or any key on a desktop that cannot repeat keys at all it was silent input loss, costing the user a second activation. A key that cannot repeat is now delivered after the repeat stops. The blocked-editing explanation on all three surfaces still told the user to "Stop movement" during a key repeat, when the only control on screen is "Stop repeating". Both now come from one shared repeatStopLabel helper so they cannot drift apart. The Android physical-switch warning now also requires the repeat commands, not just the capability flags, so it cannot appear when no repeat could start. Test fixtures advertised key repeat unconditionally, which quietly turned the action-routing test into a repeat-toggling test and left one fixture claiming key repeat while mouse repeat was unsupported. Key repeat is now opt-in per fixture, with new coverage for repeatable-key routing, live typing still using the stream, and the delivery fix.
… allowlist locally Addresses the second independent review of this branch. The previous fix keyed off "is this key repeatable" rather than "is the active repeat this key's own repeat", so a repeatable key pressed during a pointer repeat, or while a different key repeated, was still dropped - input that main delivered. The session now tracks which key is repeating and swallows the press only when it is that key's own toggle; every other case stops the repeat and still delivers the key. The advertised repeatableKeys list is now intersected with a local set rather than trusted outright. Received data is untrusted, and a desktop advertising Enter would otherwise make the Enter control re-submit on every tick, contradicting the documented guarantee. Adds the coverage the review found missing: the blocked-editing explanation naming the on-screen stop control, and the physical-switch warning being withheld when no repeat could start. Both were verified to fail when their fix is reverted. Also updates the physical smoke test and the two accessibility lines that still named Stop movement as the only repeat stop control.
The previous commit added a local REPEATABLE_KEYS intersection but left protocol-compatibility.md claiming a desktop can widen the advertised list without a Remote release. A PC release adding Home or End would silently send single presses with nothing in the doc explaining why. The paragraph now describes the client cap, what a desktop can still change unilaterally, and adds the fourth fallback cause to the skew list. Also records that Delete, PageUp and PageDown are repeatable but have no Remote action yet, so nobody hunts the picker for a control that does not exist, and narrows the accessibility claim about the blocked-editing text, which keeps its Stop movement wording when dragging or held modifiers block editing without a repeat.
Contributor
Author
|
@- |
enaboapps
marked this pull request as ready for review
September 7, 2026 23:02
Closed
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.
Navigation keys repeat through the existing repeat envelope when the desktop advertises keyRepeat support. Older desktops and unsupported keys retain single-key behavior. Repeat status and stop controls distinguish key repeats from pointer movement.
Modifier changes and commands on an existing typing stream stop the active repeat and clear Remote state and Android switch capture before sending input. This prevents the next navigation-key activation from being swallowed. Stream text, stream keys, and stream close use the repeat queue so pending repeat starts finish before cleanup.
Validation on Node.js 24.13.0:
Closes #140