diff options
| author | srdusr <[email protected]> | 2025-08-31 14:04:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2025-08-31 14:04:00 +0200 |
| commit | 4a55182ce17fd4474f8be1e8819a41b7ccd11045 (patch) | |
| tree | 68541860b6aa2c88c9da2296a747a1037499e1c0 /crates/config/src/engine/general.rs | |
| parent | be5c4efa6866b5d23e1e81ecfc3b8d276540860f (diff) | |
| download | srdwm-4a55182ce17fd4474f8be1e8819a41b7ccd11045.tar.gz srdwm-4a55182ce17fd4474f8be1e8819a41b7ccd11045.zip | |
Wire aspect_ratio, phone_mode and pin_input through config/IPC/CLI
The Lua and IPC/CLI surface for the three new core primitives
(crates/core: aspect_ratio rule action, general.phone_mode, virtual-
pointer window pinning):
- srd.rule(..., { aspect_ratio = "9:16" }): parses a "W:H" string into a
validated (u32, u32), rejecting a malformed value as a real Lua error
at config-load time rather than silently ignoring it.
- general.phone_mode config default, plus srd set phone_mode <bool> for
the live equivalent (same shape as animations/shadows/rounded_corners).
- pin_input IPC dispatch ({"cmd":"pin_input","pid":<pid>,"id":<window
id>}, id omitted to unpin) and its CLI surface, srd dispatch pin input
<pid> <window-id> / unpin input <pid>. Keyed by the owning client's
process id, not an opaque per-object id nothing outside the Wayland
backend could ever learn - a controlling tool already knows its own
pid for free.
See docs/TODO.md for the full design reasoning behind each of these.
Diffstat (limited to 'crates/config/src/engine/general.rs')
| -rw-r--r-- | crates/config/src/engine/general.rs | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/crates/config/src/engine/general.rs b/crates/config/src/engine/general.rs index e5147cd..6276854 100644 --- a/crates/config/src/engine/general.rs +++ b/crates/config/src/engine/general.rs @@ -128,8 +128,8 @@ impl Engine { /// class_regex = "...", instance = "..." }, { floating = true, /// workspace = 2, x = .., y = .., width = .., height = .., /// decorated = false, border_color = {r,g,b}, border_width = 2, - /// corner_radius = 10, maximized = true, opacity = 0.9 })`. At least - /// one matcher field is + /// corner_radius = 10, maximized = true, opacity = 0.9, + /// aspect_ratio = "9:16" })`. At least one matcher field is /// required; unmatched rules apply nothing. /// /// `title`/`class` are plain substring/exact match, cheap and cover @@ -172,6 +172,28 @@ impl Engine { _ => None, } }; + // `aspect_ratio = "9:16"` - the "phone monitor / special + // workspace" ask's own real, scoped answer (see `Window:: + // aspect_ratio`'s own doc comment in `crates/core`): a rule + // matching any VM/emulator/`scrcpy` window by `app_id` keeps + // it phone-shaped through a resize, with no Android-specific + // (or even VM-specific) code anywhere in this compositor. + // `"W:H"` (a plain string, not a table) matches this + // project's own `border_color = {r,g,b}` precedent for "a + // structured value needs its own small parse", just with a + // string instead of a table since a ratio is conventionally + // written that way everywhere (`16:9`, `9:16`, `4:3`). + let aspect_ratio: Option<(u32, u32)> = match actions.get::<_, Option<String>>("aspect_ratio")? { + Some(spec) => { + let (w, h) = spec + .split_once(':') + .and_then(|(w, h)| Some((w.trim().parse::<u32>().ok()?, h.trim().parse::<u32>().ok()?))) + .filter(|(w, h)| *w > 0 && *h > 0) + .ok_or_else(|| mlua::Error::RuntimeError(format!("srd.rule: aspect_ratio must be \"W:H\" with positive integers, got {spec:?}")))?; + Some((w, h)) + } + None => None, + }; let rule = WindowRule { matcher: WindowMatch { title_contains, class, title_regex, class_regex, instance }, @@ -187,6 +209,7 @@ impl Engine { pinned: actions.get("pinned")?, opacity: actions.get("opacity")?, resize_margin: actions.get("resize_margin")?, + aspect_ratio, }, }; state.borrow().wm.borrow_mut().add_rule(rule); |