Device list identity + unhide clearing both hidden lists#1
Merged
Conversation
A CoreAudio device with both input and output streams (virtual loopback drivers like ZoomAudioDevice, Microsoft Teams Audio, BlackHole 16ch, or aggregates) is created twice by AudioDeviceService.getDevices() - once per scope - and both AudioDevice values share the same AudioObjectID. Disconnected placeholders built via AudioDevice.disconnected(...) all use id = 0. With ForEach(..., id: \.id) SwiftUI emits "ID occurs multiple times" and collapses the list to undefined output. Keying by the full AudioDevice disambiguates input vs output and distinct placeholders.
unhideDevice(_:) previously consulted hiddenKey(for:) (which picks a list based on the device's current category) and cleared a single list. But two existing paths put an output device into a list that does not match its current category: - hideDeviceEntirely(_:) explicitly adds the device to both hiddenSpeakers and hiddenHeadphones. - "Ignore as headphone" / "Ignore as speaker" can hide a device in the non-current category. Clicking the eye in the ignored popover then appears to do nothing - the device is removed from one list but remains hidden in the other. Clear hiddenMics for inputs and both output lists for outputs so "stop ignoring" always succeeds.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two small, independent fixes on top of upstream PR #22 (cherry-picked into this fork's `main`).
1. Key device `ForEach` by `AudioDevice` instead of `AudioObjectID`
`AudioDeviceService.getDevices()` creates two `AudioDevice` values from the same `AudioObjectID` when a device has both input and output streams — the loopback drivers (ZoomAudioDevice, Microsoft Teams Audio, BlackHole 16ch) and aggregates hit this. Disconnected placeholders all use `id = 0`. SwiftUI emits `ForEach<…>: the ID occurs multiple times` and collapses the list. Keying by the full `AudioDevice` (Hashable, includes `type`) disambiguates.
Affected sites:
2. `unhideDevice(_:)` clears both hidden lists for outputs
The previous code consulted `hiddenKey(for:)` and cleared one list. Two existing paths put an output device into a list that doesn't match its current category:
Result: clicking the eye in the ignored popover silently leaves the device hidden in the other list. Fix: clear `hiddenMics` for inputs and both output lists for outputs.
Test plan