From 304f3a374408bb6a5a04ebb7d4652c631395f5c6 Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Sun, 26 Oct 2025 22:58:00 +0200 Subject: Live-expose monitor split, clean up leftover debug diagnostics srd.monitor.split only ever ran at Lua config load despite being a plain WindowManager mutation that every backend's monitors() already reads fresh on each call. Adds srd dispatch set output split [rows|columns] (IPC set_monitor_split), same id-resolves-to-name pattern set_output_enabled already uses. Also removes eight log::warn!("XXX-DIAG ...") lines left behind from live debugging in the multi-session shift that landed in 3c41fc4 - the same "temporary, never removed" pattern already fixed twice earlier this session. Several fired on genuinely constant interaction (every title change, every workspace switch, every layer-shell surface hide), not just a one-off leftover. Left xdg_shell.rs's own POPUP-GEOM-DIAG/ POPUP-GRAB-DIAG alone - that one is a still-open, self-documented investigation, not litter. Also documents (docs/TODO.md, not a code change) a live incident where creating a second fake monitor visibly corrupted the real monitor's position and kept drifting with no further input - not root-caused srdwm-side, flagged to the AGS peer session since a fake monitor's real wl_output global is indistinguishable from a real hotplug to GDK/GTK. And documents a deliberate decision not to blind-port window decoration rendering onto the experimental, never-live-tested GPU render path. --- crates/platform/src/ipc/tests.rs | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'crates/platform/src/ipc/tests.rs') diff --git a/crates/platform/src/ipc/tests.rs b/crates/platform/src/ipc/tests.rs index cb56a7c..aa86e95 100644 --- a/crates/platform/src/ipc/tests.rs +++ b/crates/platform/src/ipc/tests.rs @@ -425,6 +425,77 @@ fn set_output_enabled_with_neither_name_nor_a_resolvable_id_errors() { assert!(wm.borrow_mut().drain_output_enable_requests().is_empty()); } +#[test] +fn set_monitor_split_accepts_a_name_directly_and_applies_immediately() { + // Unlike `set_output_position`/`set_output_enabled`, this one is a + // plain `WindowManager` mutation with nothing to drain - the very + // next `monitor_split` read already reflects it. + let dir = tempfile::tempdir().unwrap(); + let mut server = IpcServer::bind_in(dir.path(), "test").unwrap(); + let wm = Rc::new(RefCell::new(WindowManager::new())); + wm.borrow_mut().set_monitors(vec![srdwm_core::Monitor::new(0, "eDP-1", srdwm_core::Rect::new(0, 0, 1920, 1080))]); + + let mut client = UnixStream::connect(&server.path).unwrap(); + let mut reader = std::io::BufReader::new(client.try_clone().unwrap()); + client.write_all(b"{\"cmd\":\"set_monitor_split\",\"name\":\"eDP-1\",\"parts\":2,\"rows\":false}\n").unwrap(); + server.poll(&wm); + let _ = read_line(&mut reader); + + let split = wm.borrow().monitor_split("eDP-1").unwrap(); + assert_eq!(split.parts, 2); + assert!(!split.rows); +} + +#[test] +fn set_monitor_split_resolves_an_id_to_its_name() { + let dir = tempfile::tempdir().unwrap(); + let mut server = IpcServer::bind_in(dir.path(), "test").unwrap(); + let wm = Rc::new(RefCell::new(WindowManager::new())); + wm.borrow_mut().set_monitors(vec![srdwm_core::Monitor::new(3, "HDMI-A-1", srdwm_core::Rect::new(0, 0, 1920, 1080))]); + + let mut client = UnixStream::connect(&server.path).unwrap(); + let mut reader = std::io::BufReader::new(client.try_clone().unwrap()); + client.write_all(b"{\"cmd\":\"set_monitor_split\",\"id\":3,\"parts\":3,\"rows\":true}\n").unwrap(); + server.poll(&wm); + let _ = read_line(&mut reader); + + let split = wm.borrow().monitor_split("HDMI-A-1").unwrap(); + assert_eq!(split.parts, 3); + assert!(split.rows); +} + +#[test] +fn set_monitor_split_with_one_part_clears_an_existing_split() { + let dir = tempfile::tempdir().unwrap(); + let mut server = IpcServer::bind_in(dir.path(), "test").unwrap(); + let wm = Rc::new(RefCell::new(WindowManager::new())); + wm.borrow_mut().set_monitors(vec![srdwm_core::Monitor::new(0, "eDP-1", srdwm_core::Rect::new(0, 0, 1920, 1080))]); + wm.borrow_mut().set_monitor_split("eDP-1".to_string(), 2, false); + + let mut client = UnixStream::connect(&server.path).unwrap(); + let mut reader = std::io::BufReader::new(client.try_clone().unwrap()); + client.write_all(b"{\"cmd\":\"set_monitor_split\",\"name\":\"eDP-1\",\"parts\":1}\n").unwrap(); + server.poll(&wm); + let _ = read_line(&mut reader); + + assert!(wm.borrow().monitor_split("eDP-1").is_none()); +} + +#[test] +fn set_monitor_split_with_neither_name_nor_a_resolvable_id_errors() { + let dir = tempfile::tempdir().unwrap(); + let mut server = IpcServer::bind_in(dir.path(), "test").unwrap(); + let wm = Rc::new(RefCell::new(WindowManager::new())); + + let mut client = UnixStream::connect(&server.path).unwrap(); + let mut reader = std::io::BufReader::new(client.try_clone().unwrap()); + client.write_all(b"{\"cmd\":\"set_monitor_split\",\"parts\":2}\n").unwrap(); + server.poll(&wm); + let line = read_line(&mut reader); + + assert!(line.contains(r#""error""#)); +} + #[test] fn monitors_query_lists_a_disabled_output_alongside_live_ones() { // What the AGS peer session asked for directly: a disabled output -- cgit v1.2.3