git.lucas.co / cce-fonts
font browser

commit7ec363611b229b9c4a3b5ed47059eb9535291eff
parent1364684f9d
authorLucas Galante <[email protected]>
date2026-07-16 12:16
feat: resolve shortcuts through input.kdl's cce-fonts domain

refresh (ctrl+r), open_search (ctrl+f), focus_preview (ctrl+e),
open_folder (ctrl+o), remove_font (delete). The +/- size chords stay
hardcoded (the +/= key pair doesn't round-trip chord strings).

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01PXSsCppeDFmSRRM5NAug5a

 src/main.rs | 78 +++++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 48 insertions(+), 30 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 3b698dd..40b8874 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -198,7 +198,32 @@ impl ScrollRegion {
     }
 }
 
+/// App shortcuts, resolved once at startup from input.kdl
+/// (`cce-fonts` domain → `cce-ui` domain), defaulting to the historical keys.
+struct FontsKeys {
+    refresh: String,
+    open_search: String,
+    focus_preview: String,
+    open_folder: String,
+    remove_font: String,
+}
+
+impl FontsKeys {
+    fn load() -> Self {
+        let get = cce_ui::input::app_chord;
+        Self {
+            refresh: get("refresh", "ctrl+r"),
+            open_search: get("open_search", "ctrl+f"),
+            focus_preview: get("focus_preview", "ctrl+e"),
+            open_folder: get("open_folder", "ctrl+o"),
+            remove_font: get("remove_font", "delete"),
+        }
+    }
+}
+
 struct TypefaceApp {
+    keys: FontsKeys,
+
     // Browse panel
     search_box: cce_ui::widget::Adapted<TextBox>,
     list_region: ScrollRegion,
@@ -586,6 +611,7 @@ impl Application for TypefaceApp {
 
         let all_fonts = pages::fetch_fonts();
         let mut app = Self {
+            keys: FontsKeys::load(),
             search_box,
             list_region: ScrollRegion::new(),
             list_item_h,
@@ -1294,41 +1320,33 @@ impl Application for TypefaceApp {
         let mut handled = false;
         let mut msg_out = None;
 
-        // Custom keyboard shortcuts
-        if event.ctrl && event.state == ElementState::Pressed {
-            if let Key::Character(ref ch) = event.logical_key {
-                match ch.to_lowercase().as_str() {
-                    "r" => {
-                        msg_out = Some(AppMessage::RefreshFonts);
-                        handled = true;
-                    }
-                    "f" => {
-                        self.search_box.focus();
-                        self.ui_context.set_focused(&mut self.search_box);
-                        self.preview_box.unfocus();
-                        handled = true;
-                    }
-                    "e" => {
-                        self.preview_box.focus();
-                        self.ui_context.set_focused(&mut self.preview_box);
-                        self.search_box.unfocus();
-                        handled = true;
-                    }
-                    "o" => {
-                        msg_out = Some(AppMessage::OpenFolder);
-                        handled = true;
-                    }
-                    _ => {}
-                }
+        // Custom keyboard shortcuts (input.kdl `cce-fonts` domain)
+        if event.state == ElementState::Pressed {
+            let m = |chord: &str| cce_ui::widget::match_key_shortcut(event, chord);
+            if m(&self.keys.refresh) {
+                msg_out = Some(AppMessage::RefreshFonts);
+                handled = true;
+            } else if m(&self.keys.open_search) {
+                self.search_box.focus();
+                self.ui_context.set_focused(&mut self.search_box);
+                self.preview_box.unfocus();
+                handled = true;
+            } else if m(&self.keys.focus_preview) {
+                self.preview_box.focus();
+                self.ui_context.set_focused(&mut self.preview_box);
+                self.search_box.unfocus();
+                handled = true;
+            } else if m(&self.keys.open_folder) {
+                msg_out = Some(AppMessage::OpenFolder);
+                handled = true;
+            } else if m(&self.keys.remove_font) {
+                msg_out = Some(AppMessage::RemoveFont);
+                handled = true;
             }
         }
 
         if !handled && event.state == ElementState::Pressed {
             match event.logical_key {
-                Key::Named(NamedKey::Delete) => {
-                    msg_out = Some(AppMessage::RemoveFont);
-                    handled = true;
-                }
                 Key::Character(ref ch) if ch == "+" || ch == "=" => {
                     if self.selected_family.is_some() {
                         let (_, max) = self.size_spinbox.range();