v0.2.1: focus hand-back, faster switch-back, smaller support file #6

Merged
aporter merged 4 commits from fix/v0.2.1-tester-findings into main 2026-11-04 11:38:08 +10:00
Owner

Fixes from a tester's 0.2.0 support file (Windows 11 26300, Zoom 7.2.5, JW Library Store app): 51 presses, all OK, but:

  1. Focus hand-back failed 9/9 after JW Library had to be re-activated. setForeground now tries SetForegroundWindow, then an empty injected mouse input (no movement or buttons; the PowerToys technique) and tries again, then the old Alt tap (now down+up in one SendInput). Injections run on koffi's worker thread, bounded to 250 ms; a stuck one is never stacked. A hand-back that lands late is watched for up to 300 ms inside the JW recovery deadline, and JW is re-checked afterwards. The log says which method worked.
  2. Switch-back took ~2 s: a fixed 1.5 s settle after JW was already showing. JW now has to stay showing for 300 ms (jwStableMs). VM: JW restore → showing 306–314 ms (was ~1.5 s).
  3. Diagnostics appeared twice in support files: the full JSON is no longer logged (33 KB line); the log gets the summary and the diagnostics-*.json name.
  4. Version 0.2.1 (package, lockfile, manifest, README, INSTALL).

Tests

  • tsc, 125/125 unit tests (10 new; each switch-back/focus test verified to fail without its fix), build, streamdeck validate, gitleaks, whitespace check.
  • Windows VM (real key presses on the emulated MK.2): toggle, triple press, JW minimised, JW minimised 20 s: 6/6 PASS, no WARN/ERROR in the plugin log. SendInput encoding verified on Windows (1 and 2 events inserted; wrong size refused). Results: testing/results/vm-v0.2.1-2026-11-04.md.
  • Not verifiable in the VM: the focus fallback itself (JW never takes the foreground there). The tester's next support file will show it.
  • workbench validate fails on workbench's own skill-link self-tests, unrelated to this repo.

Review

Review-gate: gpt-6.1-sol ship

  • Plan (Gate 1): fix-then-ship. Blockers resolved: JW re-checked after the focus wait; focus watch bounded by the recovery deadline.
  • Diff (Gate 2): fix-then-ship. Blocker resolved: SendInput moved off the plugin's thread (bounded worker, no stacking, regression tests). Re-check: ship; its two comment nits fixed.

🤖 Generated with Claude Code

Fixes from a tester's 0.2.0 support file (Windows 11 26300, Zoom 7.2.5, JW Library Store app): 51 presses, all OK, but: 1. **Focus hand-back failed 9/9** after JW Library had to be re-activated. `setForeground` now tries `SetForegroundWindow`, then an empty injected mouse input (no movement or buttons; the PowerToys technique) and tries again, then the old Alt tap (now down+up in one `SendInput`). Injections run on koffi's worker thread, bounded to 250 ms; a stuck one is never stacked. A hand-back that lands late is watched for up to 300 ms inside the JW recovery deadline, and JW is re-checked afterwards. The log says which method worked. 2. **Switch-back took ~2 s**: a fixed 1.5 s settle after JW was already showing. JW now has to stay showing for 300 ms (`jwStableMs`). VM: JW restore → showing 306–314 ms (was ~1.5 s). 3. **Diagnostics appeared twice in support files**: the full JSON is no longer logged (33 KB line); the log gets the summary and the `diagnostics-*.json` name. 4. Version **0.2.1** (package, lockfile, manifest, README, INSTALL). ### Tests - `tsc`, 125/125 unit tests (10 new; each switch-back/focus test verified to fail without its fix), build, `streamdeck validate`, gitleaks, whitespace check. - Windows VM (real key presses on the emulated MK.2): toggle, triple press, JW minimised, JW minimised 20 s: 6/6 PASS, no WARN/ERROR in the plugin log. `SendInput` encoding verified on Windows (1 and 2 events inserted; wrong size refused). Results: `testing/results/vm-v0.2.1-2026-11-04.md`. - Not verifiable in the VM: the focus fallback itself (JW never takes the foreground there). The tester's next support file will show it. - `workbench validate` fails on workbench's own skill-link self-tests, unrelated to this repo. ### Review Review-gate: gpt-6.1-sol ship - Plan (Gate 1): fix-then-ship. Blockers resolved: JW re-checked after the focus wait; focus watch bounded by the recovery deadline. - Diff (Gate 2): fix-then-ship. Blocker resolved: `SendInput` moved off the plugin's thread (bounded worker, no stacking, regression tests). Re-check: ship; its two comment nits fixed. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
From a tester's 0.2.0 support file (51 presses, all OK; Windows 11 26300):
- Focus hand-back after re-activating JW failed 9/9. setForeground now
  tries SetForegroundWindow, then an empty injected mouse input (no
  movement or buttons; the PowerToys technique) before trying again, then
  the old Alt tap. Returns which method worked; a hand-back that lands late
  is watched for up to 300 ms within the JW recovery deadline. The log says
  which method returned focus, or warns as before.
- JW is re-checked after the focus wait, so a JW that re-hides meanwhile is
  not reported as shown (record kept, next press retries).
- Switch-back took ~2 s: a fixed 1.5 s settle after JW was already
  showing. It must now stay showing for jwStableMs (300 ms, at most
  settleMs); waits for a change to show keep settleMs.
- The diagnostics snapshot is no longer logged as a 33 KB JSON line (it
  appeared twice in every support file); the log gets the summary and the
  diagnostics-*.json name.
- Version 0.2.1 (package, lockfile, manifest, README, INSTALL).

123 unit tests (8 new, each verified to fail without its fix).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Review (gpt-6.1-sol, fix-then-ship): SendInput can block inside the kernel
(PowerToys hit this with the same empty-input technique), and it ran on the
plugin's only thread. The empty mouse input and the Alt tap (which used
keybd_event, the same call) now go through koffi's .async on a worker
thread, waited for at most 250 ms; while an earlier injection hasn't
returned, further ones are skipped so stuck workers never pile up. The Alt
tap is now down+up in one SendInput call, so a late or partial injection
can't leave Alt held. setForeground is async and typed as
"direct" | "input" | "alt" | null.

125 unit tests (bounded worker: never-returning call, no stacking, recovery,
throwing start).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
VM test results for 0.2.1
All checks were successful
ci / secrets (pull_request) Successful in 14s
ci / build (pull_request) Successful in 31s
b5ca0e82d5
Co-Authored-By: Claude Opus 5.5 <[email protected]>
aporter deleted branch fix/v0.2.1-tester-findings 2026-11-04 11:38:09 +10:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
aporter/jwzoomswitcher!6
No description provided.