Skip to content

Commit 7b4ec0e

Browse files
committed
fix(desktop): make tray quit reliable via menu event handler
1 parent 4166e9a commit 7b4ec0e

3 files changed

Lines changed: 48 additions & 3 deletions

File tree

linux/src/tray.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::sync::atomic::{AtomicBool, Ordering};
22
use std::sync::{Arc, Mutex};
33
use std::time::Duration;
4+
use std::sync::mpsc as std_mpsc;
45

56
use eframe::egui;
67
use tokio::sync::{mpsc, watch};
@@ -139,6 +140,7 @@ pub struct TrayApp {
139140
ws_cmd_tx: mpsc::Sender<WsCommand>,
140141
status_rx: watch::Receiver<ConnectionStatus>,
141142
auth_event_rx: Option<mpsc::Receiver<LocalServerEvent>>,
143+
menu_event_rx: std_mpsc::Receiver<MenuEvent>,
142144

143145
// State
144146
local_port: u16,
@@ -203,6 +205,7 @@ impl TrayApp {
203205
let unregister_device = MenuItem::new("Unregister Device", false, None);
204206
let test_window = MenuItem::new("Test Window", true, None);
205207
let quit = MenuItem::new("Quit", true, None);
208+
let quit_id = quit.id().clone();
206209

207210
let menu = Menu::new();
208211
let _ = menu.append(&about);
@@ -249,6 +252,17 @@ impl TrayApp {
249252
quit,
250253
};
251254

255+
let (menu_event_tx, menu_event_rx) = std_mpsc::channel::<MenuEvent>();
256+
let ws_cmd_tx_for_handler = ws_cmd_tx.clone();
257+
MenuEvent::set_event_handler(Some(move |event: MenuEvent| {
258+
if event.id == quit_id {
259+
info!("menu: quit clicked");
260+
let _ = ws_cmd_tx_for_handler.try_send(WsCommand::Shutdown);
261+
std::process::exit(0);
262+
}
263+
let _ = menu_event_tx.send(event);
264+
}));
265+
252266
// Auto-open login window if not signed in
253267
let cloud_signed_in = !config.token.is_empty();
254268
let oss_signed_in = config.opensource_server_enabled
@@ -266,6 +280,7 @@ impl TrayApp {
266280
ws_cmd_tx,
267281
status_rx,
268282
auth_event_rx: Some(auth_event_rx),
283+
menu_event_rx,
269284
local_port,
270285
last_status: ConnectionStatus::Disconnected,
271286
is_registered: Arc::new(AtomicBool::new(false)),
@@ -299,7 +314,7 @@ impl TrayApp {
299314
}
300315

301316
fn handle_menu_events(&mut self) {
302-
while let Ok(event) = MenuEvent::receiver().try_recv() {
317+
while let Ok(event) = self.menu_event_rx.try_recv() {
303318
let items = match &self.menu_items {
304319
Some(items) => items,
305320
None => continue,

mac/src/tray.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::sync::atomic::{AtomicBool, Ordering};
22
use std::sync::{Arc, Mutex};
33
use std::time::Duration;
4+
use std::sync::mpsc as std_mpsc;
45

56
use eframe::egui;
67
use tokio::sync::{mpsc, watch};
@@ -139,6 +140,7 @@ pub struct TrayApp {
139140
ws_cmd_tx: mpsc::Sender<WsCommand>,
140141
status_rx: watch::Receiver<ConnectionStatus>,
141142
auth_event_rx: Option<mpsc::Receiver<LocalServerEvent>>,
143+
menu_event_rx: std_mpsc::Receiver<MenuEvent>,
142144

143145
// State
144146
local_port: u16,
@@ -203,6 +205,7 @@ impl TrayApp {
203205
let unregister_device = MenuItem::new("Unregister Device", false, None);
204206
let test_window = MenuItem::new("Test Window", true, None);
205207
let quit = MenuItem::new("Quit", true, None);
208+
let quit_id = quit.id().clone();
206209

207210
let menu = Menu::new();
208211
let _ = menu.append(&about);
@@ -249,6 +252,17 @@ impl TrayApp {
249252
quit,
250253
};
251254

255+
let (menu_event_tx, menu_event_rx) = std_mpsc::channel::<MenuEvent>();
256+
let ws_cmd_tx_for_handler = ws_cmd_tx.clone();
257+
MenuEvent::set_event_handler(Some(move |event: MenuEvent| {
258+
if event.id == quit_id {
259+
info!("menu: quit clicked");
260+
let _ = ws_cmd_tx_for_handler.try_send(WsCommand::Shutdown);
261+
std::process::exit(0);
262+
}
263+
let _ = menu_event_tx.send(event);
264+
}));
265+
252266
// Auto-open login window if not signed in
253267
let cloud_signed_in = !config.token.is_empty();
254268
let oss_signed_in = config.opensource_server_enabled
@@ -266,6 +280,7 @@ impl TrayApp {
266280
ws_cmd_tx,
267281
status_rx,
268282
auth_event_rx: Some(auth_event_rx),
283+
menu_event_rx,
269284
local_port,
270285
last_status: ConnectionStatus::Disconnected,
271286
is_registered: Arc::new(AtomicBool::new(false)),
@@ -299,7 +314,7 @@ impl TrayApp {
299314
}
300315

301316
fn handle_menu_events(&mut self) {
302-
while let Ok(event) = MenuEvent::receiver().try_recv() {
317+
while let Ok(event) = self.menu_event_rx.try_recv() {
303318
let items = match &self.menu_items {
304319
Some(items) => items,
305320
None => continue,

windows/src/tray.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::sync::atomic::{AtomicBool, Ordering};
22
use std::sync::{Arc, Mutex};
33
use std::time::Duration;
4+
use std::sync::mpsc as std_mpsc;
45

56
use eframe::egui;
67
use tokio::sync::{mpsc, watch};
@@ -139,6 +140,7 @@ pub struct TrayApp {
139140
ws_cmd_tx: mpsc::Sender<WsCommand>,
140141
status_rx: watch::Receiver<ConnectionStatus>,
141142
auth_event_rx: Option<mpsc::Receiver<LocalServerEvent>>,
143+
menu_event_rx: std_mpsc::Receiver<MenuEvent>,
142144

143145
// State
144146
local_port: u16,
@@ -203,6 +205,7 @@ impl TrayApp {
203205
let unregister_device = MenuItem::new("Unregister Device", false, None);
204206
let test_window = MenuItem::new("Test Window", true, None);
205207
let quit = MenuItem::new("Quit", true, None);
208+
let quit_id = quit.id().clone();
206209

207210
let menu = Menu::new();
208211
let _ = menu.append(&about);
@@ -249,6 +252,17 @@ impl TrayApp {
249252
quit,
250253
};
251254

255+
let (menu_event_tx, menu_event_rx) = std_mpsc::channel::<MenuEvent>();
256+
let ws_cmd_tx_for_handler = ws_cmd_tx.clone();
257+
MenuEvent::set_event_handler(Some(move |event: MenuEvent| {
258+
if event.id == quit_id {
259+
info!("menu: quit clicked");
260+
let _ = ws_cmd_tx_for_handler.try_send(WsCommand::Shutdown);
261+
std::process::exit(0);
262+
}
263+
let _ = menu_event_tx.send(event);
264+
}));
265+
252266
// Auto-open login window if not signed in
253267
let cloud_signed_in = !config.token.is_empty();
254268
let oss_signed_in = config.opensource_server_enabled
@@ -266,6 +280,7 @@ impl TrayApp {
266280
ws_cmd_tx,
267281
status_rx,
268282
auth_event_rx: Some(auth_event_rx),
283+
menu_event_rx,
269284
local_port,
270285
last_status: ConnectionStatus::Disconnected,
271286
is_registered: Arc::new(AtomicBool::new(false)),
@@ -299,7 +314,7 @@ impl TrayApp {
299314
}
300315

301316
fn handle_menu_events(&mut self) {
302-
while let Ok(event) = MenuEvent::receiver().try_recv() {
317+
while let Ok(event) = self.menu_event_rx.try_recv() {
303318
let items = match &self.menu_items {
304319
Some(items) => items,
305320
None => continue,

0 commit comments

Comments
 (0)