diff options
Diffstat (limited to 'crates/config')
| -rw-r--r-- | crates/config/src/engine/general.rs | 8 | ||||
| -rw-r--r-- | crates/config/src/engine/mod.rs | 22 | ||||
| -rw-r--r-- | crates/config/src/engine/support.rs | 4 |
3 files changed, 31 insertions, 3 deletions
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<mlua::Function<'_>> { 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<String>)| { // `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(()) })?) } diff --git a/crates/config/src/engine/mod.rs b/crates/config/src/engine/mod.rs index ac7bdb8..8facd56 100644 --- a/crates/config/src/engine/mod.rs +++ b/crates/config/src/engine/mod.rs @@ -26,6 +26,15 @@ struct SharedState { wm: Rc<RefCell<WindowManager>>, values: HashMap<String, ConfigValue>, key_bindings: HashMap<String, RegistryKey>, + /// Human-readable description for a binding, from `srd.bind`'s optional + /// third argument. Separate from `key_bindings` so a binding without one + /// costs nothing, and cleared alongside it on reload. + /// + /// Exists so a launcher or cheat-sheet can list what the keys actually + /// do - a bare combo is close to useless in a UI. Published to + /// `WindowManager` by `main.rs` and served over IPC as + /// `srd keybindings`. + key_descriptions: HashMap<String, String>, /// Combos registered with `srd.bind_repeat`, which fire repeatedly while /// held (Hyprland's `binde`). A subset of `key_bindings`. repeat_keys: std::collections::HashSet<String>, @@ -67,6 +76,7 @@ impl Engine { wm, values: default_config(), key_bindings: HashMap::new(), + key_descriptions: HashMap::new(), repeat_keys: std::collections::HashSet::new(), event_handlers: HashMap::new(), config_dir: config_dir.into(), @@ -189,6 +199,18 @@ impl Engine { self.state.borrow().key_bindings.keys().cloned().collect() } + /// Every binding as `(combo, description)`, sorted by combo so the list + /// is stable between calls - a UI listing them should not reshuffle on + /// every refresh. `description` is empty when the binding did not give + /// one. + pub fn bound_keys_with_descriptions(&self) -> Vec<(String, String)> { + let state = self.state.borrow(); + let mut out: Vec<(String, String)> = + state.key_bindings.keys().map(|combo| (combo.clone(), state.key_descriptions.get(combo).cloned().unwrap_or_default())).collect(); + out.sort(); + out + } + /// Combos that should auto-repeat while held. pub fn repeat_keys(&self) -> Vec<String> { self.state.borrow().repeat_keys.iter().cloned().collect() diff --git a/crates/config/src/engine/support.rs b/crates/config/src/engine/support.rs index 76bcf5e..9d81035 100644 --- a/crates/config/src/engine/support.rs +++ b/crates/config/src/engine/support.rs @@ -33,16 +33,18 @@ pub(super) fn do_reload(lua: &Lua, state: &Rc<RefCell<SharedState>>) -> Result<( std::mem::take(&mut s.key_bindings), std::mem::take(&mut s.event_handlers), std::mem::take(&mut s.repeat_keys), + std::mem::take(&mut s.key_descriptions), ); (s.config_dir.clone(), previous) }; - let restore = |state: &Rc<RefCell<SharedState>>, previous: (_, _, _)| { + let restore = |state: &Rc<RefCell<SharedState>>, previous: (_, _, _, _)| { let mut s = state.borrow_mut(); // Whatever the failed run managed to register before erroring is // discarded, not merged: half of a broken config is not a config. s.key_bindings = previous.0; s.event_handlers = previous.1; s.repeat_keys = previous.2; + s.key_descriptions = previous.3; }; let path = config_dir.join("init.lua"); let src = match std::fs::read_to_string(&path) { |