srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/platform/src/ipc/tests.rs
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-11-07 14:04:00 +0200
committersrdusr <[email protected]>2025-11-07 14:04:00 +0200
commitea78f94027ecd2c690904a6d7729e9e3cc190a20 (patch)
treefe622c0cd12a2fe077501a26f0077c51d41b4209 /crates/platform/src/ipc/tests.rs
parenta8991f65602abc5ecee740c443c58fa96ecd15e1 (diff)
downloadsrdwm-ea78f94027ecd2c690904a6d7729e9e3cc190a20.tar.gz
srdwm-ea78f94027ecd2c690904a6d7729e9e3cc190a20.zip
Make tiling's master/stack ratio live, add settings readback everywhere
Investigated the "tiling needs a lot of work" report directly. The MasterStackLayout algorithm itself was already correct; the real gap was that dragging or resizing a tiled window did nothing durable (raw geometry that the next arrange_workspace silently discarded), and master_ratio/master_count had no live path at all (config-file only). A resize-drag on the shared master/stack boundary now live-adjusts TilingConfig::master_ratio and re-arranges the group immediately; srd set master_ratio/master_count do the same for a keybind or script. Found and fixed a real bug while building this: start_resize's own focus_window call re-stacks its target in self.order before the ratio-drag decision used to be made, silently misclassifying real master-column grabs. Fixed by deciding ratio-drag status (and freezing the membership snapshot it depends on) before that raise happens, applying MasterStackLayout directly against the frozen snapshot rather than re-deriving membership from the by-then-reordered live order. Live- verified in a nested compositor, not just unit-tested. Also closes the readback gaps flagged directly by the AGS peer session: border_width/border_color/corner_radius/decoration_mode/gap_inner/ gap_outer/master_ratio/master_count were all live-settable via srd set with no way to read the current value back, and pin_input had no readback at all. SettingsResponse now reports all of them; a new pinned_inputs query (srd pinned inputs) lists every currently pinned pid/window.
Diffstat (limited to 'crates/platform/src/ipc/tests.rs')
-rw-r--r--crates/platform/src/ipc/tests.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/crates/platform/src/ipc/tests.rs b/crates/platform/src/ipc/tests.rs
index 109a9ec..13ab4c2 100644
--- a/crates/platform/src/ipc/tests.rs
+++ b/crates/platform/src/ipc/tests.rs
@@ -735,3 +735,89 @@ fn a_oneshot_clients_request_still_closes_the_connection_as_before() {
Err(e) => assert_eq!(e.kind(), ErrorKind::WouldBlock),
}
}
+
+#[test]
+fn settings_reports_the_readback_fields_flagged_as_missing() {
+ // Confirms the whole batch at once rather than one test per field --
+ // these were all added together for the same reason (a settings
+ // panel could set any of them blind but never read the current value
+ // back).
+ 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();
+ client.write_all(b"{\"cmd\":\"settings\"}\n").unwrap();
+ server.poll(&wm);
+ let line = read_line(&mut std::io::BufReader::new(client));
+ let parsed: serde_json::Value = serde_json::from_str(&line).unwrap();
+ for field in ["border_width", "border_color", "corner_radius", "decoration_mode_server", "gap_inner", "gap_outer", "master_ratio", "master_count"] {
+ assert!(parsed.get(field).is_some(), "settings response is missing '{field}'");
+ }
+ assert_eq!(parsed["border_color"].as_str().unwrap().chars().next(), Some('#'), "border_color must be a hex string, matching what srd set border_color itself accepts");
+}
+
+#[test]
+fn set_master_ratio_is_reflected_immediately_by_settings() {
+ 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 set_client = UnixStream::connect(&server.path).unwrap();
+ set_client.write_all(b"{\"cmd\":\"set\",\"key\":\"master_ratio\",\"value\":0.7}\n").unwrap();
+ server.poll(&wm);
+ let _ = read_line(&mut std::io::BufReader::new(set_client));
+
+ let mut settings_client = UnixStream::connect(&server.path).unwrap();
+ settings_client.write_all(b"{\"cmd\":\"settings\"}\n").unwrap();
+ server.poll(&wm);
+ let line = read_line(&mut std::io::BufReader::new(settings_client));
+ assert!(line.contains(r#""master_ratio":0.7"#));
+}
+
+#[test]
+fn set_master_ratio_clamps_to_a_sane_range() {
+ 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();
+ client.write_all(b"{\"cmd\":\"set\",\"key\":\"master_ratio\",\"value\":1.5}\n").unwrap();
+ server.poll(&wm);
+ let _ = read_line(&mut std::io::BufReader::new(client));
+
+ assert_eq!(wm.borrow().tiling.master_ratio, 0.9, "a value past the sane range must clamp, not be accepted verbatim");
+}
+
+#[test]
+fn pinned_inputs_lists_nothing_before_any_pin_is_applied() {
+ 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();
+ client.write_all(b"{\"cmd\":\"pinned_inputs\"}\n").unwrap();
+ server.poll(&wm);
+ let line = read_line(&mut std::io::BufReader::new(client));
+ assert_eq!(line.trim_end(), r#"{"pinned":[]}"#);
+}
+
+#[test]
+fn pinned_inputs_reports_a_pin_once_the_backend_has_applied_it() {
+ // `pin_input` only ever queues a *request* - `WindowManager::
+ // set_pinned_window` is the backend's own confirmation that it was
+ // genuinely applied, called directly here to simulate that (the real
+ // caller is `CompState::set_virtual_pointer_pin` in the wayland
+ // crate, unreachable from a platform-crate test).
+ 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_pinned_window(12345, Some(7));
+
+ let mut client = UnixStream::connect(&server.path).unwrap();
+ client.write_all(b"{\"cmd\":\"pinned_inputs\"}\n").unwrap();
+ server.poll(&wm);
+ let line = read_line(&mut std::io::BufReader::new(client));
+ assert_eq!(line.trim_end(), r#"{"pinned":[{"pid":12345,"id":7}]}"#);
+}