Skip to content

Preserve menu bar icon position when hiding (FB9052637)#71

Open
stavfx wants to merge 1 commit into
xiaogdgenuine:mainfrom
stavfx:fix/preserve-menubar-position-on-hide
Open

Preserve menu bar icon position when hiding (FB9052637)#71
stavfx wants to merge 1 commit into
xiaogdgenuine:mainfrom
stavfx:fix/preserve-menubar-position-on-hide

Conversation

@stavfx

@stavfx stavfx commented May 27, 2026

Copy link
Copy Markdown
Contributor

Problem

With a menu-bar manager like Hidden Bar, Doll's icons keep getting pushed back into the hidden section. Whenever a monitored app restarts (or Doll restarts), the icon jumps to the leftmost slot, undoing the user's arrangement.

Root cause

The "Hide icon if monitored app isn't running" and "Hide icons when there are no new notifications" options hide an icon with statusItem.isVisible = false. On macOS 12+, macOS discards a status item's saved menu-bar position when it's hidden - a long-standing AppKit bug, FB9052637. So when the icon is shown again it reappears at the default leftmost slot, which is exactly the hidden zone of menu-bar managers.

Verified on macOS 26: the NSStatusItem Preferred Position <autosaveName> default is nulled out whenever the item is hidden, even with a stable autosaveName.

Approaches that don't work (on current macOS)

  • isVisible = false/true - loses the position (the bug above).
  • removeStatusItem + recreate - purges the position key entirely.
  • KVO on the position default to restore it (workaround suggested here) - the write is done by a system process out-of-process, so an in-process observer never fires (the 2021 workaround in the FB thread predates the Control Center–managed menu bar).
  • length = 0 to keep the item alive - preserves position but leaves an empty gap in the menu bar.

Fix

Keep using isVisible (so hiding stays gapless), but manage the position ourselves:

  • Snapshot the OS-managed position before hiding - in memory and in a namespaced Doll_SavedPosition_<bundleId> default.
  • Write it back before the item reappears - in showStatusBar() for the normal hide/show cycle, and in monitorApp() to re-seed it across a Doll restart / reboot when the app was closed.

Result: gapless hide and a stable position, including across reboots.

Testing

Manual, on macOS 26 with Hidden Bar: pin icons via ⌘-drag, quit/relaunch monitored apps repeatedly, and restart Doll with apps closed - icons return to their pinned slots every time, and the saved-position defaults stop churning.

The "Hide icon if monitored app isn't running" and "Hide icons when there
are no new notifications" options toggled statusItem.isVisible. On macOS
12+, macOS discards a status item's saved position when it's hidden
(FB9052637), so the icon jumped to the leftmost slot whenever the app
restarted — repeatedly pushing icons into the hidden section of menu-bar
managers like Hidden Bar.

Snapshot the OS-managed position before hiding (in memory and in a
namespaced default), then write it back before the item reappears — in
showStatusBar() for the normal hide/show cycle, and in monitorApp() to
re-seed it across a Doll restart / reboot while the app was closed.

feedback-assistant/reports#200
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant