mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 17:56:50 -06:00
Fix #2576: poll for fonts font managers activate while the app is in front
Font services (NexusFont, Adobe Fonts) register faces with the OS without touching font-folder mtimes; only re-asking the platform lister sees them. Check every two seconds as well as on window focus, and test that path churn is detected on the system font scan. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Cursor
parent
bf2379f401
commit
640c87b537
@@ -1611,6 +1611,12 @@ impl FontDb {
|
||||
Self::new(FontPaths::Fixed(font_dirs))
|
||||
}
|
||||
|
||||
/// Same scan paths as [`FontDb::global`] (platform lister and font folders), for tests.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn for_system_scan_test() -> Self {
|
||||
Self::new(FontPaths::System)
|
||||
}
|
||||
|
||||
fn new(font_paths: FontPaths) -> Self {
|
||||
let mut faces = Vec::new();
|
||||
// Bundled fonts first, then explicitly supplied craft-fonts faces: Japanese (Mincho
|
||||
|
||||
@@ -331,6 +331,25 @@ fn service_font() -> PathBuf {
|
||||
std::env::temp_dir().join(format!("vc-sysfonts-{}-service", std::process::id())).join(".29457")
|
||||
}
|
||||
|
||||
/// Fonts a font service activates after the first scan are picked up on the next check (#2576).
|
||||
#[test]
|
||||
fn the_database_tells_when_a_font_service_adds_a_font() {
|
||||
use std::sync::Mutex;
|
||||
static FILES: Mutex<Vec<String>> = Mutex::new(Vec::new());
|
||||
set_platform_font_files(|| FILES.lock().unwrap_or_else(|e| e.into_inner()).clone());
|
||||
let file = service_font();
|
||||
std::fs::create_dir_all(file.parent().unwrap()).unwrap();
|
||||
let db = FontDb::for_system_scan_test();
|
||||
assert!(!db.installed_fonts_changed());
|
||||
db.load_system_fonts();
|
||||
assert!(!db.has_family("Service Sans3"));
|
||||
std::fs::write(&file, renamed_to("SourceSans3-Regular.ttf", "Service Sans3")).unwrap();
|
||||
*FILES.lock().unwrap_or_else(|e| e.into_inner()) = vec![file.to_string_lossy().into_owned()];
|
||||
assert!(db.installed_fonts_changed(), "a font a font service activated since the scan");
|
||||
db.load_system_fonts();
|
||||
assert!(db.has_family("Service Sans3"));
|
||||
}
|
||||
|
||||
/// The fonts a font service (Adobe Fonts on Windows, through DirectWrite) loads in place are
|
||||
/// cataloged: named by the platform's lister, read whatever their file is called (#579).
|
||||
#[test]
|
||||
|
||||
@@ -455,6 +455,8 @@ pub struct VectorcraftApp {
|
||||
/// The look for fonts installed or removed while the app was in the background, running
|
||||
/// ([`Self::refresh_installed_fonts`]): whether they were.
|
||||
font_check: Option<std::sync::mpsc::Receiver<bool>>,
|
||||
/// When installed fonts were last checked in line (app time, s).
|
||||
font_install_check_at: f64,
|
||||
/// Keyboard pastes of something other than text (see [`shortcuts::PasteChord`]).
|
||||
pub(crate) paste_chord: shortcuts::PasteChord,
|
||||
/// Saves and exports running in the background (Preferences → File Handling).
|
||||
@@ -500,6 +502,8 @@ struct PendingScreenshot {
|
||||
|
||||
/// Seconds between two looks at the system clipboard for [`VectorcraftApp::system_paste`].
|
||||
const SYSTEM_CLIPBOARD_POLL: f64 = 0.25;
|
||||
/// Seconds between looks for fonts a font manager activated while the app stays in front (#2576).
|
||||
const FONT_INSTALL_POLL: f64 = 2.0;
|
||||
|
||||
impl VectorcraftApp {
|
||||
pub fn new(mut session: Session, services: Services) -> Self {
|
||||
@@ -562,6 +566,7 @@ impl VectorcraftApp {
|
||||
picks: picks::Picks::default(),
|
||||
screen_sampler: None,
|
||||
font_check: None,
|
||||
font_install_check_at: f64::NEG_INFINITY,
|
||||
paste_chord: Default::default(),
|
||||
background: Default::default(),
|
||||
opening: Default::default(),
|
||||
@@ -1198,6 +1203,11 @@ impl VectorcraftApp {
|
||||
self.system_paste_at = now;
|
||||
self.system_paste = wanted && self.system_clipboard_pasteable();
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
if !(0.0..FONT_INSTALL_POLL).contains(&(now - self.font_install_check_at)) {
|
||||
self.font_install_check_at = now;
|
||||
self.refresh_installed_fonts();
|
||||
}
|
||||
self.poll_font_check(ctx);
|
||||
picks::poll(self, ctx);
|
||||
self.write_formats_before_text_input(ctx);
|
||||
@@ -1292,8 +1302,9 @@ impl VectorcraftApp {
|
||||
place::drop_files(self, files);
|
||||
}
|
||||
|
||||
/// Fonts installed or removed while the app was in the background are listed when it comes
|
||||
/// back (Refresh Font List by itself): a look at the font folders, a scan only when they changed.
|
||||
/// Fonts installed or removed while the app runs are listed without Refresh Font List: a look
|
||||
/// at the font folders and the platform's font list on a timer and when the window comes back,
|
||||
/// a scan only when they changed.
|
||||
/// The look runs on another thread (asking DirectWrite for the fonts font services loaded
|
||||
/// meanwhile takes tens of milliseconds on Windows, #579), [`Self::poll_font_check`] scans.
|
||||
fn refresh_installed_fonts(&mut self) {
|
||||
|
||||
Reference in New Issue
Block a user