fix(tray): vendor and patch tray-icon to fix menu popup on macOS fullscreen Spaces#2745
Closed
TuYv wants to merge 1 commit into
Closed
fix(tray): vendor and patch tray-icon to fix menu popup on macOS fullscreen Spaces#2745TuYv wants to merge 1 commit into
TuYv wants to merge 1 commit into
Conversation
Apply a local fix for tauri-apps/tray-icon#251: on macOS, clicking the tray icon on a secondary display while a full-screen Space is active on that display did nothing — the menu silently failed to appear. Other tray apps (Bartender, Hidden Bar, etc.) are unaffected because they are pure menu-bar apps; cc-switch hits the bug because it is a regular app with both a Dock icon and a tray icon. Root cause is in the tray-icon crate (every release from 0.7.5 through 0.24 inclusive): the macOS implementation triggers the menu via `button.performClick(None)`, which synthesises a click without an NSEvent. AppKit's status-item popup logic resolves the active screen/Space via `[NSApp currentEvent]` and silently no-ops when the synthesised click points to the wrong context. We vendor tray-icon 0.21.3 (the version pulled by tauri 2.8.2) under src-tauri/vendor/tray-icon and patch `on_tray_click` to drive the popup through `NSStatusItem.popUpStatusItemMenu` directly. A `[patch.crates-io]` entry in Cargo.toml redirects the dependency to the local copy. The same fix is being upstreamed in tauri-apps/tray-icon#318. Once that PR is merged, released, and Tauri picks it up, this entire vendor directory and the `[patch.crates-io]` section can be removed.
Contributor
Author
|
Closing for now — reconsidering the vendor-vs-git-fork approach before re-opening. Upstream fix is being tracked at tauri-apps/tray-icon#318. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary / 概述
Fixes the tray menu silently failing to pop up on macOS when the click happens on a secondary display while a full-screen Space is active there (主屏永远正常,副屏桌面 Space 正常,仅副屏全屏 Space 下点击托盘没反应)。
The root cause is in the upstream
tray-iconcrate: it triggers the menu viabutton.performClick(None), a synthesised click without anNSEventcontext. AppKit's status-item popup logic resolves the active screen/Space via[NSApp currentEvent]and silently no-ops when that context resolves to the wrong NSWindow (which is exactly what happens when a full-screen app on a secondary display is the front-most window).Other tray apps (Bartender, Hidden Bar 等纯菜单栏 App) are unaffected because they don't go through this code path — cc-switch hits it because it is a regular Dock-visible app with both a main window and a tray icon, and
tray-iconalways installs its customTrayTargetsubview that overridesmouseDown:.This commit vendors
tray-icon 0.21.3(the version pulled bytauri = "2.8.2") undersrc-tauri/vendor/tray-iconand replacesperformClick(None)withNSStatusItem.popUpStatusItemMenudirectly. A[patch.crates-io]entry insrc-tauri/Cargo.tomlredirects the transitive dependency.The same fix is being upstreamed in tauri-apps/tray-icon#318 (related upstream issue: #251). Once that PR is merged, released, and Tauri picks it up, this entire
vendor/directory and the[patch.crates-io]section can be removed.Reproduction (before this PR)
Repeat on the primary display, or on the secondary display's desktop Space → ✅ menu pops up normally.
Affected versions
Every release from
tray-icon@0.7.5(2023-08-03) through HEAD (0.24.0). Regression was introduced intauri-apps/tray-icon#69(refactor(macos): rewrite impl to fix missing click issues) — the rewrite moved click handling to a custom subview that interceptsmouseDown:, breaking the native button → menu path, and usedperformClick(None)as a workaround.Related Issue / 关联 Issue
Upstream: tauri-apps/tray-icon#251 (OPEN), tauri-apps/tray-icon#318 (proposed fix).
No existing cc-switch issue.
Screenshots / 截图
Not applicable — the bug is "no UI appears", and the fix is "the existing UI now appears". The change is invisible on the primary display and on secondary-display desktop Spaces; it is only visible (= the menu now works) on a full-screen Space hosted by a secondary display.
Checklist / 检查清单
pnpm typecheck— N/A, no TypeScript changespnpm format:check— N/A, no TypeScript / formatted-file changescargo clippy -p cc-switch --no-deps -- -D warningspasses on cc-switch's own code (the 16 warnings emitted from the vendoredtray-iconcrate are upstream-pre-existingunnecessary unsafe blockwarnings — not introduced by this patch)How the patch is structured
src-tauri/vendor/tray-icon/— full source oftray-icon@0.21.3taken from the cargo registry, minus the registry-internal files (.cargo-ok,.cargo-checksum.json,.cargo_vcs_info.json,Cargo.toml.orig,Cargo.lock). Dual-licensed MIT OR Apache-2.0; both license files are preserved.src-tauri/vendor/tray-icon/src/platform_impl/macos/mod.rs— the only file modified inside the vendored crate.on_tray_clickswitches fromperformClick(None)toNSStatusItem.popUpStatusItemMenu(&menu). TheRetained<NSMenu>is cloned before the modal popup so theRefCell::borrow()is released — necessary becausepopUpStatusItemMenu:is modal and a menu item action can re-enterTrayIcon::set_menu, which wouldborrow_mut()the sameRefCelland panic.src-tauri/Cargo.toml— adds[patch.crates-io]entry pointing atvendor/tray-icon.src-tauri/Cargo.lock— auto-updated by cargo to reflect the path source.Removal path
When the upstream PR (tauri-apps/tray-icon#318) is merged, released, and Tauri upgrades to use the fixed
tray-icon, this entire patch can be removed in one commit:rm -rf src-tauri/vendor/tray-icon # Remove the [patch.crates-io] section from src-tauri/Cargo.toml cargo update --package tray-iconNo other source changes will be required — the patch is purely additive.