bug-001: fix tray menu, add autostart and crash recovery launcher
All checks were successful
Build Check / build (push) Successful in 4m2s
All checks were successful
Build Check / build (push) Successful in 4m2s
This commit is contained in:
37
src/app.rs
37
src/app.rs
@@ -74,12 +74,16 @@ pub struct TickrApp {
|
||||
update_in_progress: bool,
|
||||
update_result_rx: mpsc::Receiver<UpdateCheckResult>,
|
||||
|
||||
// Tray
|
||||
// Tray — use our own channels fed by set_event_handler so events are
|
||||
// delivered even when the window is hidden (the global receiver() only
|
||||
// works reliably while the winit loop is actively processing messages).
|
||||
#[allow(dead_code)]
|
||||
tray_icon: Option<tray_icon::TrayIcon>,
|
||||
tray_open_id: Option<tray_icon::menu::MenuId>,
|
||||
tray_check_id: Option<tray_icon::menu::MenuId>,
|
||||
tray_quit_id: Option<tray_icon::menu::MenuId>,
|
||||
tray_ev_rx: mpsc::Receiver<tray_icon::TrayIconEvent>,
|
||||
menu_ev_rx: mpsc::Receiver<tray_icon::menu::MenuEvent>,
|
||||
window_visible: bool,
|
||||
hide_to_tray: bool,
|
||||
should_quit: bool,
|
||||
@@ -108,6 +112,24 @@ impl TickrApp {
|
||||
let (tray_icon, tray_open_id, tray_check_id, tray_quit_id) =
|
||||
setup_tray(icon_rgba.clone(), icon_size, watchlist.tickers.len());
|
||||
|
||||
// Route tray events through our own sync channels + wake egui immediately.
|
||||
// SyncSender is Send + Sync, satisfying the 'static closure requirement.
|
||||
// (The global receiver() channel is NOT used — set_event_handler replaces it.)
|
||||
let (tray_ev_tx, tray_ev_rx) = mpsc::sync_channel::<tray_icon::TrayIconEvent>(64);
|
||||
let (menu_ev_tx, menu_ev_rx) = mpsc::sync_channel::<tray_icon::menu::MenuEvent>(64);
|
||||
|
||||
let ctx_tray = cc.egui_ctx.clone();
|
||||
tray_icon::TrayIconEvent::set_event_handler(Some(move |e| {
|
||||
let _ = tray_ev_tx.send(e);
|
||||
ctx_tray.request_repaint();
|
||||
}));
|
||||
|
||||
let ctx_menu = cc.egui_ctx.clone();
|
||||
tray_icon::menu::MenuEvent::set_event_handler(Some(move |e| {
|
||||
let _ = menu_ev_tx.send(e);
|
||||
ctx_menu.request_repaint();
|
||||
}));
|
||||
|
||||
// Spawn background check task
|
||||
let (bg_cmd_tx, bg_cmd_rx) = tokio::sync::mpsc::unbounded_channel::<BgCmd>();
|
||||
let (update_result_tx, update_result_rx) = mpsc::channel::<UpdateCheckResult>();
|
||||
@@ -138,6 +160,8 @@ impl TickrApp {
|
||||
tray_open_id,
|
||||
tray_check_id,
|
||||
tray_quit_id,
|
||||
tray_ev_rx,
|
||||
menu_ev_rx,
|
||||
window_visible: start_visible,
|
||||
hide_to_tray: false,
|
||||
should_quit: false,
|
||||
@@ -870,17 +894,16 @@ impl TickrApp {
|
||||
}
|
||||
|
||||
fn poll_tray_events(&mut self, ctx: &Context, _frame: &mut eframe::Frame) {
|
||||
use tray_icon::TrayIconEvent;
|
||||
|
||||
while let Ok(event) = TrayIconEvent::receiver().try_recv() {
|
||||
// Drain icon-level events (single/double click → show window)
|
||||
while let Ok(event) = self.tray_ev_rx.try_recv() {
|
||||
match event {
|
||||
TrayIconEvent::Click { .. } => self.show_window(ctx),
|
||||
tray_icon::TrayIconEvent::Click { .. } => self.show_window(ctx),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
use tray_icon::menu::MenuEvent;
|
||||
while let Ok(event) = MenuEvent::receiver().try_recv() {
|
||||
// Drain context-menu events
|
||||
while let Ok(event) = self.menu_ev_rx.try_recv() {
|
||||
if self.tray_open_id.as_ref() == Some(&event.id) {
|
||||
self.show_window(ctx);
|
||||
} else if self.tray_check_id.as_ref() == Some(&event.id) {
|
||||
|
||||
Reference in New Issue
Block a user