From 4a55182ce17fd4474f8be1e8819a41b7ccd11045 Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Sun, 31 Aug 2025 14:04:00 +0200 Subject: 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 for the live equivalent (same shape as animations/shadows/rounded_corners). - pin_input IPC dispatch ({"cmd":"pin_input","pid":,"id":}, id omitted to unpin) and its CLI surface, srd dispatch pin input / unpin input . 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. --- crates/platform/src/ipc.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'crates/platform/src') diff --git a/crates/platform/src/ipc.rs b/crates/platform/src/ipc.rs index 1a4b12f..2a55294 100644 --- a/crates/platform/src/ipc.rs +++ b/crates/platform/src/ipc.rs @@ -359,6 +359,12 @@ struct SettingsResponse { animations: bool, night_light: bool, reading_mode: bool, + /// `WindowManager::phone_mode`'s own doc comment: read-only here so a + /// shell panel (AGS) can adapt its own chrome to the same + /// single-app-at-a-time signal srdwm's own placement already uses, + /// without a second, separate way to ask "is this a phone-shaped + /// session". + phone_mode: bool, } /// `"keyboard_layout"`'s one-shot reply shape - the active XKB layout's @@ -740,6 +746,7 @@ fn handle_request(line: &[u8], wm: &std::rc::Rc,"id":}` pins + // every `zwlr_virtual_pointer_unstable_v1` object that client owns + // to window `id` - Phase 2 of the multi-cursor plan (`docs/ + // TODO.md`), the primitive an agent-controlling tool needs to + // operate one specific window without moving the human's own + // cursor or stealing focus. Omitting `id` unpins instead (`{"cmd": + // "pin_input","pid":}`) - one command for both directions, + // since "pin" and "unpin" are really just "set the pin to Some or + // None", the same shape `set_output_enabled`'s own boolean already + // uses for two related actions on one dispatch. Keyed by pid, not + // an opaque per-object id nothing outside the Wayland backend + // could ever learn - a controlling tool already knows its own + // pid (`std::process::id()`) for free. Queued via `request_pin_ + // input` and applied by the Wayland backend on its own next poll, + // same one-poll-tick latency `set_output_position` already has. + "pin_input" => { + let Some(pid) = req.get("pid").and_then(|v| v.as_i64()) else { + return (err("missing pid"), false); + }; + wm.borrow_mut().request_pin_input(pid as i32, id); + (ok(), true) + } // `srd.window.maximize()`/`.fullscreen()`'s exact IPC-side // equivalents - lets an external script (or a live diagnostic // check, same as `toggle_visibility`/`focus`/`close` already allow) @@ -1174,6 +1203,20 @@ fn handle_set(req: &serde_json::Value, wm: &std::rc::Rc` - live equivalent of `general. + // phone_mode`, same "config-settable at startup, also live via + // `srd set`" shape as `animations`/`shadows`/`rounded_corners` + // just above. Only ever changes how the *next* new window opens + // (`WindowManager::add_window`'s own use of this) - `changed` + // is still `true` since a subscriber (a shell panel adapting its + // own chrome to this same signal) genuinely has something new to + // read from `srd settings`, even though no *window* moves as a + // direct result of this call alone. + "phone_mode" => { + let Some(v) = value.and_then(|v| v.as_bool()) else { return (err("phone_mode needs a boolean value"), false) }; + wm.borrow_mut().phone_mode = v; + (ok(), true) + } "blur" => (err("blur is not supported - no GPU shader path on this compositor's software renderer yet"), false), // The two ported Hyprland `decoration:screen_shader` scripts -- // mutually exclusive by construction (`srdwm_core::ColorFilter` is -- cgit v1.2.3