gardesk/garbg / f0fd979

Browse files

daemon: Add X11 health check and auto-reconnect

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
f0fd9799631e542f83469b4e35f1ed0265b3c2e0
Parents
10354f7
Tree
4940d23

1 changed file

StatusFile+-
M garbg/src/daemon/state.rs 60 1
garbg/src/daemon/state.rsmodified
@@ -305,6 +305,14 @@ impl Daemon {
305305
         let mut last_gar_reconnect = std::time::Instant::now();
306306
         let gar_max_backoff = Duration::from_secs(60);
307307
 
308
+        // X11 health check and reconnection state
309
+        let x11_health_interval = Duration::from_secs(5);
310
+        let mut last_x11_health_check = std::time::Instant::now();
311
+        let mut x11_reconnect_backoff = Duration::from_secs(1);
312
+        let mut last_x11_reconnect = std::time::Instant::now();
313
+        let x11_max_backoff = Duration::from_secs(30);
314
+        let mut x11_needs_reconnect = false;
315
+
308316
         // Track next slideshow time
309317
         let mut next_slideshow: Option<tokio::time::Instant> = self.state.slideshow_interval
310318
             .map(|d| tokio::time::Instant::now() + d);
@@ -328,7 +336,31 @@ impl Daemon {
328336
         // Main event loop
329337
         // Note: Session lifecycle is handled by systemd (PartOf=graphical-session.target)
330338
         loop {
331
-            // Compute reconnection delay (if needed) before select
339
+            // X11 health check (periodic, only if connected)
340
+            if !x11_needs_reconnect && last_x11_health_check.elapsed() >= x11_health_interval {
341
+                last_x11_health_check = std::time::Instant::now();
342
+                if !self.x11_is_alive() {
343
+                    tracing::warn!("X11 connection lost, will attempt reconnect");
344
+                    self.conn = None;
345
+                    self.animation = None; // Animation renderer is now invalid
346
+                    x11_needs_reconnect = true;
347
+                    last_x11_reconnect = std::time::Instant::now();
348
+                }
349
+            }
350
+
351
+            // Compute X11 reconnection delay
352
+            let x11_reconnect_delay = if x11_needs_reconnect {
353
+                let elapsed = last_x11_reconnect.elapsed();
354
+                if elapsed < x11_reconnect_backoff {
355
+                    Some(x11_reconnect_backoff - elapsed)
356
+                } else {
357
+                    Some(Duration::ZERO)
358
+                }
359
+            } else {
360
+                None
361
+            };
362
+
363
+            // Compute gar reconnection delay (if needed) before select
332364
             let reconnect_delay = if gar_needs_reconnect {
333365
                 let elapsed = last_gar_reconnect.elapsed();
334366
                 if elapsed < gar_reconnect_backoff {
@@ -451,6 +483,33 @@ impl Daemon {
451483
                     }
452484
                 }
453485
 
486
+                // X11 reconnection timer (only when disconnected)
487
+                _ = async {
488
+                    if let Some(delay) = x11_reconnect_delay {
489
+                        tokio::time::sleep(delay).await;
490
+                    } else {
491
+                        std::future::pending::<()>().await;
492
+                    }
493
+                } => {
494
+                    tracing::debug!("Attempting to reconnect to X11...");
495
+                    last_x11_reconnect = std::time::Instant::now();
496
+
497
+                    if self.try_connect_x11() {
498
+                        x11_needs_reconnect = false;
499
+                        x11_reconnect_backoff = Duration::from_secs(1);
500
+                        tracing::info!("Reconnected to X11");
501
+
502
+                        // Re-apply wallpaper after reconnection
503
+                        if let Err(e) = self.reapply_wallpaper() {
504
+                            tracing::warn!("Failed to re-apply wallpaper after X11 reconnect: {}", e);
505
+                        }
506
+                    } else {
507
+                        // Exponential backoff, max 30 seconds
508
+                        x11_reconnect_backoff = (x11_reconnect_backoff * 2).min(x11_max_backoff);
509
+                        tracing::debug!("X11 reconnection failed, next attempt in {:?}", x11_reconnect_backoff);
510
+                    }
511
+                }
512
+
454513
                 // gar reconnection timer (only when disconnected)
455514
                 _ = async {
456515
                     if let Some(delay) = reconnect_delay {