srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/core/src/manager/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/core/src/manager/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/core/src/manager/tests.rs')
-rw-r--r--crates/core/src/manager/tests.rs102
1 files changed, 102 insertions, 0 deletions
diff --git a/crates/core/src/manager/tests.rs b/crates/core/src/manager/tests.rs
index 3d628a8..860af89 100644
--- a/crates/core/src/manager/tests.rs
+++ b/crates/core/src/manager/tests.rs
@@ -288,6 +288,108 @@
}
#[test]
+ fn dragging_the_master_columns_right_edge_grows_master_ratio_live() {
+ // Live report: "tiling needs a lot of work" - dragging a tiled
+ // window's border used to write raw geometry that the very next
+ // `arrange_workspace` call silently discarded. Two windows: window
+ // `a` is the sole master (index 0 < master_count 1), `b` is the
+ // whole stack.
+ let mut wm = wm_with_monitor();
+ wm.set_layout(wm.current_workspace(), "tiling");
+ wm.tiling.gap_outer = 0;
+ wm.tiling.gap_inner = 0;
+ wm.tiling.master_ratio = 0.5;
+ let a = wm.alloc_window_id();
+ wm.add_window(Window::new(a, "a"));
+ let b = wm.alloc_window_id();
+ wm.add_window(Window::new(b, "b"));
+
+ let before = wm.window(a).unwrap().geometry.width;
+ wm.start_resize(a, ResizeEdge::Right, 0, 0);
+ wm.update_resize(200, 0); // dragged 200px to the right
+ let after = wm.window(a).unwrap().geometry.width;
+ assert!(after > before, "the master column must visibly grow while dragging its own right edge");
+ assert!(wm.tiling.master_ratio > 0.5, "master_ratio itself must have grown, not just this one window's rect");
+ // The stack window must have shrunk by the matching amount --
+ // this is a real ratio change, not a floating-style resize that
+ // only touched the grabbed window.
+ assert!(wm.window(b).unwrap().geometry.width < 960);
+ }
+
+ #[test]
+ fn dragging_a_stack_windows_left_edge_adjusts_the_same_shared_boundary() {
+ // The mirror case: grabbing the *stack* column's own left edge is
+ // the same physical boundary as the master column's right edge,
+ // approached from the other side.
+ let mut wm = wm_with_monitor();
+ wm.set_layout(wm.current_workspace(), "tiling");
+ wm.tiling.gap_outer = 0;
+ wm.tiling.gap_inner = 0;
+ wm.tiling.master_ratio = 0.5;
+ let a = wm.alloc_window_id();
+ wm.add_window(Window::new(a, "a"));
+ let b = wm.alloc_window_id();
+ wm.add_window(Window::new(b, "b"));
+
+ wm.start_resize(b, ResizeEdge::Left, 0, 0);
+ wm.update_resize(200, 0); // dragged the shared boundary right
+ assert!(wm.tiling.master_ratio > 0.5, "master must grow when the boundary is dragged right, regardless of which side initiated it");
+ }
+
+ #[test]
+ fn dragging_a_floating_windows_edge_never_touches_master_ratio() {
+ let mut wm = wm_with_monitor();
+ wm.set_layout(wm.current_workspace(), "tiling");
+ wm.tiling.master_ratio = 0.5;
+ let a = wm.alloc_window_id();
+ let mut w = Window::new(a, "a");
+ w.floating = true;
+ w.geometry = Rect::new(100, 100, 300, 200);
+ wm.add_window(w);
+
+ wm.start_resize(a, ResizeEdge::Right, 0, 0);
+ wm.update_resize(200, 0);
+ assert_eq!(wm.tiling.master_ratio, 0.5, "a floating window's own resize must behave exactly as before - no tiling ratio involved");
+ assert_eq!(wm.window(a).unwrap().geometry.width, 500, "the floating window itself must still resize normally");
+ }
+
+ #[test]
+ fn dragging_a_tiled_windows_vertical_edge_does_not_touch_master_ratio() {
+ // Only the shared master/stack *horizontal* boundary is a ratio
+ // drag - a vertical edge has no equivalent concept in this
+ // layout (stack windows split height evenly, with no per-window
+ // override), so it must fall through to the ordinary (if
+ // ultimately overwritten) geometry path rather than doing nothing
+ // useful either way.
+ let mut wm = wm_with_monitor();
+ wm.set_layout(wm.current_workspace(), "tiling");
+ wm.tiling.master_ratio = 0.5;
+ let a = wm.alloc_window_id();
+ wm.add_window(Window::new(a, "a"));
+ let b = wm.alloc_window_id();
+ wm.add_window(Window::new(b, "b"));
+
+ wm.start_resize(a, ResizeEdge::Bottom, 0, 0);
+ wm.update_resize(0, 100);
+ assert_eq!(wm.tiling.master_ratio, 0.5);
+ }
+
+ #[test]
+ fn dragging_the_only_windows_edge_with_no_stack_does_not_touch_master_ratio() {
+ // A lone master window has nothing on the other side of any
+ // boundary - there is no stack to trade width with.
+ let mut wm = wm_with_monitor();
+ wm.set_layout(wm.current_workspace(), "tiling");
+ wm.tiling.master_ratio = 0.5;
+ let a = wm.alloc_window_id();
+ wm.add_window(Window::new(a, "a"));
+
+ wm.start_resize(a, ResizeEdge::Right, 0, 0);
+ wm.update_resize(200, 0);
+ assert_eq!(wm.tiling.master_ratio, 0.5);
+ }
+
+ #[test]
fn ending_a_resize_remembers_the_new_size_for_the_apps_next_window() {
let mut wm = wm_with_monitor();
// Tiling layout, so `add_window` skips `SmartPlacement`'s grid/