Skip to content

Popups open far below the bar on a notched display when their shadow is large #643

Closed

Description

@M4n0x

What happens

On a MacBook's built-in display (with a notch), a theme with a large popup shadow makes popups open far below the bar. With popupDefaults.shadowRadius: 24, bar.height: 52 and bar.margin: 6, the More widgets tray (⋯) opens 36 pt below the bar instead of 6 pt. Widget popups are placed the same way and drop by the same amount.

On an external display whose menu bar hides, the same configuration opens the tray 6 pt below the bar.

Steps to reproduce

  1. On a Mac with a notch, keep the bar at the top and use a theme or configuration with:
    {
      "bar": { "height": 52, "margin": 6 },
      "popupDefaults": { "shadowColor": "#00000080", "shadowRadius": 24 }
    }
  2. Put more widgets on the right than fit, so the More widgets button (⋯) shows.
  3. Click ⋯ on the built-in display.

Expected

The tray opens 6 pt below the bar, as it does on a display without the notch strip.

Environment

  • StableBar 0.15.0
  • macOS 27.2
  • MacBook built-in Retina display, 1512 × 982 pt: frame.maxY 1440, visibleFrame.maxY 1408 (a 32 pt strip at the top)
  • External Dell U2722D, 2560 × 1440, with visibleFrame equal to frame: not affected

Evidence

  • The visible bar ends 46 pt from the top of the screen (52 − 6). The tray's window starts 50 pt above its visible edge for the shadow (shadowRadius × 2 + 2), so StableBar places the window's top 2 pt from the top of the screen (46 + 6 − 50).
  • A standalone borderless NSPanel at .floating, given that frame on the built-in display, sits 32 pt from the top once ordered front. That moves it 30 pt down, which leaves the tray 36 pt below the bar. A subclass that returns frameRect from constrainFrameRect(_:to:) stays where it was put. On the Dell, neither moves.
  • The tray in a screenshot of the running bar sits 82 pt from the top of the screen, which matches 32 + 50.

Diagnosis

On main (000007e):

  • WidgetPopup.openTooltip (Sources/StableBar/WidgetPopup.swift:466-484) pads the popup by shadowInset = shadowRadius * 2 + 2 and places the window at edge - size.height - 6 + shadowInset. WidgetPopup.open (:574) does the same for widget popups. With a large shadow, the window's transparent top margin reaches into the menu bar strip, while the visible popup stays below the bar.
  • AppKit's constrainFrameRect(_:to:) moves a window whose top is above screen.visibleFrame.maxY down to it when the window is shown. PopupPanel (WidgetPopup.swift:5) and the popup's shadow window (a plain NSPanel from makeShadowWindow, :967) don't override it. The windows that live in that strip do: BarPanel (StableBarApp.swift:211), PassiveBarPanel, BarEditControls and BarEditAddPopover.
  • The constraint applies only on a display whose visibleFrame stops below its top, such as a built-in display with a notch. It doesn't apply when the menu bar hides there and visibleFrame equals frame. Themes with the default shadowRadius (2) leave the window's top below the strip, so they're unaffected.

Related

Triaged by Claude Code (Claude Opus 5.5).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions