A pinned input device doesn't survive being unplugged — should the user's choice and the resolved device be separate? #792
aguynamedryan
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
First: app-only microphone selection in 1.6.7 is a real improvement. FluidVoice capturing a chosen input without moving the macOS default input is exactly the behaviour I wanted, and #779 / #749 got there with a migration and without the mode-switching machinery I'd been carrying in #642. I'm closing that PR — the substance of it shipped in yours.
There's one behaviour left that I'd like to understand before proposing anything, because I think it's deliberate and I don't want to "fix" a decision.
What happens
I dictate through a USB handset (AB13X USB Audio) that I unplug most days. On 1.6.7:
PreferredInputDeviceUIDis the handset. Works great — other apps keep the built-in mic.Step 3 is the part I'd like to discuss.
Why it happens
reconcileAppOnlySelectionresolves withpersistFallback: true, so when the pinned device is missing the fallback is written back over the user's choice:After that,
preferredInputDeviceUIDnames the built-in mic. On reconnect,handleDeviceListChangedasksAudioCaptureIdlePolicy.shouldReconcileInputSelectionwhether anything changed for the pinned device — and the built-in mic was there before and is there now, so the answer isfalse. Reconciliation is never scheduled. The handset coming back is invisible to the app.So the disconnect doesn't just fall back; it erases the preference that would let the app come back.
I'm fairly sure this is intentional
testMicrophoneCoordinatorFallsBackToBuiltInWhenSelectionDisappears(HotkeyShortcutTests.swift:628) asserts exactly this — pinned AirPods disappear, the fallback is persisted, and on reconnect the app stays on the built-in mic with the preference still overwritten. That's an explicit choice, not an oversight, and I can see the reasons: always having a concrete valid device pinned, and not chasing a flapping device after the route-churn problems in #752.A test for the full round trip
Your suite covers the disconnect. I wrote one that covers both halves together, because the overwrite in the first half is what disables the second. It's in your style, uses
FakeAudioDeviceManagerandwithRestoredDefaults, and passes on currentmain— it documents today's behaviour rather than asserting a change:Happy to open it as a PR on its own if a characterisation test is useful to you regardless of what you decide below.
The question
preferredInputDeviceUIDcurrently carries two meanings — the device the user chose and the device we're using right now — and the persisted fallback lets the second silently overwrite the first. The consequence is that an intermittently-connected device can't be a durable preference: one unplug repoints the app permanently.Would you consider separating them? Roughly:
Reconnect then works through machinery you already have — the pin still names the handset, so
didPreferredInputAvailabilityChangeflips on replug, reconciliation is scheduled, andinputDeviceForCapturefinds it.The narrowest version is gating the existing persist so it only fires when there's no pin yet (first run), which is the case it's genuinely needed for. But if you'd rather keep one key and solve it another way, or you want the current behaviour kept for reasons I'm not seeing, I'd rather hear that than send a PR against it.
Glad to do the work either way — just want to know which shape you'd accept before writing it.
Environment: FluidVoice 1.6.7, macOS 26.6, Apple Silicon.
All reactions