Repository navigation
feat: repeat navigation keys through the repeat envelope - #680
Merged
Merged
Conversation
Adds held/repeating keyboard input so a remote can repeat the arrow keys, Tab, Backspace, Delete, Page Up and Page Down, mirroring the existing mouse move and scroll repeat. Key repeat rides the existing `mouse.repeat.start` nested command envelope rather than introducing new command names. The desktop's command vocabulary is hand-maintained across five parallel lists, so a new namespace would need entries in all of them plus a permanent alias for existing clients; widening the envelope needs none and reuses the repeat generation, stop and cleanup machinery unchanged. A new `keyRepeat` capability block gates the feature, so old and new peers on either side degrade to single key presses. Each tick is a discrete press and release rather than a held key, so a repeat loop that dies for any reason cannot strand a key down. The one remaining gap, a press that succeeds followed by a failed release, is recorded in `pending_key_releases` and retried by `release_all` - the same deterministic cleanup path used for modifiers. Repeatable keys deliberately exclude printable characters and Space, which would flood text, modifiers, which already latch through `keyboard.modifierDown`, and Enter, which would re-submit on every tick. Modifiers latched before a repeat stay held across ticks so Shift with a repeating arrow extends a selection. Closes #677 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ding Addresses independent review findings on the key repeat change. A repeat tick whose key-up fails leaves the key physically held, and the OS's own auto-repeat then keeps firing it into the focused application. Recovery previously waited for release_all on a terminal path, so a stuck Backspace could delete continuously until the phone disconnected. Every repeat stop path on both runtimes now retries the pending release. Key repeats inject keystrokes but bypass DesktopInput::execute, which refuses keyboard input during Switch Forwarding. The repeat start path now enforces that guard itself rather than offering a way around it. Toggling "Repeat held keys" off mid-repeat also stops the active repeat, so the runtime loop ends deliberately instead of surfacing a red "Key repeat stopped" error on its next tick. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…on change Addresses the second independent review of this branch. The initial-tap failure arm on both runtimes dropped the repeat straight through the controller, bypassing the runtime helper that retries a failed key release. Every later cleanup path is gated on a repeat actually being stopped, so that key stayed held. Both arms now release it. save_settings tested the incoming values rather than a change, so with key repeat persisted off any unrelated settings save cancelled an in-flight mouse repeat. It now compares against the previous values, matching the dwell block above it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Addresses the third independent review of this branch. The stop helpers only retried a pending key release when a repeat had actually been stopped. If a tick's key-up failed and the immediate retry failed too, the key stayed in pending_key_releases with no active repeat, so no later stop would ever free it and the OS kept auto-repeating it into the focused application until disconnect. release_repeat_keys already returns immediately when nothing is pending, so calling it unconditionally costs nothing on the common path and removes the gap on both runtimes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The defensive RepeatCommand::Key arm in BeginRepeat returned after control_active, drag_active and repeat_generation had already been set and without clearing feedback, so if it ever became reachable a later re-render could paint stale pointer feedback. The check now runs before any state is touched, alongside the disabled-overlay guard. Unreachable today, since both runtimes hide the overlay for key repeats rather than beginning one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Key repeat start reported "Accessibility permission is required before the pointer can move." even though it injects keystrokes, while the branches either side of it carefully distinguish key from mouse wording. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
@- |
The comment read as though the repeat path enforced Switch Forwarding for every repeat kind. Pointer repeats have always been allowed during a session; only the new keyboard injection is guarded here.
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.
@-