fix(xpc): make MenuBarItemService work for ad-hoc-signed builds on macOS 26#950
Open
pdurlej wants to merge 2 commits into
Open
fix(xpc): make MenuBarItemService work for ad-hoc-signed builds on macOS 26#950pdurlej wants to merge 2 commits into
pdurlej wants to merge 2 commits into
Conversation
Upstream PR jordanbaird#903 introduced MenuBarItemService.xpc with this line: listener = try XPCListener(service: name, requirement: .isFromSameTeam()) { ... } `.isFromSameTeam()` requires the listener and every peer to be signed with the same Apple Team Identifier. That works for builds Jordan produces from his Developer ID Application certificate. It does NOT work for any ad-hoc-signed build (TeamIdentifier = empty), because empty-vs-empty is never treated as a match — the listener rejects every check-in attempt with "Bogus check-in attempt. Ignoring." and "Dropping check-in message due to code signing requirement". The visible symptom is the Menu Bar Layout settings pane spinning forever on "Loading menu bar items…" — XPC never returns, so Ice never gets the cached item snapshots. This is the same class of bug reported in upstream issues jordanbaird#744 (46 reactions) and jordanbaird#891 (30 react- ions), and it bites every community fork that ships without an Apple Developer Program account — which is roughly every community fork. This commit reads the running process's actual Team Identifier via SecCodeCopySigningInformation; if it's nil (ad-hoc / unsigned), we fall through to the no-requirement activation path. If it's set (properly Developer-ID-signed build), behaviour is unchanged — the strict same-team requirement still applies. For our fire fork: - 0.11.13-fire.0..fire.1 (ad-hoc, this branch's defaults) → fixed. - 0.11.13-fire.2+ once signed with our Developer ID → unchanged, still uses .isFromSameTeam() because we'll have a team ID. Also bumps MARKETING_VERSION 0.11.13-fire.1 → 0.11.13-fire.2 and CURRENT_PROJECT_VERSION 1123 → 1124 so Sparkle in installed fire.1 recognizes this as a newer build and offers the update.
Companion to the listener-side fix in the previous commit. The XPCSession client (Ice/MenuBar/MenuBarItems/MenuBarItemServiceConnection.swift) also defaults to .isFromSameTeam() peer requirement, which silently rejects ad-hoc-signed builds the same way the listener did. The refactor introduces MenuBarItemService.ownTeamIdentifier() in the shared layer so both sides query exactly the same predicate. Developer- ID-signed builds keep strict same-team enforcement; ad-hoc community builds skip both requirements (Listener accepts, Client sends).
3 tasks
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.
What
Restores
MenuBarItemServiceXPC connectivity for community ad-hoc-signed builds of Ice on macOS 26 Tahoe.Why
On macOS 26, the new
XPCSession.setPeerRequirement(.isFromSameTeam())API silently rejects every peer when the calling process has no Team Identifier — which is the case for any ad-hoc-signed build (every community fork, everyxcodebuildfrom source). The currentListener.swiftandMenuBarItemServiceConnection.swiftunconditionally apply this requirement, so:Connection.sourcePID(...)always returnsnilMenuBarItemManager.uncheckedCacheItemslogsMissing sourcePID for ...every few secondsThis is the upstream class causing:
Combined: ~130 reactions across the bug class.
How
Introduces a shared
MenuBarItemService.ownTeamIdentifier()helper inShared/Services/MenuBarItemService.swiftthat returns the running process's Team Identifier viaSecStaticCode, ornilif the binary is ad-hoc-signed.Both sides of the XPC handshake gate their
.isFromSameTeam()enforcement onownTeamIdentifier() != nil:MenuBarItemService/Listener.swift— listener falls back to unrestricted activation when no Team ID is availableIce/MenuBar/MenuBarItems/MenuBarItemServiceConnection.swift— client skipssetPeerRequirement(.isFromSameTeam())when no Team ID is availableDeveloper-ID-signed builds (App Store / future TestFlight / signed releases) keep strict same-team enforcement automatically — the helper returns the real Team ID and the requirement applies on both sides. Only community ad-hoc builds skip the requirement, which is the only configuration that can't satisfy it anyway.
Testing
Verified on:
xcodebuildfrom source): Menu Bar Layout pane populates correctly, all three sections (Visible / Hidden / Always-Hidden) render menu bar itemscodesign -dvshowing both peers signed by same Team ID)A working signed + notarized DMG that ships these commits is available for reviewers who want to test without rebuilding: https://github.com/pdurlej/Ice/releases/latest (same
com.jordanbaird.Icebundle ID, drop-in replacement).Notes
This PR is offered in good faith to the upstream repo — the same fix has been deployed in a community fork (pdurlej/Ice, "Fire from Ice") since 2026-05-24 and confirmed working by multiple users on macOS 26.4–26.5. Happy to iterate on the patch shape if a different approach is preferred.
Closes (or contributes toward closing): #744, #891, #913, #846, #818, #832, #872.