system settings
git clone https://git.lucas.co/cce-system-interface.git
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,