fix(sender): stop the status menu from orphaning a click-eating window#111
Merged
swellweb merged 1 commit intoJun 15, 2026
Merged
Conversation
Clicking the menu bar icon's menu and then selecting an item left a persistent "dead zone" below the icon: a rectangle where the cursor was visible but hover/clicks never landed, cleared only by quitting the app. A window dump while the zone was present showed a TargetBridge-owned, layer-101 (menu/popup), alpha-0 window at the menu's exact 974x272 footprint — the menu's backing window had faded out but was never closed. Two changes remove the orphaning: - Assign one NSMenu for the status item's lifetime and repopulate it lazily via NSMenuDelegate.menuNeedsUpdate(_:), instead of reassigning item.menu = makeMenu() on every service.objectWillChange. Swapping the menu object while it is open/tracking can strand its window. - Defer each menu-item handler to the next runloop tick. The handlers ran synchronously while the menu was still dismissing; activating the app, ordering windows front, or mutating observed session state mid-dismissal interrupted the fade-out so the window reached alpha 0 but was never removed. Deferring lets the menu fully tear down first. This was the primary cause — the dead zone only appeared after selecting an item, not on plain open/close. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Problem
Opening the menu bar icon's menu and then selecting an item left a persistent "dead zone" below the icon — a rectangle where the cursor was visible but hover/clicks never landed (links wouldn't highlight, menu bar unclickable). It cleared only by quitting the app, and reproduced reliably after clicking an option (not on plain open/close).
A system window dump while the dead zone was present revealed the culprit:
A TargetBridge-owned, invisible, menu-layer window sitting at the menu's exact footprint — the menu's backing window had faded out but was never closed, so it kept swallowing clicks.
Cause
Each
@objcmenu-item handler ran synchronously while the menu was still dismissing. Activating the app, ordering windows front (showMainWindow), or mutating observed session state (addSession/stopAll) mid-dismissal interrupted the menu window's fade-out: alpha reached 0 but the window was never removed.A secondary contributor: the controller reassigned
item.menu = makeMenu()on everyservice.objectWillChange(which fires constantly during a session), so the menu object could be swapped while open/tracking.Fix
NSMenufor the status item's lifetime; repopulate items lazily viaNSMenuDelegate.menuNeedsUpdate(_:)instead of swapping the menu object.Testing
Built locally (
xcodebuild … TBDisplaySender). Verified on-device: opened the menu and exercised Show main window, Add session, and Stop all repeatedly during an active session — no dead zone appears, and the orphaned layer-101 alpha-0 window no longer shows in the window dump.🤖 Generated with Claude Code