From 842857dec6035625b14ec81c77045b4562004575 Mon Sep 17 00:00:00 2001 From: "Kai (Tam Nhu) Tran" <61256810+kaitranntt@users.noreply.github.com> Date: Mon, 15 Jun 2026 19:58:00 -0400 Subject: [PATCH] fix(bar): anchor menu panel to top and stop full-screen sizing (#1530) The dropdown height defaulted to screenCap before the content was measured, and the ScrollView frame had no alignment, so an unmeasured panel rendered at nearly full screen height with the content centered in it (macOS then centered the oversized window). Default to a modest height until measured and pin the frame to .top, so the popover anchors under the menu bar and sizes to its content, scrolling only on genuine overflow. --- macos-bar/Sources/CCSBarApp/BarMenuView.swift | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/macos-bar/Sources/CCSBarApp/BarMenuView.swift b/macos-bar/Sources/CCSBarApp/BarMenuView.swift index 59099ede..6bbddcb3 100644 --- a/macos-bar/Sources/CCSBarApp/BarMenuView.swift +++ b/macos-bar/Sources/CCSBarApp/BarMenuView.swift @@ -51,8 +51,12 @@ struct BarMenuView: View { /// Content shorter than the cap renders FULLY with no scroll bar. /// Content taller than the cap scrolls. private var scrollAreaHeight: CGFloat { - guard contentHeight > 0 else { return screenCap } - return min(contentHeight, screenCap) + let cap = screenCap + // Before the first measurement, use a modest default so the popover is never + // sized to the full screen (which macOS then centers). Once the content is + // measured, use its height, capped. + guard contentHeight > 0 else { return min(cap, 560) } + return min(contentHeight, cap) } var body: some View { @@ -132,7 +136,7 @@ struct BarMenuView: View { // Content shorter than the cap renders FULLY (no empty space, no clip). // Content taller scrolls. contentHeight starts at 0 so we show screenCap // until the first preference fires. - .frame(height: scrollAreaHeight) + .frame(height: scrollAreaHeight, alignment: .top) .onPreferenceChange(ContentHeightKey.self) { measured in // Only grow, never shrink — prevents a feedback loop where a smaller // frame triggers a re-layout that reports an even smaller height.