@@ -270,10 +270,19 @@ impl ManagedConfigDocument { |
| 270 | 270 | } |
| 271 | 271 | |
| 272 | 272 | pub fn resolved_keybind_rows(&self, mod_key: Modifiers) -> Vec<KeybindRow> { |
| 273 | | - resolve_keybind_rows( |
| 274 | | - self.managed_keybind_rows(mod_key), |
| 275 | | - self.external_keybind_rows(mod_key), |
| 276 | | - ) |
| 273 | + let mut external = self.external_keybind_rows(mod_key); |
| 274 | + // Always include defaults so they serve as a fallback layer. |
| 275 | + // When the managed block defines binds, load_config_from_source skips |
| 276 | + // appending defaults to the effective config, which means external_rows |
| 277 | + // can be empty. Without this, editing even one keybind via the settings |
| 278 | + // UI causes all other (default) keybinds to vanish after reload. |
| 279 | + let defaults = super::lua::default_keybinds(&self.effective.settings); |
| 280 | + external.extend(build_keybind_rows( |
| 281 | + &defaults, |
| 282 | + ConfigSource::Default, |
| 283 | + mod_key, |
| 284 | + )); |
| 285 | + resolve_keybind_rows(self.managed_keybind_rows(mod_key), external) |
| 277 | 286 | } |
| 278 | 287 | |
| 279 | 288 | pub fn resolved_keybinds(&self, mod_key: Modifiers) -> Vec<LuaKeybind> { |
@@ -1006,16 +1015,31 @@ mod tests { |
| 1006 | 1015 | |
| 1007 | 1016 | let rows = doc.resolved_keybind_rows(Modifiers::COMMAND); |
| 1008 | 1017 | |
| 1009 | | - assert_eq!(rows.len(), 3); |
| 1018 | + // Managed override takes priority |
| 1010 | 1019 | assert_eq!(rows[0].source, ConfigSource::Managed); |
| 1011 | 1020 | assert_eq!(rows[0].action, "reload"); |
| 1012 | | - assert!(rows.iter().any(|row| row.keybind == default_only)); |
| 1021 | + // Lua-only bind is preserved |
| 1013 | 1022 | assert!(rows.iter().any(|row| row.keybind == lua_only)); |
| 1023 | + // Default-only bind is preserved |
| 1024 | + assert!(rows.iter().any(|row| row.keybind == default_only)); |
| 1025 | + // Managed signature (Cmd+Return) is NOT duplicated by default/lua layer |
| 1014 | 1026 | assert!(!rows.iter().any(|row| { |
| 1015 | 1027 | row.source != ConfigSource::Managed |
| 1016 | 1028 | && row.keybind.modifiers == Modifiers::COMMAND |
| 1017 | 1029 | && row.keybind.key == Key::Return |
| 1018 | 1030 | })); |
| 1031 | + // All default keybinds are present as fallbacks |
| 1032 | + let all_defaults = super::super::lua::default_keybinds(&doc.effective.settings); |
| 1033 | + for default_kb in &all_defaults { |
| 1034 | + let sig = keybind_signature(default_kb); |
| 1035 | + assert!( |
| 1036 | + rows.iter() |
| 1037 | + .any(|row| keybind_signature(&row.keybind) == sig), |
| 1038 | + "missing default keybind: {:?}+{:?}", |
| 1039 | + default_kb.modifiers, |
| 1040 | + default_kb.key, |
| 1041 | + ); |
| 1042 | + } |
| 1019 | 1043 | } |
| 1020 | 1044 | |
| 1021 | 1045 | #[test] |