From 670c9845129fc0c4b6e0192d657eea05e1a64b49 Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Wed, 13 May 2026 19:47:00 +0200 Subject: Expose key bindings over IPC so a launcher can list them Asked whether srdwm's bindings show in the AGS launcher. They could not: srd.bind lives entirely in the Lua engine, and nothing published a binding anywhere a client could read it. There was no IPC command, no field in any response, and bound_keys() was used only by main.rs to register grabs. srd.bind now takes an optional third argument, a description, and the loaded set is copied into the WindowManager after the initial load and after every reload. Core neither owns nor interprets them - it has no Lua state and never dispatches a key - it holds them so the IPC layer, which is handed a WindowManager and nothing else, can serve them. New `srd keybindings` returns combo and description pairs, sorted so a UI listing them does not reshuffle on every refresh. Every binding in the shipped config now carries a description, so the feature is useful without the user writing any. Verified live in a nested instance: 46 bindings published, 0 without a description, and editing the config file updated the list without a restart (which also exercised reload-on-write again). Also verified, for the separate report that windows cannot be moved to another workspace from the AGS workspace pills: the compositor side works. `srd dispatch move workspace 2` moved a window from workspace 1 to 2 and correctly hid it, since workspace 1 was active. Nothing to fix here; the missing piece is on the shell side. 515 tests pass, clippy clean. --- crates/config/src/engine/general.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'crates/config/src/engine/general.rs') diff --git a/crates/config/src/engine/general.rs b/crates/config/src/engine/general.rs index c8a136f..68b441e 100644 --- a/crates/config/src/engine/general.rs +++ b/crates/config/src/engine/general.rs @@ -109,7 +109,7 @@ impl Engine { pub(super) fn fn_bind(&self) -> Result> { let state = self.state.clone(); - Ok(self.lua.create_function(move |lua, (combo, f): (String, mlua::Function)| { + Ok(self.lua.create_function(move |lua, (combo, f, description): (String, mlua::Function, Option)| { // `key_bindings` is keyed by whatever string dispatch builds // from a real keypress (`srdwm_core::key_combo_string`, fixed // Ctrl/Shift/Alt/Mod4 order) - storing the config's own @@ -119,7 +119,11 @@ impl Engine { // grabbed/intercepted. See `parse_key_combo`'s doc comment. let combo = srdwm_core::canonicalize_key_combo(&combo); let key = lua.create_registry_value(f)?; - state.borrow_mut().key_bindings.insert(combo, key); + let mut s = state.borrow_mut(); + if let Some(description) = description.filter(|d| !d.trim().is_empty()) { + s.key_descriptions.insert(combo.clone(), description); + } + s.key_bindings.insert(combo, key); Ok(()) })?) } -- cgit v1.2.3