From ea78f94027ecd2c690904a6d7729e9e3cc190a20 Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Fri, 7 Nov 2025 14:04:00 +0200 Subject: 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. --- crates/platform/src/ipc/dispatch.rs | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'crates/platform/src/ipc/dispatch.rs') diff --git a/crates/platform/src/ipc/dispatch.rs b/crates/platform/src/ipc/dispatch.rs index 918b7e0..3dcca57 100644 --- a/crates/platform/src/ipc/dispatch.rs +++ b/crates/platform/src/ipc/dispatch.rs @@ -28,6 +28,14 @@ pub(crate) fn handle_request(line: &[u8], wm: &std::rc::Rc { + let pinned: Vec = wm.borrow().all_pinned_windows().map(|(pid, id)| PinnedInputInfo { pid, id }).collect(); + (serde_json::to_vec(&PinnedInputsResponse { pinned }).unwrap_or_default(), false) + } // `{"cmd":"create_fake_monitor","name":,"width":, // "height":}` - a fully virtual `wl_output` with no real // hardware behind it, applied by whichever backend owns real @@ -498,6 +514,35 @@ fn handle_set(req: &serde_json::Value, wm: &std::rc::Rc` / `srd set master_count ` -- + // the two `TilingConfig` fields a resize-drag on the master/stack + // boundary (`WindowManager::adjust_master_ratio_for_drag`) already + // live-adjusts interactively; this is the same thing for a + // keybinding or script instead of a mouse drag, e.g. dwm's + // `mod+h`/`mod+l` grow/shrink-master or `mod+i`/`mod+d` add/remove- + // a-master-window conventions. Unlike `gap_inner`/`gap_outer` + // above, which accept "takes effect whenever the workspace next + // re-arranges anyway" (a cosmetic preference under no time + // pressure), this re-arranges the current workspace immediately -- + // a keybind pressed to grow the master column is expected to show + // the result at once, the same instant feedback the drag path + // already gives. + "master_ratio" => { + let Some(v) = value.and_then(|v| v.as_f64()) else { return (err("master_ratio needs a numeric value"), false) }; + let mut wm = wm.borrow_mut(); + wm.tiling.master_ratio = (v as f32).clamp(0.1, 0.9); + let current = wm.current_workspace(); + wm.arrange_workspace(current); + (ok(), true) + } + "master_count" => { + let Some(v) = value.and_then(|v| v.as_u64()) else { return (err("master_count needs a numeric value"), false) }; + let mut wm = wm.borrow_mut(); + wm.tiling.master_count = (v as usize).max(1); + let current = wm.current_workspace(); + wm.arrange_workspace(current); + (ok(), true) + } "shadows" => { let Some(v) = value.and_then(|v| v.as_bool()) else { return (err("shadows needs a boolean value"), false) }; wm.borrow_mut().shadows_enabled = v; -- cgit v1.2.3