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/ctl/src | |
| 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/ctl/src')
| -rw-r--r-- | crates/ctl/src/main.rs | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/crates/ctl/src/main.rs b/crates/ctl/src/main.rs index fb896a3..fb7196c 100644 --- a/crates/ctl/src/main.rs +++ b/crates/ctl/src/main.rs @@ -145,6 +145,8 @@ fn build_request(args: &[String]) -> Result<String, String> { Some("monitors") => Ok(r#"{"cmd":"monitors"}"#.to_string()), Some("workspaces") => Ok(r#"{"cmd":"workspaces"}"#.to_string()), Some("settings") => Ok(r#"{"cmd":"settings"}"#.to_string()), + Some("pinned") if args.get(1).map(String::as_str) == Some("inputs") => Ok(r#"{"cmd":"pinned_inputs"}"#.to_string()), + Some("pinned") => Err("did you mean 'srd pinned inputs'?".to_string()), Some("keyboard") if args.get(1).map(String::as_str) == Some("layout") => Ok(r#"{"cmd":"keyboard_layout"}"#.to_string()), Some("keyboard") => Err("did you mean 'srd keyboard layout'?".to_string()), Some("subscribe") => Ok(r#"{"cmd":"subscribe"}"#.to_string()), @@ -184,13 +186,14 @@ fn build_request(args: &[String]) -> Result<String, String> { // as booleans at all, not a string it then has to reject. Some("set") => { let key = args.get(1).ok_or( - "set needs a key (border_width/border_color/corner_radius/gap_inner/gap_outer/shadows/rounded_corners/animations/night_light/reading_mode/phone_mode/multi_cursor/decoration_mode)", + "set needs a key (border_width/border_color/corner_radius/gap_inner/gap_outer/master_ratio/master_count/shadows/rounded_corners/animations/night_light/reading_mode/phone_mode/multi_cursor/decoration_mode)", )?; let raw = args.get(2).ok_or("set needs a value")?; let value = match key.as_str() { - "border_width" | "corner_radius" | "gap_inner" | "gap_outer" => { + "border_width" | "corner_radius" | "gap_inner" | "gap_outer" | "master_count" => { raw.parse::<u64>().map_err(|_| format!("{key} needs a numeric value"))?.to_string() } + "master_ratio" => raw.parse::<f64>().map_err(|_| format!("{key} needs a numeric value"))?.to_string(), "shadows" | "rounded_corners" | "animations" | "night_light" | "reading_mode" | "phone_mode" | "multi_cursor" => match raw.as_str() { "true" | "false" => raw.clone(), _ => return Err(format!("{key} needs 'true' or 'false'")), @@ -394,6 +397,7 @@ fn print_usage() { eprintln!(" srd monitors"); eprintln!(" srd workspaces"); eprintln!(" srd settings"); + eprintln!(" srd pinned inputs"); eprintln!(" srd keyboard layout"); eprintln!(" srd subscribe"); eprintln!(" srd dispatch focus <id>"); @@ -654,6 +658,24 @@ mod tests { fn settings_query_needs_no_further_arguments() { assert_eq!(build_request(&args(&["settings"])).unwrap(), r#"{"cmd":"settings"}"#); } + + #[test] + fn pinned_inputs_query_reads_as_two_words() { + assert_eq!(build_request(&args(&["pinned", "inputs"])).unwrap(), r#"{"cmd":"pinned_inputs"}"#); + assert!(build_request(&args(&["pinned"])).is_err()); + } + + #[test] + fn set_master_ratio_accepts_a_fractional_value() { + assert_eq!(build_request(&args(&["set", "master_ratio", "0.65"])).unwrap(), r#"{"cmd":"set","key":"master_ratio","value":0.65}"#); + assert!(build_request(&args(&["set", "master_ratio", "not-a-number"])).is_err()); + } + + #[test] + fn set_master_count_accepts_a_plain_integer() { + assert_eq!(build_request(&args(&["set", "master_count", "2"])).unwrap(), r#"{"cmd":"set","key":"master_count","value":2}"#); + assert!(build_request(&args(&["set", "master_count", "not-a-number"])).is_err()); + } } #[cfg(unix)] |