diff --git a/desktop-client/src-tauri/src/lib.rs b/desktop-client/src-tauri/src/lib.rs index 21859e6..4fe27b2 100644 --- a/desktop-client/src-tauri/src/lib.rs +++ b/desktop-client/src-tauri/src/lib.rs @@ -1,6 +1,6 @@ mod tunnel_manager; -use std::{fs, path::PathBuf, sync::Mutex}; +use std::{fs, net::TcpListener, path::PathBuf, sync::Mutex}; use base64::{engine::general_purpose::STANDARD, Engine as _}; use rand_core::OsRng; @@ -15,9 +15,11 @@ use x25519_dalek::{PublicKey, StaticSecret}; const PROFILE_NAME: &str = "NexaVPN"; const MAIN_WINDOW_LABEL: &str = "main"; +const SINGLE_INSTANCE_ADDR: &str = "127.0.0.1:53190"; struct AppState { session: Mutex>, + single_instance_lock: TcpListener, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -362,12 +364,6 @@ fn ensure_app_dir(app: &AppHandle) -> Result { Ok(dir) } -fn restore_window(window: &Window) { - let _ = window.show(); - let _ = window.unminimize(); - let _ = window.set_focus(); -} - fn restore_webview_window(window: &WebviewWindow) { let _ = window.show(); let _ = window.unminimize(); @@ -382,6 +378,9 @@ fn hide_main_window(window: &Window) { pub fn run() { tauri::Builder::default() .setup(|app| { + let single_instance_lock = TcpListener::bind(SINGLE_INSTANCE_ADDR) + .map_err(|_| format!("{} is already running.", app.package_info().name))?; + let open_item = MenuItemBuilder::with_id("open", "Open NexaVPN").build(app)?; let quit_item = MenuItemBuilder::with_id("quit", "Quit NexaVPN").build(app)?; let menu = MenuBuilder::new(app).items(&[&open_item, &quit_item]).build()?; @@ -418,24 +417,20 @@ pub fn run() { }) .build(app)?; + app.manage(AppState { + session: Mutex::new(None), + single_instance_lock, + }); + Ok(()) }) - .manage(AppState { - session: Mutex::new(None), - }) .on_window_event(|window, event| match event { - WindowEvent::CloseRequested { api, .. } => { - api.prevent_close(); - hide_main_window(window); - } + WindowEvent::CloseRequested { .. } => {} WindowEvent::Resized(_) => { if window.is_minimized().unwrap_or(false) { hide_main_window(window); } } - WindowEvent::Focused(true) => { - restore_window(window); - } _ => {} }) .invoke_handler(tauri::generate_handler![load_state, clear_session, enroll_device, sync_profile, connect_tunnel, disconnect_tunnel, tunnel_status]) diff --git a/desktop-client/src-tauri/tauri.conf.json b/desktop-client/src-tauri/tauri.conf.json index 137197d..2a4d652 100644 --- a/desktop-client/src-tauri/tauri.conf.json +++ b/desktop-client/src-tauri/tauri.conf.json @@ -15,7 +15,8 @@ "title": "NexaVPN", "width": 1120, "height": 760, - "resizable": true + "resizable": false, + "maximizable": false } ], "security": {