From 4d0b1c865c5be0f564bafd12d1c9513f0b7c3250 Mon Sep 17 00:00:00 2001 From: Hunter B Date: Thu, 17 Sep 2026 04:44:28 -0700 Subject: [PATCH] ios: let the host install an app-provided asset source run_app builds the Application with the unit asset source, so every kit Icon paints a blank slot, and there is no post-run setter. set_app_assets registers an Arc before run_app and the runner installs it via with_assets, keeping the runner decoupled from any bundle the app might choose. --- src/ios/ffi.rs | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/ios/ffi.rs b/src/ios/ffi.rs index 5b0c892..6aa9836 100644 --- a/src/ios/ffi.rs +++ b/src/ios/ffi.rs @@ -509,6 +509,30 @@ pub fn set_app_callback(cb: Box) { } } +// An app-provided asset source for `run_app`: without one the Application +// is built with the unit asset source, so every kit `Icon` paints a blank +// slot. Main thread only, like the app callback; a second call keeps the +// first source. +static APP_ASSETS: OnceLock> = OnceLock::new(); + +/// Register the asset source `run_app` installs via `with_assets`. Call this +/// before `run_app`, alongside [`set_app_callback`]. +pub fn set_app_assets(source: std::sync::Arc) { + let _ = APP_ASSETS.set(source); +} + +struct AppAssets(std::sync::Arc); + +impl gpui::AssetSource for AppAssets { + fn load(&self, path: &str) -> gpui::Result>> { + self.0.load(path) + } + + fn list(&self, path: &str) -> gpui::Result> { + self.0.list(path) + } +} + #[allow(clippy::type_complexity)] fn take_app_callback() -> Option> { APP_CALLBACK @@ -545,7 +569,14 @@ pub fn run_app() { } let platform = Rc::new(super::IosPlatform::new()); - let application = Application::with_platform(platform).run_embedded(|cx: &mut App| { + // Install the app-provided asset source when one was registered; + // without it kit icons paint blank. + let application = Application::with_platform(platform); + let application = match APP_ASSETS.get() { + Some(source) => application.with_assets(AppAssets(source.clone())), + None => application, + }; + let application = application.run_embedded(|cx: &mut App| { if let Some(cb) = take_app_callback() { log::info!("GPUI iOS: Invoking user-provided app callback"); cb(cx);