You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Browse filesBrowse the repository at this point in the historyBrowse files
authored
fix(forwarding): restore hold-to-stop for scanning profiles (#177)
* fix(forwarding): restore hold-to-stop for scanning profiles
Removing it in #173 left switch users no way to end a session from a
switch. A release at or past the Forwarding hold-to-stop stops
forwarding without an actionable release again; shorter holds still
deliver their release so the PC can run hold actions. The idle stop
stays off for scanning, and cancelled or replaced presses keep their
sync-based handling.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* test(forwarding): pin safety stop ordering after a hold-to-stop
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Owen McGirr <o.a.mcgirr@gmail.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/physical-smoke-test.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -67,4 +67,4 @@ Verify three-column/four-row Movement layouts including Scroll up, Scroll down,
67
67
68
68
### Remote scanning
69
69
70
-
With a compatible Windows or macOS PC, assign remote slots in PC settings and select Switchify scanning in Remote Forwarding. Start with one Select switch in automatic mode, then test three slots in manual mode. Check row escape, icon menus, scroll repetition, confirmed drag and shared colour/timing. Verify local mapped keys do nothing while Remote owns scanning, but PC Escape stops it. Check hold action labels on PC. Confirm cancellation and switch replacement never click on release and keep the session running; confirm a hold longer than the Forwarding hold-to-stop still delivers its release and the PC offers hold actions; confirm no idle stop occurs while scanning waits; confirm navigation away, backgrounding and disconnect never click on release and always release an active drag. Changing PC assignments applies to a live session; reload profiles only to refresh the labels shown in Remote. Reconnect must require explicit Start. Use a disposable target application for real-input checks; keep these checks separate from automated tests.
70
+
With a compatible Windows or macOS PC, assign remote slots in PC settings and select Switchify scanning in Remote Forwarding. Start with one Select switch in automatic mode, then test three slots in manual mode. Check row escape, icon menus, scroll repetition, confirmed drag and shared colour/timing. Verify local mapped keys do nothing while Remote owns scanning, but PC Escape stops it. Check hold action labels on PC. Confirm cancellation and switch replacement never click on release and keep the session running; confirm holds shorter than the Forwarding hold-to-stop deliver their release and the PC offers hold actions, and that reaching the hold-to-stop stops forwarding without clicking; confirm no idle stop occurs while scanning waits; confirm navigation away, backgrounding and disconnect never click on release and always release an active drag. Changing PC assignments applies to a live session; reload profiles only to refresh the labels shown in Remote. Reconnect must require explicit Start. Use a disposable target application for real-input checks; keep these checks separate from automated tests.
Copy file name to clipboardExpand all lines: docs/protocol-compatibility.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -39,4 +39,4 @@ Fake tests cover negotiation, backward compatibility, response bounds, serial po
39
39
40
40
PCs may advertise `capabilities.switchScanning: true`. Only then request `switch.profile.list` with `{ "includeScanning": true }`; older PCs retain the empty-object request. The opt-in catalog adds kind `scanning`, ID `builtin.switchify-scanning`, a revision and up to eight stateful/unassigned switch labels. Older clients receive the unchanged catalog. Protocol v1, authentication and existing forwarding command payloads are unchanged.
41
41
42
-
Scanning edges request acknowledgements. The PC owns hold timing for scanning profiles: Remote's hold-to-stop and 60-second idle stop apply to keyboard forwarding only, and a long hold still delivers its release. A cancelled press is withdrawn with a `switch.sync` that omits it, so the PC drops the gesture without selecting; a replacement press is withdrawn with a `switch.sync` and then sent as a fresh press, never as a release. A PC refusal stops forwarding and clears restoration intent. Scanning profiles are never automatically restored after reconnect. A fresh start receives a new session ID; the PC applies its current assignments at start and no longer rejects a stale profile revision, so labels in Remote may lag until profiles are reloaded.
42
+
Scanning edges request acknowledgements. The PC owns hold-action timing for scanning profiles, so holds shorter than the Forwarding hold-to-stop deliver their release; a hold that reaches the hold-to-stop sends session stop without an actionable release, which is the switch user's way out. The 60-second idle stop applies to keyboard forwarding only. A cancelled press is withdrawn with a `switch.sync` that omits it, so the PC drops the gesture without selecting; a replacement press is withdrawn with a `switch.sync` and then sent as a fresh press, never as a release. A PC refusal stops forwarding and clears restoration intent. Scanning profiles are never automatically restored after reconnect. A fresh start receives a new session ID; the PC applies its current assignments at start and no longer rejects a stale profile revision, so labels in Remote may lag until profiles are reloaded.
Copy file name to clipboardExpand all lines: src/app/(tabs)/settings.tsx
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -41,7 +41,7 @@ export default function SettingsScreen() {
41
41
<Viewstyle={cardWidth}><SettingCardtitle="Typing mode"description="Choose whether text sends live or as a draft."><Viewstyle={{flexDirection: 'row',gap: spacing.sm}}><ControlButtonlabel="Live"selected={preferences.typingMode==='live'}onPress={()=>voidpreferencesStore.update({typingMode: 'live'})}/><ControlButtonlabel="Draft"selected={preferences.typingMode==='draft'}onPress={()=>voidpreferencesStore.update({typingMode: 'draft'})}/></View></SettingCard></View>
42
42
<Viewstyle={cardWidth}><SettingCardtitle="Default PC"description="Select the computer used for automatic connection.">{saved.length===0 ? <EmptyStateicon="computer"title="No saved PCs"body="Pair a PC before choosing a default."/> : <Viewstyle={{gap: spacing.sm}}><ControlButtonlabel="Most recently connected"selected={defaultId===null}onPress={()=>voidsetDefault(null)}/>{saved.map((pc)=><ControlButtonkey={pc.desktopId}label={pc.displayName}selected={defaultId===pc.desktopId}onPress={()=>voidsetDefault(pc.desktopId)}/>)}</View>}</SettingCard></View>
43
43
<Viewstyle={cardWidth}><SettingCardtitle="Pointer controls"description="Capabilities reported by the connected computer.">{connection.kind==='connected'&&connection.profile ? <View><ListRowicon="speed"title="Pointer speed"description={`${connection.profile.capabilities.pointerSpeed.scalePercent}%`}/><ListRowicon="repeat"title="Movement repeat"description={connection.profile.capabilities.mouseRepeat.enabled ? 'On' : 'Off'}/><ListRowicon="desktop-windows"title="Displays"description={`${connection.profile.capabilities.displayNavigation.displayCount}`}/></View> : <EmptyStateicon="link"title="Connect a PC"body="Supported pointer controls are provided by the connected computer."/>}</SettingCard></View>
44
-
{Platform.OS==='android' ? <Viewstyle={cardWidth}><SettingCardtitle="Forwarding hold to stop"description="How long a physical switch must be held to stop keyboard forwarding. Switchify scanning uses the PC's hold limit instead."><SelectorFieldlabel="Hold to stop"options={[3_000,5_000,8_000].map((milliseconds)=>({key: milliseconds,label: `${milliseconds/1000} seconds`}))}selectedKey={preferences.forwardingHoldToStopMs}onSelect={(forwardingHoldToStopMs)=>preferencesStore.update({ forwardingHoldToStopMs })}/></SettingCard></View> : null}
44
+
{Platform.OS==='android' ? <Viewstyle={cardWidth}><SettingCardtitle="Forwarding hold to stop"description="How long a physical switch must be held to stop forwarding. With Switchify scanning, shorter holds run the PC's hold actions."><SelectorFieldlabel="Hold to stop"options={[3_000,5_000,8_000].map((milliseconds)=>({key: milliseconds,label: `${milliseconds/1000} seconds`}))}selectedKey={preferences.forwardingHoldToStopMs}onSelect={(forwardingHoldToStopMs)=>preferencesStore.update({ forwardingHoldToStopMs })}/></SettingCard></View> : null}
0 commit comments