Skip to content

Harden menu bar status item placement#1216

Merged
steipete merged 2 commits into
steipete:mainfrom
pdurlej:codex/statusitem-placement-preflight
May 30, 2026
Merged

Harden menu bar status item placement#1216
steipete merged 2 commits into
steipete:mainfrom
pdurlej:codex/statusitem-placement-preflight

Conversation

@pdurlej
Copy link
Copy Markdown
Contributor

@pdurlej pdurlej commented May 29, 2026

Summary

Harden CodexBar status item placement on crowded macOS 26 menu bars.

This PR adds stable NSStatusItem.autosaveName values, writes a low preferred-position key before status item creation when the saved value is missing or suspiciously high, and adds CGWindowList-based diagnostics for real menu-bar window bounds. It also keeps cached brand-percent renders self-healing by reapplying the button title, and makes merged fallback provider selection follow the configured enabled provider order.

Maintainer follow-up: the placement preflight now preserves reasonable legacy AppKit Item-N placement only for the matching new stable identity, so upgrades keep valid existing placement while fresh or suspicious provider identities still get seeded.

Why

Field debugging on macOS 26 showed cases where NSStatusBarButton.title and frame were correct, but the host menu bar placed the status item under/over the clock or off-screen. AX title checks were misleading, so the diagnostics now report CGWindow bounds keyed by the stable autosave/window name.

This does not try to guarantee visibility under active menu-bar managers; it reduces fragility for standalone CodexBar and gives better evidence when the host menu bar is the failing layer.

Changes

  • Add stable autosave names:
    • codexbar-merged
    • codexbar-<provider>
  • Preflight NSStatusItem Preferred Position <autosaveName> to 0 before item creation when missing or greater than 100.
  • Preserve reasonable legacy Item-N placement for the matching stable identity during upgrade.
  • Add MenuBarStatusItemWindowProbe using CGWindowListCopyWindowInfo for bounds/on-screen diagnostics.
  • Include window diagnostics in existing visibility recovery failure logs.
  • Reapply title/image-position state when cached merged brand-percent icon rendering is skipped.
  • Respect enabled provider order in merged fallback provider selection.
  • Use Bundle.module for provider icon resources outside app-bundle execution so package tests exercise the brand-percent path.

Validation

  • swift test --filter StatusItemControllerSplitLifecycleTests - 19 tests passed.
  • swift test --filter MenuBarVisibilityWatcherTests --filter StatusItemAnimationSignatureTests --filter StatusMenuTests - 73 tests passed.
  • make check - SwiftFormat and SwiftLint clean.
  • swift test - 3157 tests in 378 suites passed.
  • /Users/steipete/Projects/agent-scripts/skills/autoreview/scripts/autoreview --mode local - clean, no accepted/actionable findings.

No full app launch in validation: repo policy avoids live provider/keychain prompts for this path; AppKit proof is via status-item/controller tests and CGWindow-style visibility tests.

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 29, 2026

Codex review: needs real behavior proof before merge. Reviewed May 30, 2026, 12:12 PM ET / 16:12 UTC.

Summary
The PR adds stable status-item autosave names, preferred-position preflight/migration, CGWindow menu-bar diagnostics, merged-icon title repair, provider-order fallback selection, and focused tests.

Reproducibility: no. The PR body describes field debugging on crowded macOS 26 menu bars, but the available evidence does not give a high-confidence current-main reproduction path in a real menu-bar setup.

Review metrics: 2 noteworthy metrics.

  • Changed surface: 11 files, +574/-22. The diff touches runtime status-item placement, diagnostics, icon rendering, changelog text, and tests.
  • Test surface: 4 test files updated. Most confidence for the migration behavior currently comes from focused tests rather than live runtime proof.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted real behavior proof for the after-fix crowded menu-bar path, preferably including fresh install and upgrade/legacy placement state.
  • Include enough diagnostic output or visible before/after context to show the status item is actually placed and not hidden by the host menu bar.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body provides tests, lint, and autoreview output only, and explicitly says there was no full app launch; this needs redacted after-fix screenshot/recording, live output, or logs before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Mantis proof suggestion
A short desktop visual proof would materially help verify the changed macOS menu-bar placement behavior. A maintainer can ask Mantis to capture proof by posting a new PR comment that starts with the OpenClaw Mantis account mention, followed by:

visual task: verify CodexBar stays visible and placed correctly on a crowded macOS 26 menu bar after fresh install and an upgrade with legacy Item-N placement.

Risk before merge

  • [P1] This PR changes persisted NSStatusItem Preferred Position behavior and stable autosave identity, so upgrade safety still depends on real AppKit behavior outside the focused tests.
  • [P1] The branch changes visible macOS menu-bar placement behavior, but the available proof is tests/lint/autoreview only rather than a redacted screenshot, recording, live output, or logs from the after-fix runtime path.

Maintainer options:

  1. Require real menu-bar proof (recommended)
    Ask for a redacted screenshot, recording, or diagnostic logs from a crowded macOS 26 menu bar showing the fixed placement path and upgrade preservation.
  2. Accept the tested migration risk
    Maintainers can merge based on the focused tests if they intentionally own the unproven AppKit runtime and upgrade behavior.

Next step before merge

  • [P1] Human review is needed because automation cannot supply the missing real macOS menu-bar proof or accept the compatibility tradeoff for persisted placement migration.

Security
Cleared: The diff does not introduce a concrete security or supply-chain concern; CGWindow diagnostics are filtered to matching status-item names and no dependency or secret-handling surface changes were found.

Review details

Best possible solution:

Land the maintainer-fixup version after adding real macOS after-fix proof for fresh placement and upgrade preservation, or have maintainers explicitly accept the remaining AppKit placement migration risk.

