git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commitfcf1815aecf48079219e64cd166c87b0aa0f58a7
parent691c7e357f
authorLucas Galante <[email protected]>
date2026-07-01 12:40
Support nested key_bindings inside input node in config.kdl

 src/config.rs                        | 11 +++++++++--
 src/widget/input/keybinds_control.rs |  6 +++++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/config.rs b/src/config.rs
index 8bac96a..040e22e 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -391,7 +391,7 @@ pub fn write_keybindings_to_kdl(path: &str, keybinds: &[serde_json::Value]) -> b
         Err(_) => kdl::KdlDocument::new(),
     };
 
-    // Remove all existing key_bindings nodes
+    // Remove all existing key_bindings nodes (root-level)
     doc.nodes_mut().retain(|n| n.name().value() != "key_bindings");
 
     // Construct nested key_bindings block
@@ -422,7 +422,14 @@ pub fn write_keybindings_to_kdl(path: &str, keybinds: &[serde_json::Value]) -> b
     block_str.push_str("}\n");
 
     if let Ok(node) = block_str.parse::<kdl::KdlNode>() {
-        doc.nodes_mut().push(node);
+        if let Some(input_idx) = doc.nodes().iter().position(|n| n.name().value() == "input") {
+            let input_node = &mut doc.nodes_mut()[input_idx];
+            let children = input_node.ensure_children();
+            children.nodes_mut().retain(|n| n.name().value() != "key_bindings");
+            children.nodes_mut().push(node);
+        } else {
+            doc.nodes_mut().push(node);
+        }
     }
 
     let updated_str = doc.to_string();
diff --git a/src/widget/input/keybinds_control.rs b/src/widget/input/keybinds_control.rs
index b5952a2..0ce9dd4 100644
--- a/src/widget/input/keybinds_control.rs
+++ b/src/widget/input/keybinds_control.rs
@@ -57,7 +57,11 @@ impl KeybindsControl {
         let content = std::fs::read_to_string(&path).unwrap_or_default();
         let val = crate::config::parse_kdl_to_json(&content);
         let mut loaded = Vec::new();
-        if let Some(arr) = val.get("key_bindings").and_then(|k| k.as_array()) {
+        let mut keybind_val = val.get("key_bindings");
+        if keybind_val.is_none() {
+            keybind_val = val.get("input").and_then(|i| i.get("key_bindings"));
+        }
+        if let Some(arr) = keybind_val.and_then(|k| k.as_array()) {
             for v in arr {
                 let mods = v.get("mods").and_then(|m| m.as_str()).unwrap_or("").to_string();
                 let key = v.get("key").and_then(|k| k.as_str()).unwrap_or("").to_string();