@@ -253,12 +253,19 @@ impl HyprKvmGui { |
| 253 | 253 | let _ = reader.read_line(&mut response); |
| 254 | 254 | } |
| 255 | 255 | // Give daemon time to shutdown |
| 256 | | - std::thread::sleep(std::time::Duration::from_millis(500)); |
| 256 | + std::thread::sleep(std::time::Duration::from_millis(1000)); |
| 257 | 257 | } |
| 258 | 258 | |
| 259 | 259 | // Now spawn a new daemon process |
| 260 | + // Try current_exe first, fall back to PATH lookup |
| 260 | 261 | let exe = std::env::current_exe().unwrap_or_else(|_| "hyprkvm".into()); |
| 261 | | - match Command::new(&exe) |
| 262 | + tracing::info!("Restarting daemon with exe: {:?}", exe); |
| 263 | + |
| 264 | + // Use setsid to create a new session so daemon survives GUI exit |
| 265 | + // This is the Unix way to properly daemonize |
| 266 | + match Command::new("setsid") |
| 267 | + .arg("--fork") |
| 268 | + .arg(&exe) |
| 262 | 269 | .arg("daemon") |
| 263 | 270 | .stdin(std::process::Stdio::null()) |
| 264 | 271 | .stdout(std::process::Stdio::null()) |
@@ -267,14 +274,44 @@ impl HyprKvmGui { |
| 267 | 274 | { |
| 268 | 275 | Ok(_) => { |
| 269 | 276 | // Wait a moment for daemon to start |
| 270 | | - std::thread::sleep(std::time::Duration::from_millis(500)); |
| 271 | | - self.state.error = None; |
| 272 | | - self.state.needs_restart = false; |
| 273 | | - self.state.success = Some("Daemon restarted".to_string()); |
| 277 | + std::thread::sleep(std::time::Duration::from_millis(1000)); |
| 278 | + |
| 279 | + // Verify daemon actually started by checking socket |
| 280 | + if UnixStream::connect(&socket_path).is_ok() { |
| 281 | + self.state.error = None; |
| 282 | + self.state.needs_restart = false; |
| 283 | + self.state.success = Some("Daemon restarted".to_string()); |
| 284 | + } else { |
| 285 | + self.state.error = Some("Daemon spawn succeeded but socket not available".to_string()); |
| 286 | + self.state.needs_restart = true; |
| 287 | + } |
| 274 | 288 | } |
| 275 | 289 | Err(e) => { |
| 276 | | - self.state.error = Some(format!("Failed to start daemon: {}", e)); |
| 277 | | - self.state.needs_restart = false; |
| 290 | + // setsid not available, try direct spawn |
| 291 | + tracing::warn!("setsid failed: {}, trying direct spawn", e); |
| 292 | + match Command::new(&exe) |
| 293 | + .arg("daemon") |
| 294 | + .stdin(std::process::Stdio::null()) |
| 295 | + .stdout(std::process::Stdio::null()) |
| 296 | + .stderr(std::process::Stdio::null()) |
| 297 | + .spawn() |
| 298 | + { |
| 299 | + Ok(_) => { |
| 300 | + std::thread::sleep(std::time::Duration::from_millis(1000)); |
| 301 | + if UnixStream::connect(&socket_path).is_ok() { |
| 302 | + self.state.error = None; |
| 303 | + self.state.needs_restart = false; |
| 304 | + self.state.success = Some("Daemon restarted".to_string()); |
| 305 | + } else { |
| 306 | + self.state.error = Some("Daemon spawn succeeded but socket not available".to_string()); |
| 307 | + self.state.needs_restart = true; |
| 308 | + } |
| 309 | + } |
| 310 | + Err(e2) => { |
| 311 | + self.state.error = Some(format!("Failed to start daemon: {}", e2)); |
| 312 | + self.state.needs_restart = false; |
| 313 | + } |
| 314 | + } |
| 278 | 315 | } |
| 279 | 316 | } |
| 280 | 317 | } |