srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/platform/src/ipc/dispatch.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/dispatch.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/dispatch.rs')
-rw-r--r--crates/platform/src/ipc/dispatch.rs45
1 files changed, 45 insertions, 0 deletions
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<std::cell::RefCell<Wi
reading_mode: wm.color_filter == srdwm_core::ColorFilter::ReadingMode,
phone_mode: wm.phone_mode,
multi_cursor: wm.multi_cursor_enabled,
+ border_width: wm.theme.default_border_width,
+ border_color: srdwm_core::format_hex_color(wm.theme.default_border_color),
+ corner_radius: wm.theme.default_corner_radius,
+ decoration_mode_server: wm.theme.default_decorated,
+ gap_inner: wm.tiling.gap_inner,
+ gap_outer: wm.tiling.gap_outer,
+ master_ratio: wm.tiling.master_ratio,
+ master_count: wm.tiling.master_count,
};
(serde_json::to_vec(&settings).unwrap_or_default(), false)
}
@@ -127,6 +135,14 @@ pub(crate) fn handle_request(line: &[u8], wm: &std::rc::Rc<std::cell::RefCell<Wi
wm.borrow_mut().request_pin_input(pid as i32, id);
(ok(), true)
}
+ // `{"cmd":"pinned_inputs"}` - every pid currently pinned and which
+ // window, read from `WindowManager::all_pinned_windows` (the
+ // backend's own confirmation that a `pin_input` request was
+ // genuinely applied, not the one-shot request queue itself).
+ "pinned_inputs" => {
+ let pinned: Vec<PinnedInputInfo> = 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":<string>,"width":<u32>,
// "height":<u32>}` - 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<std::cell::RefCell<Windo
wm.borrow_mut().tiling.gap_outer = v as u32;
(ok(), true)
}
+ // `srd set master_ratio <0.0..1.0>` / `srd set master_count <n>` --
+ // 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;