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

commit11bc7d517991cf8bf899b923b8c801ed11b1b864
parent9ef50e5692
authorLucas Galante <[email protected]>
date2026-06-23 14:23
refactor: remove legacy fallback files and watchers, query compositor via sockets

 src/main.rs            |   8 +---
 src/pages/interface.rs | 105 ++++++++++++++++++++++++++++++++-----------------
 src/watchers.rs        |  38 ------------------
 3 files changed, 71 insertions(+), 80 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 645e51b..c9390b2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -135,7 +135,6 @@ struct SystemInterface {
     rx_display: std::sync::mpsc::Receiver<pages::display::DisplayState>,
     rx_network: std::sync::mpsc::Receiver<pages::network::NetworkState>,
     rx_layout: std::sync::mpsc::Receiver<pages::interface::WindowsState>,
-    rx_wm_events: std::sync::mpsc::Receiver<()>,
     rx_input: std::sync::mpsc::Receiver<pages::input::InputState>,
     rx_fingers: std::sync::mpsc::Receiver<Vec<Finger>>,
     rx_processes: std::sync::mpsc::Receiver<pages::processes::ProcessesState>,
@@ -233,7 +232,6 @@ impl cce_ui::engine::Application for SystemInterface {
             rx_display: watchers.rx_display,
             rx_network: watchers.rx_network,
             rx_layout: watchers.rx_layout,
-            rx_wm_events: watchers.rx_wm_events,
             rx_input: watchers.rx_input,
             rx_fingers: watchers.rx_fingers,
             rx_processes: watchers.rx_processes,
@@ -584,11 +582,7 @@ fn collect_popover_rects(w: &dyn cce_ui::widget::Element, popovers: &mut Vec<(f3
                 self.needs_rebuild = true;
             }
         }
-        while let Ok(_) = self.rx_wm_events.try_recv() {
-            if self.app.current_page == Page::Interface {
-                self.needs_rebuild = true;
-            }
-        }
+
         while let Ok(s) = self.rx_input.try_recv() {
             input::update(&mut self.app.input, input::InputMessage::Refreshed(s));
             if self.app.current_page == Page::Input {
diff --git a/src/pages/interface.rs b/src/pages/interface.rs
index 275adb0..5c1818e 100644
--- a/src/pages/interface.rs
+++ b/src/pages/interface.rs
@@ -17,6 +17,44 @@ fn get_socket_path() -> String {
     }
 }
 
+fn get_status_socket_path() -> String {
+    match std::env::var("WAYLAND_DISPLAY") {
+        Ok(display) => format!("/tmp/cce-status-{}.sock", display),
+        Err(_) => "/tmp/cce-status.sock".to_string(),
+    }
+}
+
+fn query_ipc(cmd: &str) -> String {
+    use std::io::{Read, Write};
+    if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(get_socket_path()) {
+        let _ = stream.set_read_timeout(Some(std::time::Duration::from_millis(20)));
+        let _ = stream.set_write_timeout(Some(std::time::Duration::from_millis(20)));
+        if stream.write_all(format!("{}\n", cmd).as_bytes()).is_ok() {
+            let mut reply = String::new();
+            if stream.read_to_string(&mut reply).is_ok() {
+                return reply;
+            }
+        }
+    }
+    String::new()
+}
+
+fn query_status(sub: &str) -> String {
+    use std::io::{BufRead, Write};
+    if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(get_status_socket_path()) {
+        let _ = stream.set_read_timeout(Some(std::time::Duration::from_millis(20)));
+        let _ = stream.set_write_timeout(Some(std::time::Duration::from_millis(20)));
+        if stream.write_all(format!("{}\n", sub).as_bytes()).is_ok() {
+            let mut reader = std::io::BufReader::new(stream);
+            let mut line = String::new();
+            if reader.read_line(&mut line).is_ok() {
+                return line;
+            }
+        }
+    }
+    String::new()
+}
+
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub enum WidthParam {
     Fullscreen, Cascade, Grid, Floating,
@@ -1059,49 +1097,46 @@ struct LayoutStatusInfo {
     focused_layout_mode: String,
 }
 
+fn get_closest_tag(x: f64, y: f64) -> i32 {
+    let centers = [(0.0, 0.0), (2000.0, 0.0), (0.0, 2000.0), (2000.0, 2000.0)];
+    let mut min_dist = f64::MAX;
+    let mut best_tag = 1;
+    for (i, &(cx, cy)) in centers.iter().enumerate() {
+        let dx = x - cx;
+        let dy = y - cy;
+        let dist = dx * dx + dy * dy;
+        if dist < min_dist {
+            min_dist = dist;
+            best_tag = (i + 1) as i32;
+        }
+    }
+    best_tag
+}
+
 fn read_current_layout_status() -> LayoutStatusInfo {
     let mut active_tags = 1;
     let mut focused_tags = 1;
     let mut _num_tags = 4;
 
-    let display = std::env::var("WAYLAND_DISPLAY").unwrap_or_else(|_| "wayland-0".to_string());
-    
-    let tags_path = format!("/tmp/cce-tags-{}", display);
-    let tags_fallback = "/tmp/cce-tags".to_string();
-    let tags_content = fs::read_to_string(&tags_path)
-        .or_else(|_| fs::read_to_string(&tags_fallback))
-        .unwrap_or_default();
-
-    if let Some(line) = tags_content.lines().next() {
-        let parts: Vec<&str> = line.split_whitespace().collect();
-        if parts.len() >= 3 {
-            active_tags = parts[0].parse().unwrap_or(1);
-            focused_tags = parts[1].parse().unwrap_or(1);
-            _num_tags = parts[2].parse().unwrap_or(4);
+    let tags_content = query_status("tags");
+    if let Some(pan_idx) = tags_content.find("Pan: (") {
+        let coords_str = &tags_content[pan_idx + "Pan: (".len()..];
+        if let Some(end_idx) = coords_str.find(")") {
+            let parts: Vec<&str> = coords_str[..end_idx].split(',').collect();
+            if parts.len() == 2 {
+                let pan_x = parts[0].trim().parse::<f64>().unwrap_or(0.0);
+                let pan_y = parts[1].trim().parse::<f64>().unwrap_or(0.0);
+                let best_tag = get_closest_tag(pan_x, pan_y);
+                active_tags = 1 << (best_tag - 1);
+                focused_tags = active_tags;
+            }
         }
     }
 
-    let title_path = format!("/tmp/cce-title-{}", display);
-    let title_fallback = "/tmp/cce-title".to_string();
-    let focused_title = fs::read_to_string(&title_path)
-        .or_else(|_| fs::read_to_string(&title_fallback))
-        .unwrap_or_default()
-        .trim()
-        .to_string();
-
-    let layout_path = format!("/tmp/cce-layout-{}", display);
-    let layout_fallback = "/tmp/cce-layout".to_string();
-    let focused_layout_mode = fs::read_to_string(&layout_path)
-        .or_else(|_| fs::read_to_string(&layout_fallback))
-        .unwrap_or_else(|_| "Cascade".to_string())
-        .trim()
-        .to_string();
-
-    let windows_path = format!("/tmp/cce-windows-{}", display);
-    let windows_fallback = "/tmp/cce-windows".to_string();
-    let windows_content = fs::read_to_string(&windows_path)
-        .or_else(|_| fs::read_to_string(&windows_fallback))
-        .unwrap_or_default();
+    let focused_title = query_status("title").trim().to_string();
+    let focused_layout_mode = query_status("layout").trim().to_string();
+
+    let windows_content = query_ipc("windows");
 
     let mut windows = Vec::new();
     for line in windows_content.lines() {
diff --git a/src/watchers.rs b/src/watchers.rs
index 280a2e6..8a97368 100644
--- a/src/watchers.rs
+++ b/src/watchers.rs
@@ -9,7 +9,6 @@ pub struct Watchers {
     pub rx_display: Receiver<display::DisplayState>,
     pub rx_network: Receiver<network::NetworkState>,
     pub rx_layout: Receiver<interface::WindowsState>,
-    pub rx_wm_events: Receiver<()>,
     pub rx_input: Receiver<input::InputState>,
     pub rx_fingers: Receiver<Vec<Finger>>,
     pub rx_processes: Receiver<processes::ProcessesState>,
@@ -95,42 +94,6 @@ pub fn spawn_all(
         rx
     };
 
-    let rx_wm_events = {
-        let (tx, rx) = channel::<()>();
-        let current_page_shared = current_page_shared.clone();
-        tokio::spawn(async move {
-            let display = std::env::var("WAYLAND_DISPLAY").unwrap_or_else(|_| "wayland-0".to_string());
-            let windows_path = format!("/tmp/cce-windows-{}", display);
-            let tags_path = format!("/tmp/cce-tags-{}", display);
-            let title_path = format!("/tmp/cce-title-{}", display);
-            
-            let mut last_mod = std::time::SystemTime::UNIX_EPOCH;
-            
-            let check_mtime = |path: &str| -> Option<std::time::SystemTime> {
-                std::fs::metadata(path).and_then(|m| m.modified()).ok()
-            };
-
-            loop {
-                let current_page = current_page_shared.load(Ordering::SeqCst);
-                if current_page == 4 { // Interface is index 4
-                    let mut changed = false;
-                    for p in &[&windows_path, &tags_path, &title_path] {
-                        if let Some(mtime) = check_mtime(p) {
-                            if mtime > last_mod {
-                                last_mod = mtime;
-                                changed = true;
-                            }
-                        }
-                    }
-                    if changed {
-                        if tx.send(()).is_err() { break; }
-                    }
-                }
-                tokio::time::sleep(std::time::Duration::from_millis(500)).await;
-            }
-        });
-        rx
-    };
 
     let rx_input = {
         let (tx, rx) = channel::<input::InputState>();
@@ -262,7 +225,6 @@ pub fn spawn_all(
             rx_display,
             rx_network,
             rx_layout,
-            rx_wm_events,
             rx_input,
             rx_fingers,
             rx_processes,