From ef211a496de8ba458383fb002d1878f59f206e17 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Mon, 6 Jul 2026 16:01:48 -0700 Subject: [PATCH] menubar-fit: wand out-ranks Menu Band + wizard pinned left of it DateWizard priority 20->40 and Menu Band 40->20 so the broker shrinks Menu Band's piano-key ladder before the wand sheds its countdown badge (the prior ordering did the reverse). Both status items now set an autosaveName and seed 'NSStatusItem Preferred Position' (wizard 24 > menuband 8) so the wand sits to the LEFT of Menu Band; a user Cmd-drag still persists over it. Co-Authored-By: Claude Opus 4.8 (1M context) --- date-wizard/Sources/DateWizard/MenuBarDays.swift | 16 ++++++++++++---- slab/menuband/Sources/MenuBand/AppDelegate.swift | 11 ++++++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/date-wizard/Sources/DateWizard/MenuBarDays.swift b/date-wizard/Sources/DateWizard/MenuBarDays.swift index 1c56ae7cdc..dacdf7576a 100644 --- a/date-wizard/Sources/DateWizard/MenuBarDays.swift +++ b/date-wizard/Sources/DateWizard/MenuBarDays.swift @@ -45,7 +45,15 @@ final class MenuBarDays { // ── lifecycle ───────────────────────────────────────────────────── func install() { barThickness = NSStatusBar.system.thickness + // Pin the wand LEFT of Menu Band. NSStatusItem has no absolute-ordering + // API; its autosaveName + "Preferred Position" default is the lever macOS + // honors (higher = further left). Seed once; a user ⌘-drag persists over it. + let posKey = "NSStatusItem Preferred Position datewizard" + if UserDefaults.standard.object(forKey: posKey) == nil { + UserDefaults.standard.set(24, forKey: posKey) + } statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) + statusItem.autosaveName = "datewizard" if let button = statusItem.button { self.button = button button.imagePosition = .imageOnly @@ -131,13 +139,13 @@ final class MenuBarDays { // ── menu-bar-fit negotiation ────────────────────────────────────── // The wand's ladder: bare → presence-dot → full countdown pill. With no // upcoming event the ladder collapses to just the bare wand so the broker's - // width model stays honest (nothing to shed). Low priority (20): the badge - // is glanceable-but-redundant with the calendar, so DateWizard sheds it - // before Menu Band gives up piano keys. + // width model stays honest (nothing to shed). High priority (40): the wand's + // countdown is the thing to defend, so Menu Band gives up piano keys before + // DateWizard sheds the badge. private func startFitNegotiation() { guard let statusItem, fit == nil else { return } let has = (nextEventDate != nil) - fit = MenuBarFit(slug: "datewizard", priority: 20, + fit = MenuBarFit(slug: "datewizard", priority: 40, rungs: fitRungs(hasNext: has), statusItem: statusItem, startAt: has ? 2 : 0) { [weak self] _, idx in self?.fitRung = idx diff --git a/slab/menuband/Sources/MenuBand/AppDelegate.swift b/slab/menuband/Sources/MenuBand/AppDelegate.swift index b63b98eee3..f7997d3bde 100644 --- a/slab/menuband/Sources/MenuBand/AppDelegate.swift +++ b/slab/menuband/Sources/MenuBand/AppDelegate.swift @@ -698,7 +698,14 @@ final class AppDelegate: NSObject, NSApplicationDelegate { KeyboardIconRenderer.iconScale = max(1.0, min(1.6, (barThickness - 0.5) / baseIconH)) } + // Keep Menu Band to the RIGHT of the wand: lower preferred position than + // datewizard's (higher = further left). Seed once; a ⌘-drag persists over it. + let mbPosKey = "NSStatusItem Preferred Position menuband" + if UserDefaults.standard.object(forKey: mbPosKey) == nil { + UserDefaults.standard.set(8, forKey: mbPosKey) + } statusItem = NSStatusBar.system.statusItem(withLength: KeyboardIconRenderer.imageSize.width) + statusItem.autosaveName = "menuband" debugLog("statusItem created, button=\(statusItem.button != nil) length=\(statusItem.length)") if let button = statusItem.button { let cell = NoHighlightStatusBarCell() @@ -1995,7 +2002,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate { fitLayouts = layouts let startIdx = layouts.firstIndex(of: saved) ?? layouts.count - 1 - fit = MenuBarFit(slug: "menuband", priority: 40, rungs: rungs, + // priority 20 (below datewizard's 40): Menu Band yields piano keys before + // the wand sheds its countdown badge. + fit = MenuBarFit(slug: "menuband", priority: 20, rungs: rungs, statusItem: statusItem, startAt: startIdx) { [weak self] _, idx in guard let self, idx >= 0, idx < self.fitLayouts.count else { return } KeyboardIconRenderer.displayLayout = self.fitLayouts[idx] -- 2.51.2