Follow the system UI font face

Detect the desktop's configured interface font and use its family for all
application UI text, instead of iced's generic sans-serif.

- sys::ui_font reads the setting per platform: GNOME/Cinnamon/MATE
  gsettings, KDE kdeglobals, Xfce xfconf, the XDG Settings portal, GTK
  settings.ini and a Fontconfig fallback on Linux; the non-client message
  font (SystemParametersInfoForDpi at 96 DPI) on Windows; the AppKit system
  font on macOS.
- ui_font::apply remaps generic sans-serif in iced's shared font database
  to that family. iced's Font::DEFAULT is sans-serif, so every widget,
  canvas text, bold/italic variant and ribbon measurement follows it with
  no call-site changes. A family that is not installed (or a generic alias)
  keeps iced's own choice. The font's weight and style are ignored.
- Live updates: portal SettingChanged on Linux, a 2 s poll on Windows. A
  change bumps the font-system version so laid-out text reshapes, and
  iced::font::set_defaults relays out every window; ribbon large-button
  widths re-measure. Without a portal, Linux needs a restart; macOS has no
  user-adjustable UI font.
- Monospaced text, drawing text (own cosmic-text font systems) and the web
  build's font loading are unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Manu VarkeyandClaude Opus 5.5 committed 2026-10-16 01:59:17 +05:30
1 parent bec9e63679
commit 62175f4ed5
10 files changed
+1134 -7

No files matched your search

+12 -4
View File
@@ -94,8 +94,9 @@ const COMBO_PANEL_PAD: Padding = Padding {
thread_local! {
/// Ribbon layout runs on every pointer-driven view update. Cache the font-
/// measured width per translated label so the automatic sizing stays cheap.
static LARGE_WIDTH_CACHE: RefCell<HashMap<String, f32>> =
RefCell::new(HashMap::default());
/// Tagged with the UI-font generation it was measured with.
static LARGE_WIDTH_CACHE: RefCell<(u32, HashMap<String, f32>)> =
RefCell::new((0, HashMap::default()));
}
/// Dropdown items that report a state and cannot be picked.
@@ -173,13 +174,20 @@ fn measure_large_width(renderer: &iced::Renderer, label: &str) -> f32 {
}
fn automatic_large_width(renderer: &iced::Renderer, label: &str) -> f32 {
if let Some(width) = LARGE_WIDTH_CACHE.with(|cache| cache.borrow().get(label).copied()) {
let generation = crate::sys::ui_font::generation();
if let Some(width) = LARGE_WIDTH_CACHE.with(|cache| {
let mut cache = cache.borrow_mut();
if cache.0 != generation {
*cache = (generation, HashMap::default());
}
cache.1.get(label).copied()
}) {
return width;
}
let width = measure_large_width(renderer, label);
LARGE_WIDTH_CACHE.with(|cache| {
cache.borrow_mut().insert(label.to_string(), width);
cache.borrow_mut().1.insert(label.to_string(), width);
});
width
}