diff --git a/desktop/src-tauri/src/system_settings.rs b/desktop/src-tauri/src/system_settings.rs index bb6e646..7d14869 100644 --- a/desktop/src-tauri/src/system_settings.rs +++ b/desktop/src-tauri/src/system_settings.rs @@ -613,15 +613,14 @@ pub fn ready(app: &AppHandle) { .logs .event("warn", "system_integrations_restore_failed", None); } - if enabled(&s, "start_minimal") { - if let Some(window) = app.get_webview_window("main") { - let _ = window.minimize(); - } - } + let start_minimal = enabled(&s, "start_minimal"); let remembered = enabled(&s, "remember_enable") .then(|| engine.store.library.selected.clone()) .flatten(); drop(guard); + if start_minimal { + crate::window_behavior::start_minimal(&app).await; + } if let Some(id) = remembered { if crate::connection_preflight::connect(&app, &id) .await diff --git a/desktop/src-tauri/src/window_behavior.rs b/desktop/src-tauri/src/window_behavior.rs index 9d9ee6d..7c84312 100644 --- a/desktop/src-tauri/src/window_behavior.rs +++ b/desktop/src-tauri/src/window_behavior.rs @@ -26,7 +26,7 @@ pub fn shown(app: &AppHandle) { /// Asks the session bus; blocking for up to 500 ms, so only `watch` calls it /// on a blocking thread. -fn host_available(app: &AppHandle) -> bool { +pub(crate) fn host_available(app: &AppHandle) -> bool { if app.state::().disabled.load(Ordering::SeqCst) { return false; } @@ -70,7 +70,7 @@ fn host_available(app: &AppHandle) -> bool { } } -fn background(app: &AppHandle, can_hide: bool) { +pub(crate) fn background(app: &AppHandle, can_hide: bool) { if let Some(window) = app.get_webview_window("main") { if can_hide && window.hide().is_ok() { app.state::().hidden.store(true, Ordering::SeqCst); @@ -169,3 +169,25 @@ pub fn toggle(app: &AppHandle) { crate::tray::show(app); } } + +/// Applies the "start minimized" setting: into the tray when a tray host shows +/// our indicator, otherwise minimized so the window stays reachable. Right +/// after login the tray host may register a moment later than an autostarted +/// application, so a tray that is expected is waited for briefly. +pub async fn start_minimal(app: &AppHandle) { + const ATTEMPTS: u32 = 5; + let mut can_hide = false; + for attempt in 1..=ATTEMPTS { + let handle = app.clone(); + can_hide = tauri::async_runtime::spawn_blocking(move || host_available(&handle)) + .await + .unwrap_or(false); + let tray_expected = !app.state::().disabled.load(Ordering::SeqCst) + && app.tray_by_id("thronium").is_some(); + if can_hide || !tray_expected || attempt == ATTEMPTS { + break; + } + tokio::time::sleep(std::time::Duration::from_secs(1)).await; + } + background(app, can_hide); +}