git.lucas.co / cce-system-interface
system settings
git clone https://git.lucas.co/cce-system-interface.git

commitdf05d41f16c84bea45179f77f0d434f55b08bc18
parenta514ab5b25
authorLucas Galante <[email protected]>
date2026-06-26 17:26
fix: debounce status interface reloads on slider changes to prevent compositor segfaults

 src/pages/interface.rs | 50 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 7 deletions(-)

diff --git a/src/pages/interface.rs b/src/pages/interface.rs
index 04378e5..3212c13 100644
--- a/src/pages/interface.rs
+++ b/src/pages/interface.rs
@@ -1919,13 +1919,49 @@ fn apply_disabled_color(rgb: [u8; 3]) {
 }
 
 pub fn status_interface_reload() {
-    std::thread::spawn(|| {
-        let _ = std::process::Command::new("pkill")
-            .args(["-f", "cce-status-interface"])
-            .status();
-        std::thread::sleep(std::time::Duration::from_millis(150));
-        send_ipc_command("spawn cce-status-interface");
-    });
+    use std::sync::{Mutex, OnceLock};
+    use std::time::{Duration, Instant};
+
+    struct StatusDebouncer {
+        last_trigger: Instant,
+        active: bool,
+    }
+
+    impl StatusDebouncer {
+        fn new() -> Self {
+            Self {
+                last_trigger: Instant::now(),
+                active: false,
+            }
+        }
+    }
+
+    static DEBOUNCER: OnceLock<Mutex<StatusDebouncer>> = OnceLock::new();
+    let debouncer = DEBOUNCER.get_or_init(|| Mutex::new(StatusDebouncer::new()));
+    
+    let mut guard = debouncer.lock().unwrap();
+    guard.last_trigger = Instant::now();
+    if !guard.active {
+        guard.active = true;
+        std::thread::spawn(|| {
+            loop {
+                std::thread::sleep(Duration::from_millis(100));
+                let mut guard = DEBOUNCER.get().unwrap().lock().unwrap();
+                if guard.last_trigger.elapsed() >= Duration::from_millis(250) {
+                    guard.active = false;
+                    drop(guard);
+
+                    // Perform the actual reload
+                    let _ = std::process::Command::new("pkill")
+                        .args(["-f", "cce-status-interface"])
+                        .status();
+                    std::thread::sleep(Duration::from_millis(150));
+                    send_ipc_command("spawn cce-status-interface");
+                    break;
+                }
+            }
+        });
+    }
 }
 
 fn write_status_value(key: &str, value: &str) {