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

commit7c65e048ccb31e17f3bc51b45b03ef1f9c60e020
parent14aa423c63
authorLucas Galante <[email protected]>
date2026-07-03 17:55
Fix text invisibility in cce-files by defaulting to system monospace font when generic sans-serif query fails to match

 src/backend/window_runner.rs | 15 +++++++++------
 src/color.rs                 |  1 +
 src/layout.rs                | 17 +++++++++++++++++
 3 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/src/backend/window_runner.rs b/src/backend/window_runner.rs
index d4138ae..8fb9ccd 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -102,15 +102,17 @@ pub fn get_text_buffer(fs: &mut FontSystem, text: &str, size: f32, font: Option<
     let metrics = Metrics::new(physical_size, line_height);
     let mut buf = Buffer::new(fs, metrics);
     let mut attrs = Attrs::new();
-    if let Some(ref font_family) = family_name {
-        let family = match font_family.as_str() {
+    let family = if let Some(ref font_family) = family_name {
+        match font_family.as_str() {
             "monospace" => glyphon::Family::Name(crate::layout::get_system_monospace_font()),
-            "sans-serif" => glyphon::Family::SansSerif,
+            "sans-serif" => glyphon::Family::Name(crate::layout::get_system_monospace_font()),
             "serif" => glyphon::Family::Serif,
             name => glyphon::Family::Name(name),
-        };
-        attrs = attrs.family(family);
-    }
+        }
+    } else {
+        glyphon::Family::Name(crate::layout::get_system_monospace_font())
+    };
+    attrs = attrs.family(family);
     buf.set_text(fs, text, attrs, glyphon::Shaping::Advanced);
     buf.shape_until_scroll(fs, true);
 
@@ -1600,6 +1602,7 @@ impl<A: Application> EngineState<A> {
         
         let bounds = TextBounds { left: 0, top: 0, right: pw as i32, bottom: ph as i32 };
         let areas = self.inner.text_areas(scale_f32, bounds);
+        eprintln!("DEBUG RENDER AREAS: len = {}", areas.len());
         
         adapter.text_renderer.prepare(&adapter.device, &adapter.queue, &mut adapter.font_system, &mut adapter.text_atlas, &adapter.text_viewport, areas, &mut adapter.swash_cache).unwrap();
         
diff --git a/src/color.rs b/src/color.rs
index 8db0dad..9610471 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -1118,6 +1118,7 @@ mod color_tests {
             println!("FILE READ FAILED!");
         }
         println!("DROPDOWN COLOR GETTER: {:?}", dropdown_background_color());
+        println!("LIST FONT COLOR GETTER: {:?}", list_font_color());
     }
 }
 
diff --git a/src/layout.rs b/src/layout.rs
index 89a337e..8be2bb3 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -5078,6 +5078,23 @@ pub fn get_system_monospace_font() -> &'static str {
     })
 }
 
+pub fn get_system_sans_serif_font() -> &'static str {
+    static SANS_SERIF_FONT: std::sync::OnceLock<String> = std::sync::OnceLock::new();
+    SANS_SERIF_FONT.get_or_init(|| {
+        if let Ok(output) = std::process::Command::new("fc-match")
+            .args(["-f", "%{family}", "sans-serif"])
+            .output()
+        {
+            let name = String::from_utf8_lossy(&output.stdout);
+            let parsed = name.split(',').next().unwrap_or("sans-serif").trim();
+            if !parsed.is_empty() {
+                return parsed.to_string();
+            }
+        }
+        "sans-serif".to_string()
+    })
+}
+
 impl crate::widget::ContainerLayout for FlexLayout {
     fn box_clone_container(&self) -> Box<dyn crate::widget::ContainerLayout> {
         Box::new(self.clone())