diff --git a/rust/windows-client/src-tauri/src/client/gui.rs b/rust/windows-client/src-tauri/src/client/gui.rs index a52a62dc4..5519a942f 100644 --- a/rust/windows-client/src-tauri/src/client/gui.rs +++ b/rust/windows-client/src-tauri/src/client/gui.rs @@ -222,58 +222,20 @@ async fn accept_deep_links(mut server: deep_link::Server, ctlr_tx: CtlrTx) -> Re } fn handle_system_tray_event(app: &tauri::AppHandle, event: TrayMenuEvent) -> Result<()> { - let ctlr_tx = &app - .try_state::() - .ok_or_else(|| anyhow!("can't get Managed struct from Tauri"))? - .ctlr_tx; - - // TODO: Just handle these in Controller directly: - match event { - TrayMenuEvent::About => { - let win = app - .get_window("about") - .ok_or_else(|| anyhow!("getting handle to About window"))?; - - if win.is_visible()? { - win.hide()?; - } else { - win.show()?; - } - } - TrayMenuEvent::CancelSignIn => ctlr_tx.blocking_send(ControllerRequest::CancelSignIn)?, - TrayMenuEvent::Resource { id } => { - ctlr_tx.blocking_send(ControllerRequest::CopyResource(id))? - } - TrayMenuEvent::Settings => { - let win = app - .get_window("settings") - .ok_or_else(|| anyhow!("getting handle to Settings window"))?; - - if win.is_visible()? { - // If we close the window here, we can't re-open it, we'd have to fully re-create it. Not needed for MVP - We agreed 100 MB is fine for the GUI client. - win.hide()?; - } else { - win.show()?; - } - } - TrayMenuEvent::SignIn => ctlr_tx.blocking_send(ControllerRequest::SignIn)?, - TrayMenuEvent::SignOut => ctlr_tx.blocking_send(ControllerRequest::SignOut)?, - TrayMenuEvent::Quit => ctlr_tx.blocking_send(ControllerRequest::Quit)?, - } + app.try_state::() + .context("can't get Managed struct from Tauri")? + .ctlr_tx + .blocking_send(ControllerRequest::SystemTrayMenu(event))?; Ok(()) } pub(crate) enum ControllerRequest { - CancelSignIn, - CopyResource(String), Disconnected, DisconnectedTokenExpired, ExportLogs { path: PathBuf, stem: PathBuf }, GetAdvancedSettings(oneshot::Sender), - Quit, SchemeRequest(url::Url), - SignIn, - SignOut, + SystemTrayMenu(TrayMenuEvent), TunnelReady, } @@ -509,6 +471,26 @@ impl Controller { self.refresh_system_tray_menu()?; Ok(()) } + + fn toggle_window(&self, window: system_tray_menu::Window) -> Result<()> { + let id = match window { + system_tray_menu::Window::About => "about", + system_tray_menu::Window::Settings => "settings", + }; + + let win = self + .app + .get_window(id) + .ok_or_else(|| anyhow!("getting handle to `{id}` window"))?; + + if win.is_visible()? { + // If we close the window here, we can't re-open it, we'd have to fully re-create it. Not needed for MVP - We agreed 100 MB is fine for the GUI client. + win.hide()?; + } else { + win.show()?; + } + Ok(()) + } } // TODO: After PR #2960 lands, move some of this into `impl Controller` @@ -553,9 +535,6 @@ async fn run_controller( break; }; match req { - Req::CopyResource(id) => if let Err(e) = controller.copy_resource(&id) { - tracing::error!("couldn't copy resource to clipboard: {e:#?}"); - } Req::Disconnected => { tracing::debug!("connlib disconnected, tearing down Session"); controller.tunnel_ready = false; @@ -566,10 +545,6 @@ async fn run_controller( } controller.refresh_system_tray_menu()?; } - Req::CancelSignIn | Req::SignOut => { - tracing::info!("User signed out or canceled sign-in"); - controller.sign_out()?; - } Req::DisconnectedTokenExpired => { tracing::info!("Token expired"); controller.sign_out()?; @@ -579,11 +554,18 @@ async fn run_controller( Req::GetAdvancedSettings(tx) => { tx.send(controller.advanced_settings.clone()).ok(); } - Req::Quit => break, Req::SchemeRequest(url) => if let Err(e) = controller.handle_deep_link(&url).await { tracing::error!("couldn't handle deep link: {e:#?}"); } - Req::SignIn => { + Req::SystemTrayMenu(TrayMenuEvent::ToggleWindow(window)) => controller.toggle_window(window)?, + Req::SystemTrayMenu(TrayMenuEvent::CancelSignIn | TrayMenuEvent::SignOut) => { + tracing::info!("User signed out or canceled sign-in"); + controller.sign_out()?; + } + Req::SystemTrayMenu(TrayMenuEvent::Resource { id }) => if let Err(e) = controller.copy_resource(&id) { + tracing::error!("couldn't copy resource to clipboard: {e:#?}"); + } + Req::SystemTrayMenu(TrayMenuEvent::SignIn) => { if let Some(req) = controller.auth.start_sign_in()? { let url = req.to_url(&controller.advanced_settings.auth_base_url); controller.refresh_system_tray_menu()?; @@ -594,6 +576,7 @@ async fn run_controller( )?; } } + Req::SystemTrayMenu(TrayMenuEvent::Quit) => break, Req::TunnelReady => { controller.tunnel_ready = true; controller.refresh_system_tray_menu()?; diff --git a/rust/windows-client/src-tauri/src/client/gui/system_tray_menu.rs b/rust/windows-client/src-tauri/src/client/gui/system_tray_menu.rs index ff503776e..3e8345bdd 100644 --- a/rust/windows-client/src-tauri/src/client/gui/system_tray_menu.rs +++ b/rust/windows-client/src-tauri/src/client/gui/system_tray_menu.rs @@ -4,15 +4,20 @@ use tauri::{CustomMenuItem, SystemTrayMenu, SystemTrayMenuItem, SystemTraySubmen #[derive(Debug, PartialEq)] pub(crate) enum Event { - About, CancelSignIn, Resource { id: String }, - Settings, SignIn, SignOut, + ToggleWindow(Window), Quit, } +#[derive(Debug, PartialEq)] +pub(crate) enum Window { + About, + Settings, +} + #[derive(thiserror::Error, Debug)] pub(crate) enum Error { #[error("the system tray menu item ID is not valid")] @@ -24,9 +29,9 @@ impl FromStr for Event { fn from_str(s: &str) -> Result { Ok(match s { - "/about" => Self::About, + "/about" => Self::ToggleWindow(Window::About), "/cancel_sign_in" => Self::CancelSignIn, - "/settings" => Self::Settings, + "/settings" => Self::ToggleWindow(Window::Settings), "/sign_in" => Self::SignIn, "/sign_out" => Self::SignOut, "/quit" => Self::Quit, @@ -93,12 +98,15 @@ pub(crate) fn signed_out() -> SystemTrayMenu { #[cfg(test)] mod tests { - use super::Event; + use super::{Event, Window}; use std::str::FromStr; #[test] fn systray_parse() { - assert_eq!(Event::from_str("/about").unwrap(), Event::About); + assert_eq!( + Event::from_str("/about").unwrap(), + Event::ToggleWindow(Window::About) + ); assert_eq!( Event::from_str("/resource/1234").unwrap(), Event::Resource {