git.lucas.co / cce-fonts
font browser

commit6674e1a9542a443f70e784dc5d412468136e0d0d
parentea12c6eb62
authorLucas Galante <lsgalante12@gmail.com>
date2026-10-08 08:33
fix(refresh): Ctrl+R and Remove Font rescan the disk, not just the list

RefreshFonts and RemoveFont relisted the font database as loaded at launch,
so a font installed while the app was open never appeared and a removed one
stayed listed until a restart. Both now go through cce_ui::rescan_fonts,
which also brings the renderer's database along; Remove Font waits for the
trash to finish so the rescan finds the file gone. The selection follows
its family by name, since a rescan can add families above it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

 src/main.rs | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 4406392..dafb987 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -394,6 +394,15 @@ impl TypefaceApp {
         v
     }
 
+    /// Pick up fonts installed or removed since launch: the font database is
+    /// the disk as it was at startup until rescanned, so a reload alone only
+    /// relisted what was already known. The engine's renderer takes the same
+    /// change before its next frame.
+    fn rescan_fonts(&mut self) {
+        cce_ui::rescan_fonts(&mut self.font_system);
+        self.reload_fonts();
+    }
+
     fn reload_fonts(&mut self) {
         self.all_fonts = previewable_fonts(self.font_system.db());
         self.families = self.extract_families(&self.all_fonts);
@@ -415,6 +424,11 @@ impl TypefaceApp {
             self.ui_context.register_host(btn);
         }
 
+        // A rescan can add families above the selection: keep it by name, not
+        // by row. (A removed family leaves its row to the one after it.)
+        if let Some(i) = self.selected_family.as_ref().and_then(|f| self.filtered.iter().position(|g| g == f)) {
+            self.selected_idx = Some(i);
+        }
         if let Some(sel) = self.selected_idx {
             if sel >= self.filtered.len() {
                 self.selected_idx = None;
@@ -892,16 +906,17 @@ impl Application for TypefaceApp {
             AppMessage::RemoveFont => {
                 if let Some(ref file) = self.selected_file {
                     if self.is_user_font {
-                        let _ = std::process::Command::new("gio").args(["trash", file]).spawn();
+                        // Waited for: the rescan must find the file gone.
+                        let _ = std::process::Command::new("gio").args(["trash", file]).status();
                         let _ = std::process::Command::new("fc-cache").arg("-f").spawn();
-                        self.reload_fonts();
+                        self.rescan_fonts();
                         *needs_rebuild = true;
                         self.needs_rebuild = true;
                     }
                 }
             }
             AppMessage::RefreshFonts => {
-                self.reload_fonts();
+                self.rescan_fonts();
                 *needs_rebuild = true;
                 self.needs_rebuild = true;
             }