From d6ae5d0c9165cfe0ed25db91d49670637f2b7ada Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 13 Nov 2026 21:32:56 +0000 Subject: [PATCH] fix(tray): disable macOS floating tooltip overlay Multi-line NSStatusItem tooltips from tray-icon were painting a pointer- following overlay with dendritic/fleet status. Keep that status in the menubar menu only; clear tooltips on Darwin. Linux tips unchanged. Co-authored-by: Alex Spaulding --- docs/dendritic-tray.md | 4 ++++ modules/apps/pass-store-tray/src/main.rs | 21 ++++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/docs/dendritic-tray.md b/docs/dendritic-tray.md index b1ed7b4c..3e077b0a 100644 --- a/docs/dendritic-tray.md +++ b/docs/dendritic-tray.md @@ -4,6 +4,10 @@ Native menubar applet (macOS NSStatusItem / Linux StatusNotifier). Same binary and launchd/systemd labels as before (`pass-store-tray`) — pass sync status is unchanged; dendritic fleet/theme/llm/wg/android/flake status is layered on top. +**macOS tooltips are disabled.** Status lives only in the menubar menu. A +multi-line `NSStatusItem` tooltip was painting a floating overlay that followed +the pointer; Linux StatusNotifier tips remain enabled. + ## Status files | File | Writer | diff --git a/modules/apps/pass-store-tray/src/main.rs b/modules/apps/pass-store-tray/src/main.rs index 70f122de..6881fcc3 100644 --- a/modules/apps/pass-store-tray/src/main.rs +++ b/modules/apps/pass-store-tray/src/main.rs @@ -12,9 +12,10 @@ use std::time::Duration; use tray_icon::menu::{Menu, MenuEvent, MenuItem, PredefinedMenuItem, Submenu}; use tray_icon::{Icon, TrayIcon, TrayIconBuilder}; use ui_contract::{ - Action, DendriticFacts, TOOLTIP_IDLE, build_dendritic_rows, build_status_lines, - merge_status_lines, + Action, DendriticFacts, build_dendritic_rows, build_status_lines, merge_status_lines, }; +#[cfg(not(target_os = "macos"))] +use ui_contract::TOOLTIP_IDLE; #[cfg(target_os = "macos")] use winit::application::ApplicationHandler; @@ -624,13 +625,15 @@ impl NativeTray { fn build(env: Env, quit: Arc) -> Self { let (menu, status_rows, actions) = Self::compose_menu(&[]); - let tray = TrayIconBuilder::new() + // macOS: never set a tray tooltip. tray-icon's multi-line tip paints a + // floating overlay that follows the pointer; status belongs in the menu. + let builder = TrayIconBuilder::new() .with_menu(Box::new(menu)) - .with_tooltip(TOOLTIP_IDLE) .with_icon(make_icon(IconKind::Idle)) - .with_icon_as_template(cfg!(target_os = "macos")) - .build() - .expect("create tray icon"); + .with_icon_as_template(cfg!(target_os = "macos")); + #[cfg(not(target_os = "macos"))] + let builder = builder.with_tooltip(TOOLTIP_IDLE); + let tray = builder.build().expect("create tray icon"); let mut app = Self { env, @@ -663,6 +666,10 @@ impl NativeTray { item.set_text(text.clone()); } } + // macOS: keep tip cleared every refresh (see build() comment). + #[cfg(target_os = "macos")] + let _ = self.tray.set_tooltip(None); + #[cfg(not(target_os = "macos"))] let _ = self.tray.set_tooltip(Some(lines.tooltip.clone())); }