Skip to content

Fix empty MenuBarExtra popover (device list was height 0) - #33

Open
makingmusic wants to merge 1 commit into
tobi:mainfrom
makingmusic:fix/show-device-list-in-popover
Open

Fix empty MenuBarExtra popover (device list was height 0)#33
makingmusic wants to merge 1 commit into
tobi:mainfrom
makingmusic:fix/show-device-list-in-popover

Conversation

@makingmusic

@makingmusic makingmusic commented Aug 27, 2026

Copy link
Copy Markdown

What you see today

Clicking the menu bar icon opens a popover that looks finished — Speakers / Headphones / Custom, volume slider, Login / Edit / Quit — but no devices. No Speakers section, no Headphones section, no Microphones, not even “No devices”.

CoreAudio is fine. The volume slider still drives the default output. The rows are in the view tree; the window is just too short to show them.

Likely a macOS 26 regression

This does not look like an AudioPriorityBar logic bug. Device enumeration still works; the popover layout broke after a macOS update.

The ScrollView { … }.frame(maxHeight: 420) layout was already in the app. What changed is how MenuBarExtra(.window) sizes itself on newer 26.x: a ScrollView now gets an ideal height of ~0pt, so the window shrinks to the header + footer and clips every device row. Older macOS (and earlier 26.x) apparently still gave that ScrollView enough height to show the lists.

If you are still on an older macOS and have not seen this, that fits.

Cause

MenuBarView wraps the device lists in:

ScrollView {  }
    .frame(maxHeight: 420)

MenuBarExtra { … }.menuBarExtraStyle(.window) sizes the window to the content’s ideal height. A ScrollView has no intrinsic height, so SwiftUI gives it ~0pt. The header and footer have intrinsic sizes, so they still render. The lists sit in the gap and get clipped.

Same collapse is described in #22, #28, and #30 (all still open).

What this PR does

Two small view-only changes. No audio / priority / persistence logic.

1. Drop the ScrollView (MenuBarView.swift)

Let the device VStack size the popover. Typical setups have a handful of devices, so a growing window is the right default. This does not depend on whatever ideal-height quirk the current macOS build has.

Approach Why not here
.fixedSize(vertical: true) on the ScrollView (#22) Still asks a view whose ideal height is 0
minHeight: on the ScrollView (#30) Reserves a hole even when the list is short; easy to get wrong across modes
GeometryReader + PreferenceKey (#28) Correct if we need a 420pt cap, but a lot of machinery for a menu with ~5 rows

If a 420pt cap + scrolling becomes necessary (Edit mode with dozens of remembered devices), wrap the VStack later with a measured height — not a ScrollView that reports 0.

2. Always show the row ⋯ menu (DeviceListView.swift)

Move to Speakers / Headphones, Ignore, Never Use were behind if isHovering. Hover in a MenuBarExtra window is flaky, so those actions often never appeared. The ⋯ is always on the row now (dimmed while dragging). Menu contents are unchanged.

This also matters because renamed Bluetooth devices (e.g. AirPods named “smile”) never match HeadphoneDetection and land in Speakers. Without a visible ⋯ there is no way to Move to Headphones.

Tested

  • macOS 26.6.2, Xcode 26.6, ./build.sh (universal Release)
  • Before: popover was header + volume + footer only
  • After: Speakers listed MacBook Pro Speakers, a Bluetooth headset, and ZoomAudioDevice; Microphones listed the built-in mic and others; ⋯ was visible without hovering
  • Drag-to-reorder, ⋯ → Move to Headphones, Ignore, Never Use still work

Happy to split the ⋯ change into a follow-up if you’d rather take the layout fix alone.

ScrollView inside MenuBarExtra(.window) has no intrinsic height, so the
popover collapsed to the header/footer and hid every device. Size the
lists to their content instead.

Keep the row ⋯ menu always visible: hover is unreliable in menu-bar
windows, which made Move to Headphones / Ignore / Never Use hard to find.
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