Skip to content

fix: mitigate macOS 26 Tahoe menu bar state corruption hiding the tray icon#571

Open
robinebers wants to merge 1 commit into
mainfrom
claude/jovial-hawking-06132c
Open

fix: mitigate macOS 26 Tahoe menu bar state corruption hiding the tray icon#571
robinebers wants to merge 1 commit into
mainfrom
claude/jovial-hawking-06132c

Conversation

@robinebers

@robinebers robinebers commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #517 — on macOS 26.5 (Tahoe), ControlCenter's menu bar bookkeeping can corrupt per-app, parking the status item off-screen at (-1, screenHeight-1) and leaving the app completely unreachable. This is an OS bug (same signature hit CodexBar, Stats, oMLX, NetBird, BetterDisplay), so this PR ships the same mitigations those projects merged:

  1. Clear stale visibility defaults before tray creation (CodexBar 6665d028): drops NSStatusItem Visible* = false records left behind by Tahoe's menu bar migration; true/unrelated entries are untouched. Also migrates the saved Preferred Position from the auto-generated Item-0 identity to the new one, so existing installs keep their menu bar slot.
  2. Explicit autosaveName on the status item (oMLX 7f38bf6): tray-icon leaves the auto-generated Item-0 identity — exactly the record Tahoe corrupts. A custom name re-registers affected installs under a fresh ControlCenter identity on update.
  3. Startup health check with recovery guidance (oMLX): macOS 26+ only, probes the item at +5s and confirms at +15s before acting (avoids fighting ControlCenter, per BetterDisplay's recreation-loop failure). If the item is reported visible but isn't actually hosted on any screen, logs the full state and shows a one-shot alert pointing to System Settings → Menu Bar — since the tray is the app's only entry point.

Implementation: reaches the raw NSStatusItem via TrayIcon::with_inner_tray_iconns_status_item(); the needed objc2-app-kit/objc2-foundation features unify with the versions tray-icon already pulls.

Testing

  • cargo test — 131 passing (4 new unit tests covering the broken-state detection: off-screen, hidden, allow-list-blocked signatures)
  • cargo clippy — clean on changed files
  • Live smoke test on macOS 26.5 (the affected OS version): tray renders normally, health check probe reports visible: true, has_button: true, has_window: true, has_screen: true, window_y: 1084.0 (the bug signature is has_screen: false, window_y: -22), no alert fires, and the position migration verifiably copied Preferred Position Item-0Preferred Position OpenUsage in the live defaults domain
  • The corrupted state itself can't be reproduced on a healthy machine — verification on an affected machine is requested from the reporter in Menu bar status item renders off-screen at (-1, 1116) on macOS 26.5 Tahoe (Apple Silicon) #517

Notes

  • No docs in docs/ describe tray placement behavior, so none needed updating.
  • Known consideration: if "Automatically hide and show the menu bar" turns out to detach the status item window from its screen, the double-probe could false-positive for those users; the two-probe delay plus the alert's once-per-launch cap bounds the impact, and the logged StatusItemHealth makes any report easy to triage.

🤖 Generated with Claude Code


Note

Medium Risk
macOS-only startup logic touches NSUserDefaults and raw NSStatusItem via tray internals; incorrect probes could false-positive alerts, but scope is gated to macOS 26+ with double-delay confirmation.

Overview
Adds macOS 26 (Tahoe)–specific tray mitigations for ControlCenter menu bar state corruption (#517), where the status item can stay hidden or off-screen while the app still thinks it is fine.

A new tray_tahoe module runs before tray creation to clear stale NSStatusItem Visible* = false defaults and migrate Preferred Position from legacy Item-0 to a stable OpenUsage autosave identity. After the tray is built, it sets that autosave name on the raw NSStatusItem and, on macOS 26+, runs a double health probe (5s + 10s) that shows an NSAlert with System Settings recovery steps if the icon is not actually hosted in the menu bar.

tray::create wires these hooks and keeps the built tray handle for post-build setup. Cargo.toml expands objc2-foundation / objc2-app-kit features for NSUserDefaults, status item APIs, and alerts.

Reviewed by Cursor Bugbot for commit 4005e1c. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Mitigates a macOS 26 (Tahoe) menu bar bug that can hide the tray icon by corrupting ControlCenter state, restoring visibility and adding recovery guidance. Addresses #517.

  • Bug Fixes

    • Clear stale NSStatusItem Visible* = false defaults and migrate Preferred Position from Item-0 to OpenUsage before tray creation.
    • Set a stable autosaveName for the status item to replace the corrupted Item-0 identity.
    • Add a macOS 26+ startup health check (two probes) that logs state and shows a one-time alert with recovery steps if the icon isn’t hosted.
  • Dependencies

    • Enable extra objc2-foundation features (NSUserDefaults, NSValue) and objc2-app-kit features (NSStatusItem, NSStatusBarButton, NSWindow, NSAlert, others) needed for defaults cleanup, identity adoption, and the alert.

Written for commit 4005e1c. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes

    • Improved macOS tray icon stability, particularly on macOS 26 (Tahoe).
    • Added automatic health checks that detect when the menu bar tray icon fails to display.
    • Introduced recovery alerts with step-by-step guidance if tray icon issues are detected.
  • Improvements

    • Enhanced macOS system integration for more reliable menu bar functionality.

…y icon

macOS 26 hosts third-party status items through ControlCenter, and its
per-app bookkeeping can corrupt (notably on 26.5), parking the tray icon
off-screen and leaving the app unreachable. Mirrors fixes shipped by
other affected menu bar apps (CodexBar, oMLX):

1. Clear stale `NSStatusItem Visible* = false` defaults before the tray
   is created, and migrate the saved menu bar position to the new
   identity so existing installs keep their slot.
2. Give the status item an explicit autosave name so affected installs
   re-register under a fresh ControlCenter identity.
3. Probe the status item after startup (macOS 26+, two probes 10s
   apart) and show recovery guidance if it never lands in the menu bar.

Mitigates #517

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the rust Pull requests that update rust code label Jun 10, 2026
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR implements macOS 26 (Tahoe) menu bar tray icon recovery mitigations. It expands AppKit dependencies, adds a new macOS-conditional module with pre-build default cleanup, post-build identity adoption, and a health check with recovery guidance, then integrates these steps into tray initialization.

Changes

macOS 26 Tahoe tray icon mitigations

Layer / File(s) Summary
AppKit dependencies and module setup
src-tauri/Cargo.toml, src-tauri/src/lib.rs
Cargo.toml expands objc2-foundation and objc2-app-kit feature flags to support status item and AppKit operations. lib.rs declares the tray_tahoe module conditionally on macOS.
Tahoe tray icon mitigation implementation
src-tauri/src/tray_tahoe.rs
New module implements three entry points: prepare_status_item_defaults() clears stale visibility flags and migrates menu bar position, adopt_stable_identity() sets a stable autosave name to re-register under a fresh ControlCenter identity, and schedule_health_check() probes the status item twice and shows a main-thread recovery alert if broken. Includes StatusItemHealth struct, probe_status_item() helper, and unit tests validating health detection logic.
Tray initialization integration
src-tauri/src/tray.rs
Tray creation now calls prepare_status_item_defaults() before building, binds the builder to a variable, and calls adopt_stable_identity() and schedule_health_check() after building, all behind macOS-only gates.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • davidarny
  • validatedev
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: addressing macOS 26 Tahoe menu bar state corruption that hides the tray icon through specific mitigations.
Docstring Coverage ✅ Passed Docstring coverage is 92.31% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/jovial-hawking-06132c

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 4 files

Re-trigger cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rust Pull requests that update rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Menu bar status item renders off-screen at (-1, 1116) on macOS 26.5 Tahoe (Apple Silicon)

1 participant