Skip to content

Fix blank popover on macOS 26 Tahoe#23

Closed
coherent-cache wants to merge 1 commit into
tobi:mainfrom
coherent-cache:fix/menubarextra-scrollview-blank
Closed

Fix blank popover on macOS 26 Tahoe#23
coherent-cache wants to merge 1 commit into
tobi:mainfrom
coherent-cache:fix/menubarextra-scrollview-blank

Conversation

@coherent-cache

Copy link
Copy Markdown

Summary

On macOS 26 (Tahoe) the menu-bar popover renders blank in the middle — the mode toggle, volume slider and footer draw, but the device-section area is empty. Child view bodies still execute with the right data (verified via os_log inside body); nothing paints.

Changes

  • Views/MenuBarView.swift — drop the ScrollView around the device sections. Under MenuBarExtra(.window) on macOS 26, ScrollView content fails to render, and .frame(maxHeight:) doesn't work around it (see Apple Developer Forums thread 741601; .fixedSize(horizontal: false, vertical: true) helps in some layouts but not this one). Since the popover has bounded content, a plain VStack lets MenuBarExtra auto-size correctly.
  • Views/DeviceListView.swift + HiddenDevicesToggleView — key ForEach by the AudioDevice value instead of \.id (AudioObjectID). A CoreAudio device with both input and output streams (virtual loopback drivers, aggregates) produces two AudioDevice values sharing one AudioObjectID, and disconnected placeholders all use id = 0. This triggered SwiftUI's "ID occurs multiple times" warning and collapsed the hidden-devices list into undefined rendering.
  • Services/PriorityManager.swiftunhideDevice(_:) now clears the UID from both hiddenSpeakers and hiddenHeadphones for outputs. Previously it only cleared whichever list matched getCategory(for:), so unhiding from the ignored popover could silently land the device in a section that wasn't currently visible, making the action look like a no-op.

Test plan

No tests added — the upstream project has no test target, and two of the three fixes are SwiftUI rendering regressions that aren't cleanly unit-testable (a snapshot-based approach via ImageRenderer + Vision OCR is feasible if a test target is added later).

Verified manually on macOS 26.2 / Xcode 17:

  • Builds cleanly via ./build.sh
  • Popover now shows Speaker / Headphone / Microphone sections with live devices (verified via live popover and offscreen ImageRenderer snapshot)
  • Unhiding from the ignored popover returns the device to its section regardless of current mode
  • No more ForEach<…> ID occurs multiple times warnings in the log when virtual loopback devices are present

- MenuBarView: drop the ScrollView. Under MenuBarExtra(.window) on Tahoe,
  ScrollView content fails to render (child bodies run but nothing draws).
  .frame(maxHeight:) does not work around it. A plain VStack lets the
  popover auto-size correctly.

- DeviceListView / HiddenDevicesToggleView: key ForEach by the AudioDevice
  itself, not by AudioObjectID. Devices with both input and output streams
  share one AudioObjectID, and disconnected placeholders share id=0, which
  triggered SwiftUI duplicate-id warnings and undefined rendering.

- PriorityManager.unhideDevice: for outputs, clear both hiddenSpeakers and
  hiddenHeadphones. The old code only cleared the list matching the device's
  current category, so "unhide" from the ignored popover could drop a device
  into a section that wasn't on screen, making the action look like a no-op.
@coherent-cache coherent-cache deleted the fix/menubarextra-scrollview-blank branch April 17, 2026 21:55
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