Skip to content

fix(windows): let Quit actually exit and enforce a single tray instance - #1226

Open
iamtoruk wants to merge 1 commit into
mainfrom
fix/windows-tray-quit-single-instance
Open

fix(windows): let Quit actually exit and enforce a single tray instance#1226
iamtoruk wants to merge 1 commit into
mainfrom
fix/windows-tray-quit-single-instance

Conversation

@iamtoruk

@iamtoruk iamtoruk commented Sep 1, 2026

Copy link
Copy Markdown
Member

Bugs, as observed on a Windows 11 VM

1. Quit does nothing. Right-click the tray icon > Quit CodeBurn and the app just keeps running. The Tauri run loop's RunEvent::ExitRequested handler unconditionally called api.prevent_exit(), which also swallowed the explicit app.exit(0) fired by the tray "quit" menu item and commands::quit_app. In Tauri 2, ExitRequested carries code: Option<i32>: None when the last window closes on its own, Some(_) for an explicit app.exit(..). Fixed by only preventing exit when code.is_none(), so the popover window closing still keeps the app resident in the tray, but Quit actually quits.

2. Launching twice gives four tray icons. Each running instance registers two tray icons by design (the flame logo plus a spend badge icon next to it). Launching the app a second time (e.g. double-clicking the shortcut again) starts a second process instead of reusing the first, so the notification area ends up with two flame icons and two badge icons for what looks like one app. Fixed by adding tauri-plugin-single-instance, registered first in the builder chain per its docs; a second launch now just calls the existing show_popover to bring the running instance's popover forward instead of spawning a duplicate process.

Changes

  • windows/src-tauri/src/lib.rs: guard ExitRequested on code.is_none(); register tauri_plugin_single_instance::init as the first plugin, focusing the popover on relaunch.
  • windows/src-tauri/Cargo.toml: add tauri-plugin-single-instance = "2" (resolves to 2.4.4 against the pinned tauri 2.10.3).
  • windows/src-tauri/Cargo.lock: minimal lockfile addition for the new dependency (17 lines).

Test plan

  • cargo check passes on macOS host (compiles the non-Linux tray code path)
  • CI nsis/appx Windows build jobs
  • Manual: Windows 11 VM, right-click tray > Quit exits the process
  • Manual: Windows 11 VM, launch app twice, only one flame + one badge icon remain, second launch focuses the popover
Quit CodeBurn in the tray menu called app.exit(0), but ExitRequested
was unconditionally prevented in the run loop, so the process never
actually exited. Only prevent exit when code is None (the popover
window closing on its own), letting an explicit app.exit(..) through.

Launching the menubar app twice left two processes running, each
registering its own flame + spend-badge tray icon pair, so the
notification area showed four icons for one app. Add
tauri-plugin-single-instance, registered first in the builder chain,
so a second launch just refocuses the running instance's popover.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant