diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 0d9cbe7..3d823f8 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -411,7 +411,19 @@ pub fn run() { native::toast::show_rich_toast, ]) .plugin(tauri_plugin_localhost::Builder::new(port).build()) - .plugin(tauri_plugin_window_state::Builder::default().build()) + .plugin( + // DECORATIONS is excluded: the custom-chrome toggle (set_custom_chrome) + // owns the decorated flag. Letting window-state restore a saved + // decorated=false at startup would re-create the frameless window + // BEFORE lib.rs applies Mica (a broken combination) and before the web + // side has pushed the user's current setting. + tauri_plugin_window_state::Builder::default() + .with_state_flags( + tauri_plugin_window_state::StateFlags::all() + & !tauri_plugin_window_state::StateFlags::DECORATIONS, + ) + .build(), + ) .plugin(tauri_plugin_opener::init()) .plugin(tauri_plugin_notification::init()) .plugin(tauri_plugin_deep_link::init()); diff --git a/src-tauri/src/native/chrome.rs b/src-tauri/src/native/chrome.rs index 2a80cc5..72990bf 100644 --- a/src-tauri/src/native/chrome.rs +++ b/src-tauri/src/native/chrome.rs @@ -6,11 +6,12 @@ //! `decorations(true)` and only `set_custom_chrome(true)` makes it frameless, so //! the safe default is the untouched native frame. //! -//! Everything here goes through the cross-platform Tauri v2 window API — there is -//! no `windows` crate dependency, so the same code path runs on Windows, macOS -//! and Linux. Each command resolves the "main" window and silently no-ops if it -//! isn't present (e.g. during teardown); the `Result`s are intentionally ignored -//! since a failed chrome tweak should never surface as an error to the user. +//! Everything here goes through the cross-platform Tauri v2 window API (plus a +//! Windows-only `window_vibrancy` dance in `set_custom_chrome`, since Mica and a +//! frameless window can't coexist). Each command resolves the "main" window and +//! silently no-ops if it isn't present (e.g. during teardown); the `Result`s are +//! intentionally ignored since a failed chrome tweak should never surface as an +//! error to the user. use tauri::{AppHandle, Manager}; @@ -21,7 +22,23 @@ use tauri::{AppHandle, Manager}; #[tauri::command] pub fn set_custom_chrome(app: AppHandle, enabled: bool) { if let Some(window) = app.get_webview_window("main") { + // Windows: the Mica backdrop (applied at startup in lib.rs) and a + // frameless window are a known-bad combo — stripping WS_CAPTION under a + // system backdrop glitches the whole surface (black/blank window). Drop + // the backdrop before undecorating, and restore it together with the + // native frame when custom chrome turns off. + #[cfg(target_os = "windows")] + if enabled { + let _ = window_vibrancy::clear_mica(&window); + } let _ = window.set_decorations(!enabled); + // Re-assert the DWM shadow so a frameless window keeps its drop shadow + // and resize borders on Windows (no-op / harmless elsewhere). + let _ = window.set_shadow(true); + #[cfg(target_os = "windows")] + if !enabled { + let _ = window_vibrancy::apply_mica(&window, Some(true)); + } } }