Skip to content

fix: warn about another app only when it sends to the pad - #21

Merged
timwata merged 2 commits into
mainfrom
fix/contention-passive-holder
Oct 10, 2026
Merged

timwata merged 2 commits into
mainfrom
fix/contention-passive-holder

Conversation

@timwata

@timwata timwata commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

Right after launch, with no other app open, the panel showed "Also driving this pad: input — colours may fight." Recheck cleared it until the next launch. With the Inspector open it read "input, Micro Manager Inspector". After the first commit fixed that, a second issue showed up: opening and then quitting the Inspector left "Also driving this pad: input" up until Recheck.

Cause

Work Louder's Input (/Applications/input.app) keeps running in the background after its window is closed, and it caused both issues:

  1. It holds the pad. It keeps a client open on the pad's vendor interface (ioreg: "pid 24802, input" under PrimaryUsagePage 65280). Phase 3 raised the warning for any other client in an .authoritative scan, and start() forgets what Recheck acknowledged, so the warning came back on every launch.
  2. It sends host.focused_app on every frontmost-app change, and the firmware answers with a bare "result": null. A live probe showed this: a test process holding the pad logged every reply and scan, first while the Inspector was opened and quit, then while only the frontmost app was switched. Every switch produced a foreign reply with a random id and a null result; the probe's own host.focused_app got the same null back. The reply that came after the Inspector quit found only Input in the scan, so it was blamed on Input, and Input stays running.

Fix

  • Only foreign replies raise the warning. Holding the pad is not driving it.
  • Replies with a null result are ignored. Lighting calls are answered {"ok":1}, so a null reply cannot be a fight over the colours. The filter runs after the own-id check, so our own ids are still consumed. Error replies still count.
  • The registry scan still says who may have sent a reply, and clears the warning once they have gone. A reply is blamed on the newcomers: other clients not already seen holding the pad quietly. If every client there is quiet, it is blamed on all of them. With Input running, the Inspector round trip clears by itself: the warning names only the Inspector and goes away once it has quit.
  • suspectedPIDs keeps a Recheck with the Inspector still open from marking the Inspector as quiet.
  • acknowledgedPIDs is removed, along with the bridge's distinction between .authoritative and .advisory. Recheck's help text is updated.
  • PadEmulator answers host.focused_app with null, as the device does.
  • BridgeContentionTests is rewritten for the new rules (29 tests). Every mutation listed in design/pad-contention.md is caught.
  • README, CLAUDE.md, docs/hacking.md and design/pad-contention.md are updated. The design doc records both bugs, the probe findings and the known limits.

Testing

  • swift build -c release has zero warnings.
  • env -u HERDR_SOCKET_PATH swift test: two runs on the final commit, both green (239 tests, 2 skipped). Earlier, on the first commit, one of seven runs had a single failure. Its test name was lost to output filtering and it did not come back. That run had the real pad and the installed app running, so the failure was likely in a Live* test; this is not confirmed.

User checks (not done in-session)

  • Input running in the background → launch → no warning
  • Switch between apps a few times → still no warning
  • Open the Inspector → "Also driving this pad: Micro Manager Inspector"
  • Quit it, reopen the panel → warning gone without pressing anything

🤖 Generated with Claude Code

timwata and others added 2 commits October 10, 2026 12:55
An app that holds the pad's vendor interface without sending (Work Louder's
Input running in the background) raised the warning on every launch, since
any other client in an authoritative scan raised it and start() forgot what
Recheck had acknowledged.

Only foreign replies raise the warning now. The registry scan lays a reply at
the newcomers (other clients not seen holding the pad quietly), names them,
and clears the warning once they have gone, so the Inspector round trip still
clears by itself while Input keeps running. acknowledgedPIDs is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Input sends host.focused_app to the pad on every frontmost-app change, and
the firmware answers it with a bare null. The reply after the Inspector quit
found only Input in the registry, so it was blamed and the warning stayed
until Recheck. A foreign reply with a null result is not about the lighting
(lighting calls answer {"ok":1}), so it is now ignored, after the own-id
check. PadEmulator answers host.focused_app with null, as the device does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@timwata
timwata merged commit 9360aab into main Oct 10, 2026
1 check passed
@timwata
timwata deleted the fix/contention-passive-holder branch October 10, 2026 10:07
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.

1 participant