Summary
CodexBar can leave its menu bar icon unavailable after the external display that currently hosts the status item is unplugged.
This looks distinct from the existing startup recovery fixes. The app process keeps running, but the NSStatusItem appears to remain tied to the removed display's menu bar instead of being rematerialized on the remaining built-in display.
Steps to Reproduce
- Connect an external display to a Mac.
- Launch CodexBar.
- Have the CodexBar menu bar item visible on the external display's menu bar.
- Unplug the external display while CodexBar is still running.
Actual Behavior
The CodexBar process keeps running, but the menu bar icon does not appear on the built-in display. In my local reproduction, relaunching CodexBar also did not immediately make the icon visible on the built-in menu bar.
Expected Behavior
When macOS screen parameters change and the display hosting the menu bar item disappears, CodexBar should recover the status item on one of the currently active screens, ideally after a short debounce to let AppKit settle.
Related Work
Those fixes are valuable, but I do not see runtime display topology changes being handled today. StatusItemController schedules a startup visibility check, but it does not currently observe NSApplication.didChangeScreenParametersNotification.
Root Cause Hypothesis
NSStatusItem can report as present while its backing button/window is associated with a screen that is no longer part of NSScreen.screens. Because CodexBar only checks visibility at startup, a hot-unplug event can leave the app running with an inaccessible status item.
Proposed Fix
Observe NSApplication.didChangeScreenParametersNotification, debounce the recovery check, and recreate status items when:
- the screen count decreases while any status item is expected to be visible, or
- a visible status item snapshot is blocked/missing/detached from the current
NSScreen.screens.
I have a local patch for this and will open a PR.
Summary
CodexBar can leave its menu bar icon unavailable after the external display that currently hosts the status item is unplugged.
This looks distinct from the existing startup recovery fixes. The app process keeps running, but the
NSStatusItemappears to remain tied to the removed display's menu bar instead of being rematerialized on the remaining built-in display.Steps to Reproduce
Actual Behavior
The CodexBar process keeps running, but the menu bar icon does not appear on the built-in display. In my local reproduction, relaunching CodexBar also did not immediately make the icon visible on the built-in menu bar.
Expected Behavior
When macOS screen parameters change and the display hosting the menu bar item disappears, CodexBar should recover the status item on one of the currently active screens, ideally after a short debounce to let AppKit settle.
Related Work
a75d276fadds startup recovery for a missing status item.Those fixes are valuable, but I do not see runtime display topology changes being handled today.
StatusItemControllerschedules a startup visibility check, but it does not currently observeNSApplication.didChangeScreenParametersNotification.Root Cause Hypothesis
NSStatusItemcan report as present while its backing button/window is associated with a screen that is no longer part ofNSScreen.screens. Because CodexBar only checks visibility at startup, a hot-unplug event can leave the app running with an inaccessible status item.Proposed Fix
Observe
NSApplication.didChangeScreenParametersNotification, debounce the recovery check, and recreate status items when:NSScreen.screens.I have a local patch for this and will open a PR.