Fix "Unable to display menu bar items" on macOS 26.4#922
Open
heyalchang wants to merge 1 commit into
Open
Conversation
macOS 26.4.1 (Tahoe, build 25E253) appears to have changed the
behavior of the private SkyLight function
CGSCopyActiveMenuBarDisplayIdentifier so that it now returns nil.
This cascades through the cache pipeline:
Bridging.getActiveMenuBarDisplayID() returns nil
MenuBarItemManager.ItemCache.displayID stays nil
MenuBarItemImageCache.updateCacheWithoutChecks bails on its
`guard let displayID` check (silently, no log)
cacheFailed(for:) returns true (items are cached but no images)
Layout pane renders "Unable to display menu bar items"
Same source builds and works on macOS 26.3.1, where the SkyLight
call still returns a valid identifier.
Fix: when the SkyLight call returns nil (or the UUID-to-displayID
lookup fails), fall back to CGMainDisplayID(). Correct for
single-display setups, which is the common case. Multi-display
configurations with an active menu bar on a non-main display may
need a richer fallback (for example, the NSScreen whose frame
intersects the menu-bar window's frame).
emindeniz99
pushed a commit
to emindeniz99/Ice
that referenced
this pull request
Apr 18, 2026
Ice's macos-26 branch left several critical issues that prevent the app from working correctly on Tahoe, especially 26.3+ / 26.4+. This change folds in the fixes from the three community PRs that address them (jordanbaird#903, jordanbaird#911, jordanbaird#922) and the cache-thrash guard from jordanbaird#874. Changes: * `Bridging.getActiveMenuBarDisplayID()` falls back to `CGMainDisplayID()` when `CGSCopyActiveMenuBarDisplayIdentifier` returns nil, which is now the case on macOS 26.4.1. Without the fallback, the item cache's `displayID` stayed `nil` and the layout preview rendered as "Unable to display menu bar items" even though items existed. * `MenuBarItemTag.Namespace` on macOS 26 recognizes Ice's own control items by window title ("Ice.ControlItem.*") and falls back to the owning application's identifiers when the owner isn't Control Center. This stops the UUID-namespace feedback loop that left the layout stuck on "Loading menu bar items..." after Control Center re-parented Ice's status items. * `SourcePIDCache` caches failed AX lookups for 30 seconds, and the item manager no longer invalidates the window-ID cache when `sourcePID` is nil. Those two together stopped the thrash where each failed lookup triggered another full scan, racing with `IceBarPanel.show()` and causing clicks to drop roughly half the time on notched Macs. * `AXHelpers.menuBarElement(nearDisplayOrigin:)` probes several inset points along the leftmost menu bar region instead of hit-testing the exact display corner. Single-point probing fails on notched displays (outside the rounded-corner mask), next to menu bar accessories such as NotchNook, and on Tahoe's translucent menu bar. `getApplicationMenuFrame()` and `hasValidMenuBar(in:for:)` both use the new helper. * `MenuBarItemImageCache.compositeCapture` falls back to `item.bounds` when `CGSGetScreenRectForWindow` fails and tolerates a one-pixel discrepancy in the composite width. This keeps items that Control Center has re-parented from being dropped entirely. * XPC `.isFromSameTeam()` requirement is only applied when the current process actually has a team identifier. Ad-hoc signed builds (the default when no signing team is configured) do not, and the old requirement refused every peer, leaving the `MenuBarItemService` unusable. A new `CodeSignInfo` helper inspects the process's code signature. * The settings detail pane is keyed by the current navigation identifier on macOS 26 so that `NavigationSplitView` reliably updates on the first sidebar click.
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.
Fixes the empty Menu Bar Layout pane on macOS 26.4 / 26.4.1. Likely fixes #913 and #916, possibly #891 and #921.
On macOS 26.4.1 (build 25E253),
CGSCopyActiveMenuBarDisplayIdentifierreturns nil. That cascades:Bridging.getActiveMenuBarDisplayID()returns nilMenuBarItemManager.ItemCache.displayIDstays nil aftercacheItemsRegardlessMenuBarItemImageCache.updateCacheWithoutChecksbails on itsguard let displayIDcheck (silently, no log)cacheFailed(for:)returns true for every section because items were cached but no imagesItems themselves enumerate fine (20 items in my case) and
cacheItemsRegardlessreachesUpdated menu bar item cache-- only the displayID is nil.This PR adds a
CGMainDisplayID()fallback ingetActiveMenuBarDisplayID. Verified on a single-display setup running 26.4.1; the layout pane populates correctly. Multi-display configurations with the menu bar on a non-main display may need a richer fallback (for example, the NSScreen whose frame intersects the menu-bar window's frame), butCGMainDisplayID()is strictly better than nil in every case.Test plan
macos-26clean on macOS 26.4.1, observe the empty Layout pane