diff options
| author | srdusr <[email protected]> | 2025-11-07 14:04:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2025-11-07 14:04:00 +0200 |
| commit | ea78f94027ecd2c690904a6d7729e9e3cc190a20 (patch) | |
| tree | fe622c0cd12a2fe077501a26f0077c51d41b4209 /crates/core/src/manager/tests.rs | |
| parent | a8991f65602abc5ecee740c443c58fa96ecd15e1 (diff) | |
| download | srdwm-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.rs | 102 |
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/ |