Do we have a high-confidence way to reproduce the issue?

No. The PR body describes field debugging on crowded macOS 26 menu bars, but the available evidence does not give a high-confidence current-main reproduction path in a real menu-bar setup.

Is this the best way to solve the issue?

Mostly yes. Stable autosave names with a legacy-preservation guard and focused migration tests look like a maintainable fix, but merge readiness depends on real runtime proof or explicit maintainer acceptance of the remaining AppKit behavior risk.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 5ce38b605cca.

Label changes

Label changes:

  • add P2: This is a normal-priority macOS menu-bar reliability improvement with limited blast radius but real upgrade/runtime sensitivity.
  • add merge-risk: 🚨 compatibility: The PR changes persisted macOS status-item placement keys and autosave identities, which can affect existing users' menu-bar ordering on upgrade.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • remove rating: 🧂 unranked krab: Current PR rating is rating: 🦪 silver shellfish, so this older rating label is no longer current.

Label justifications:

  • P2: This is a normal-priority macOS menu-bar reliability improvement with limited blast radius but real upgrade/runtime sensitivity.
  • merge-risk: 🚨 compatibility: The PR changes persisted macOS status-item placement keys and autosave identities, which can affect existing users' menu-bar ordering on upgrade.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body provides tests, lint, and autoreview output only, and explicitly says there was no full app launch; this needs redacted after-fix screenshot/recording, live output, or logs before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

What I checked:

  • Repository policy read: AGENTS.md was read fully; it asks for focused tests when safe, but also says UI/runtime behavior should be validated against a freshly built bundle when runtime behavior needs bundle-level validation. (AGENTS.md:23, 5ce38b605cca)
  • Status-item creation path: The PR preflights placement defaults before creating each NSStatusItem and then assigns stable autosave names such as codexbar-merged or codexbar-. (Sources/CodexBar/StatusItemController.swift:217, 38f684169ae3)
  • Upgrade guard source: The placement preflight now skips writing a new stable key when a matching legacy Item-N placement exists and is not considered suspicious, while still seeding missing or high preferred-position values. (Sources/CodexBar/MenuBarStatusItemPlacementPreflight.swift:13, 38f684169ae3)
  • Regression coverage: The branch adds tests for stable autosave names, fresh-install preflight, matching legacy preservation, suspicious legacy repair, and provider-slot matching. (Tests/CodexBarTests/StatusItemControllerSplitLifecycleTests.swift:127, 38f684169ae3)
  • Maintainer follow-up: The PR discussion says steipete pushed fixups preserving reasonable legacy Item-N placement only for the matching new stable identity and added fresh-install, legacy-upgrade, suspicious-slot, mixed-slot, and provider-slot regression coverage. (38f684169ae3)
  • Proof gap: The PR body lists Swift test filters, make check, full swift test, and local autoreview, and explicitly says there was no full app launch; that is test validation, not after-fix real macOS menu-bar behavior proof. (38f684169ae3)

Likely related people:

  • steipete: Current main blame covers the status-item creation path, and nearby menu-bar placement/history commits include preserve status items, avoid hidden autosaved items, repair hidden defaults, plus the maintainer fixup on this branch. (role: recent area contributor and likely follow-up owner; confidence: high; commits: f83fb70b7f24, 30218e29c971, 35cd513b07e2; files: Sources/CodexBar/StatusItemController.swift, Sources/CodexBar/MenuBarVisibilityWatcher.swift, Sources/CodexBar/MenuBarStatusItemDefaultsRepair.swift)
  • René: Recent main history includes a display-change recovery churn fix in MenuBarVisibilityWatcher, which is adjacent to this PR's status-item recovery diagnostics. (role: recent adjacent contributor; confidence: medium; commits: 63d9373b733f; files: Sources/CodexBar/MenuBarVisibilityWatcher.swift, Tests/CodexBarTests/MenuBarVisibilityWatcherTests.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a6f4282e4e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

static func shouldSetPreferredPosition(_ value: Any?) -> Bool {
guard let value else { return true }
guard let number = value as? NSNumber else { return true }
return number.doubleValue > self.suspiciousPreferredPositionThreshold
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve legitimate saved status item positions

When a user already has a real NSStatusItem Preferred Position value above 100 (for example after dragging CodexBar farther left among other menu extras or on a wide display), this treats that saved order as corrupt and prepare resets it to 0 every time the status item is created. That erases the user’s menu bar ordering and can also give all split provider items the same preferred position; the repair should be limited to values that are actually offscreen/corrupt or done as a narrower one-time migration.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 29, 2026
pdurlej and others added 2 commits May 30, 2026 16:46
Set stable autosave names for CodexBar status items and preflight their preferred position before creation so crowded macOS menu bars do not inherit parked Item-N placement.

Add CGWindowList-based diagnostics for status item window bounds, keep cached icon renders self-healing, and make merged fallback provider selection follow enabled provider order.

Cover placement preflight, window probing, stable identities, cached title repair, and provider-order fallback with tests.
@steipete steipete force-pushed the codex/statusitem-placement-preflight branch from a6f4282 to 38f6841 Compare May 30, 2026 16:07
@steipete
Copy link
Copy Markdown
Owner

Pushed maintainer fixups on top of this branch.

Main changes: stable placement keys now preserve reasonable legacy Item-N placement only for the matching new identity, while fresh/missing provider identities and suspicious saved positions still get the low-position preflight. Added regression coverage for fresh installs, legacy upgrades, suspicious legacy slots, mixed legacy slots, and provider-slot matching.

Proof is in the PR body. Thanks @pdurlej.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels May 30, 2026
@steipete steipete merged commit 8545c76 into steipete:main May 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants