Skip to content

fix: add autosaveName to all Spoons with menubar items#362

Open
johntrandall wants to merge 2 commits intoHammerspoon:masterfrom
johntrandall:fix-menubar-autosavename
Open

fix: add autosaveName to all Spoons with menubar items#362
johntrandall wants to merge 2 commits intoHammerspoon:masterfrom
johntrandall:fix-menubar-autosavename

Conversation

@johntrandall
Copy link
Copy Markdown

@johntrandall johntrandall commented Apr 10, 2026

Summary

  • Adds autosaveName parameter to all hs.menubar.new() calls across 14 Spoons that create persistent menubar items
  • Each Spoon's menubar item gets a stable, unique name matching the Spoon name (e.g., "Caffeine", "TimeMachineProgress")

Problem

Without autosaveName, macOS creates NSStatusItems without a stable identifier. When items are destroyed and recreated (on Hammerspoon config reload, or when a Spoon dynamically shows/hides its menubar item), macOS treats them as brand-new and places them at the far-left of the menubar.

This breaks compatibility with third-party menubar managers that track item positions:

  • Ice — items fall into the "always hidden" section on every reload (verified; tracked in Ice issues #6, #29, #378, #767)
  • Bartender — items lose their configured visibility/position (reported by Hammerspoon maintainer cmsj in #2197)
  • Hidden Bar, Vanilla — likely affected by the same root cause (not directly verified, but they use similar position-based tracking)

Setting autosaveName gives macOS a persistent key to remember each item's user-chosen position across destroy/recreate cycles. This is the standard practice for well-behaved macOS apps — NSStatusItem.autosaveName has been available since macOS 10.12.

Affected Spoons

Caffeine, Cherry, ClipboardTool, ColorPicker, CountDown, EjectMenu, MicMute, PushToTalk, Shade, SpeedMenu, TextClipboardHistory, TimeMachineProgress, TurboBoost, ZeroOffset

Change pattern

Every change follows the same minimal pattern — adding the Spoon name as the second argument:

-- Before
self.menuBarItem = hs.menubar.new()
-- After
self.menuBarItem = hs.menubar.new(true, "SpoonName")

For Spoons that already pass inMenuBar as the first arg (e.g., CountDown, Cherry, SpeedMenu), only the second argument is appended:

-- Before
obj.menuBar = hs.menubar.new(obj.menuBarAlwaysShow)
-- After  
obj.menuBar = hs.menubar.new(obj.menuBarAlwaysShow, "CountDown")

Note: ClipboardTool has a second hs.menubar.new(false) call (line 283) used for an ephemeral popup context menu — this was intentionally left unchanged as it is not a persistent menubar item.

Test plan

  • Verified that hs.menubar.new(inMenuBar, autosaveName) signature is supported (parameter added in Hammerspoon core)
  • Verified no behavioral change: explicit true matches the default inMenuBar value
  • Verified each Spoon has a single persistent menubar item (no name collisions)
  • Tested with Ice 0.11.12: menubar items survive Hammerspoon config reload without falling into "always hidden"

🤖 Generated with Claude Code

Without autosaveName, macOS creates NSStatusItems without a stable
identifier. When items are destroyed and recreated (e.g., on
Hammerspoon config reload, or when a Spoon dynamically shows/hides
its menubar item), macOS treats them as brand-new items and places
them at the far-left of the menubar.

This breaks compatibility with popular menubar managers (Ice, Bartender,
Hidden Bar, Vanilla) that track item positions — they misclassify
recreated items as unknown and hide them. Setting autosaveName gives
macOS a persistent key to remember each item's user-chosen position
across destroy/recreate cycles.

Affected Spoons: Caffeine, Cherry, ClipboardTool, ColorPicker,
CountDown, EjectMenu, MicMute, PushToTalk, Shade, SpeedMenu,
TextClipboardHistory, TimeMachineProgress, TurboBoost, ZeroOffset

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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