diff --git a/clients/desktop/src-tauri/src/lib.rs b/clients/desktop/src-tauri/src/lib.rs index 6361dd9..bf9d030 100644 --- a/clients/desktop/src-tauri/src/lib.rs +++ b/clients/desktop/src-tauri/src/lib.rs @@ -526,6 +526,8 @@ fn start_background_sync( // --- App Setup --- /// Check if another instance is running. If yes, pass the .cloud file to it and exit. +/// Single instance per user. On terminal servers each user gets their own +/// instance because the lock file is in %APPDATA% (user-specific). fn handle_single_instance() { let config_dir = dirs::config_dir() .unwrap_or_else(|| PathBuf::from(".")) @@ -535,22 +537,48 @@ fn handle_single_instance() { let lock_file = config_dir.join("instance.lock"); let args: Vec = std::env::args().collect(); - // If we have a .cloud file argument and another instance is running - if args.len() > 1 && args[1].ends_with(".cloud") { - if lock_file.exists() { - // Write the .cloud path to a request file for the running instance - let request_file = config_dir.join("open_request.txt"); - std::fs::write(&request_file, &args[1]).ok(); - eprintln!("[SingleInstance] Passing {} to running instance", args[1]); - std::process::exit(0); - } + // Check if another instance of THIS USER is running + let other_running = if lock_file.exists() { + if let Ok(pid_str) = std::fs::read_to_string(&lock_file) { + let pid = pid_str.trim().parse::().unwrap_or(0); + if pid > 0 && pid != std::process::id() { + // Check if that process is still alive + #[cfg(target_os = "windows")] + { + std::process::Command::new("tasklist") + .args(["/FI", &format!("PID eq {}", pid), "/NH"]) + .output() + .map(|o| String::from_utf8_lossy(&o.stdout).contains(&pid.to_string())) + .unwrap_or(false) + } + #[cfg(not(target_os = "windows"))] + { + std::path::Path::new(&format!("/proc/{}", pid)).exists() + } + } else { false } + } else { false } + } else { false }; + + // If .cloud file argument and another instance runs -> delegate and exit + if args.len() > 1 && args[1].ends_with(".cloud") && other_running { + let request_file = config_dir.join("open_request.txt"); + std::fs::write(&request_file, &args[1]).ok(); + eprintln!("[SingleInstance] Delegated {} to running instance (PID in lock)", args[1]); + std::process::exit(0); } - // Write our lock file - std::fs::write(&lock_file, std::process::id().to_string()).ok(); + // If no .cloud argument but another instance runs -> just bring it to front and exit + if other_running && args.len() <= 1 { + eprintln!("[SingleInstance] Already running, exiting"); + std::process::exit(0); + } + // We are the main instance - write our PID + std::fs::write(&lock_file, std::process::id().to_string()).ok(); } + + #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { handle_single_instance();