Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions apps/desktop/electron/main/bootstrap/app-lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,14 @@ export function createApplicationLifecycle({
state.tray = new Tray(icon);
state.tray.setToolTip(APP_NAME);
// macOS single-click opens its attached menu without focusing/reading a conversation.
if (process.platform !== "darwin") state.tray.on("click", restoreMainWindow);
// mouse-enter/move/leave replace the native NSStatusItem with a custom view,
// which hides the menu-bar extra. Keep hover retry on Windows/Linux only.
if (process.platform !== "darwin") {
state.tray.on("click", restoreMainWindow);
state.tray.on("mouse-enter", () => { void traySessions.refresh(); });
state.tray.on("right-click", () => { void traySessions.refresh(); });
}
state.tray.on("double-click", restoreMainWindow);
// User access retries a transient Host read failure without a polling timer.
state.tray.on("mouse-enter", () => { void traySessions.refresh(); });
state.tray.on("right-click", () => { void traySessions.refresh(); });
updateTrayMenu();
void traySessions.refresh();
}
Expand Down
11 changes: 11 additions & 0 deletions apps/desktop/test/close-behavior-tray.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,14 @@ test("explicit quit asks for confirmation except probes and update restarts", ()
/already chose to quit in the close-behavior dialog[\s\S]*?windowState\.quitConfirmed = true/,
);
});

test("macOS tray keeps the native status item instead of mouse-enter tracking", async () => {
const lifecycle = await readMainModule("bootstrap/app-lifecycle.ts");
const create = lifecycle.slice(lifecycle.indexOf("function createTray()"));
const body = create.slice(0, create.indexOf("function resetMenuRendererReady"));
assert.match(
body,
/if \(process\.platform !== "darwin"\) \{[\s\S]*on\("mouse-enter"[\s\S]*on\("right-click"/,
);
assert.equal((body.match(/on\("mouse-enter"/g) || []).length, 1);
});
5 changes: 3 additions & 2 deletions docs/adr/tray-session-shortcuts.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ or closed, so a renderer-only menu snapshot would become stale.
(the existing 200-record inbox), consumes root agent lifecycle/status
events, and refreshes after session/inbox mutations. It coalesces pending
reads, rejects obsolete host generations, and clears shortcuts on a failed
refresh. Tray hover/right-click retries a failed read. It continues to
refresh with no renderer attached; deleting a
refresh. Windows/Linux hover/right-click retries a failed read. macOS does
not subscribe to mouse-enter, which would replace the native status item.
It continues to refresh with no renderer attached; deleting a
session or archiving it or its project removes the shortcut.
4. A session click restores/focuses the main window and sends
`tray/event/sessionActivated { sessionId }` (`null` means View more) only after the renderer finishes
Expand Down
4 changes: 4 additions & 0 deletions docs/spec/04-ux/09-interaction-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ recency only breaks ties between equally relevant matches.
- Start/finish, read, pin, rename, archive, delete, and backend restart update
the menu. The menu remains available when the main window is hidden or
closed, without creating another window until an explicit activation.
- macOS does not listen for tray mouse-enter: that event replaces the native
status item and hides the extra. Windows/Linux still retry a failed Host
read on hover/right-click; macOS retries from the next session or inbox event.


### 1.6 Sidebar project and conversation organization

Expand Down
2 changes: 1 addition & 1 deletion docs/spec/06-delivery/04-e2e-test-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -13031,7 +13031,7 @@ plugin-form fixtures in an isolated temporary directory at runtime.
Close the macOS window while a task runs and let it finish, then activate
its tray row while the new renderer bootstraps a pending plan. Delay a Host
read while a newer preference update, delete, or Host restart arrives.
Retry a transient read failure by hovering/right-clicking the tray.
Retry a transient read failure by hovering/right-clicking the tray on Windows/Linux; macOS retries from the next session or inbox event instead of mouse-enter.
Repeat after clearing all group memberships and changing shipped locales.
Choose Quit then Cancel, then Quit and confirm.
- **Expected**: Running → Unread → Pinned; at most nine rows in total. Each
Expand Down
2 changes: 2 additions & 0 deletions docs/zh-CN/spec/04-ux/09-interaction-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@
- Start/finish, read, pin, rename, archive, delete, and backend restart update
the menu. The menu remains available when the main window is hidden or
closed, without creating another window until an explicit activation.
- macOS 不监听托盘 mouse-enter:该事件会替换原生 status item 并让菜单栏图标消失。
Windows/Linux 仍可在悬停/右键时重试失败的 Host 读取;macOS 改由下一次会话或收件箱事件刷新。

### 1. 6 侧边栏项目和对话组织

Expand Down
2 changes: 1 addition & 1 deletion docs/zh-CN/spec/06-delivery/04-e2e-test-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -7855,7 +7855,7 @@ runner 会在运行时的隔离临时目录中生成六个插件形态 fixture
Close the macOS window while a task runs and let it finish, then activate
its tray row while the new renderer bootstraps a pending plan. Delay a Host
read while a newer preference update, delete, or Host restart arrives.
Retry a transient read failure by hovering/right-clicking the tray.
Retry a transient read failure by hovering/right-clicking the tray on Windows/Linux; macOS retries from the next session or inbox event instead of mouse-enter.
Repeat after clearing all group memberships and changing shipped locales.
Choose Quit then Cancel, then Quit and confirm.
- **Expected**: Running → Unread → Pinned; at most nine rows in total. Each
Expand Down
Loading