Skip to content

Restart switch capture after the computer wakes from sleep - #1180

Merged
enaboapps merged 3 commits into
mainfrom
fix/1179-sleep-switch-capture
Oct 23, 2026
Merged

enaboapps merged 3 commits into
mainfrom
fix/1179-sleep-switch-capture

Conversation

@enaboapps

@enaboapps enaboapps commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1179

Problem

On Windows, keyboard switch capture sometimes stopped working permanently after the PC woke from sleep. The capture worker is health-checked every 500 ms with a 1.5 s timeout on a clock that keeps counting through sleep. The first check after wake could see the entire sleep as worker silence, terminate the worker, and latch Core::worker_failed. Nothing cleared that latch, so every later capture start bailed with "Keyboard capture worker stopped… restart Switchify" and the scanning retry loop could never recover. The power monitor only reset Bluetooth; local capture was never told about sleep.

Change

  • Sleep-aware health check. check_health records when it last ran. If the parent itself missed checks (sleep or a system-wide stall) the worker gets a fresh timeout instead of being terminated. Pure worker_health function with a unit-test matrix.
  • Suspend/resume for switches. switch_runtime::Controller::suspend / resume / suspended, called from the Windows power monitor and the macOS sleep observers. Suspend stops capture with a new StopReason::Suspended, releasing held switch keys, and holds scanning off (scanning_runtime::wanted plus a check under the broker lock in enable) until the resume signal. Resume refreshes the worker's clocks, drops a worker that failed or finished during sleep together with its stale key ownership, and clears the worker latch. Wake is the only thing that clears the latch; ordinary stops still never do.
  • Docs. Troubleshooting page describes sleep behaviour, including that a phone-forwarded session ends on sleep.

Accepted residual: if the worker process is still unresponsive 1.5 s after the parent's first post-wake check and the resume signal has already been handled, the latch can set again until the next sleep cycle. Both processes wake together and the worker polls every 5 ms, so this needs a very slow wake.

Validation

  • npm run prediction-model, npm run lint, npm test (19 pass), npm run build: pass
  • cargo fmt --check, cargo clippy --all-targets -D warnings: pass
  • cargo test: 819 passed, 5 ignored. New tests: health_check_terminates_a_silent_worker_but_not_after_the_parent_slept, sleep_stops_an_active_session_once_and_wake_unlatches_the_worker, sleep_holds_scanning_off_until_the_resume_signal
  • site: npm run build, 16 pages built
  • Three independent review rounds; all actionable findings addressed.

Not yet verified on a real sleep/wake cycle; that needs a device check with the next build.

🤖 Generated with Claude Code

On Windows the keyboard capture worker is health-checked every 500 ms
with a 1.5 s timeout on a clock that keeps counting through sleep. The
first check after wake could see the whole sleep as worker silence,
terminate the worker and latch worker_failed, which nothing cleared, so
switches stayed dead until the app restarted.

The health check now notices when the parent itself missed checks and
grants the worker a fresh timeout instead. The power monitors on Windows
and macOS also stop capture when the computer suspends, so held switch
keys are released, and clear the worker latch on resume so scanning can
re-arm. A Suspended stop reason carries the pause message, and the
troubleshooting page describes the behaviour.

Closes #1179

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
site Ready Ready Preview Oct 23, 2026 7:03pm UTC

Request Review

Scanning re-armed capture one tick after the suspend stop, so the keys
were suppressed again before the computer slept. The switch controller
now stays suspended until the resume signal and scanning treats that
like released keys. On wake the worker's health clocks are refreshed so
pre-sleep silence can never count against it, and a worker that died
while the computer slept is dropped with its stale key ownership.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Drop a latched worker on wake even before its io thread has noticed the
termination, refuse to enable capture under the broker lock while the
computer is suspended, pause switches after Bluetooth in the Windows
suspend handler so a slow capture start cannot delay the Bluetooth pause,
and tell phone users that sleep ends a forwarded session.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@enaboapps
enaboapps marked this pull request as ready for review October 23, 2026 19:07
@enaboapps
enaboapps merged commit fd82adc into main Oct 23, 2026
10 checks passed
@enaboapps
enaboapps deleted the fix/1179-sleep-switch-capture branch October 23, 2026 19:36

This branch was successfully deployed

1 active deployment
Preview — 3d769e72 Deployed Oct 23, 2026 by vercel[bot]
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.

Switches stop working after Windows wakes from sleep

2 participants