From 6087b8b8e8c992c57301895b421336ce49d39eee Mon Sep 17 00:00:00 2001 From: thomas Date: Sat, 31 Oct 2026 21:58:20 +0800 Subject: [PATCH] fix(windows): match the native window theme to the app theme The native outline and shadow followed the OS appearance, so a light app theme in OS dark mode drew a dark border around project and settings windows. Co-Authored-By: Claude Sonnet 5.5 --- src-tauri/src/windows.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/windows.rs b/src-tauri/src/windows.rs index 9a6b29267..5f882e3e8 100644 --- a/src-tauri/src/windows.rs +++ b/src-tauri/src/windows.rs @@ -297,15 +297,27 @@ fn build_project_window(app: &AppHandle, mut config: WindowConfig) -> IdeResult< .and_then(|b| b.build()) .map_err(|e| IdeError::internal(format!("cannot create window: {e}")))?; apply_zoom(app, &window); + match_native_theme(&window, config.background_color); // "Sync with OS" needs the OS mode, known once the window exists. if let Some(a) = appearance.filter(|a| plugin_frame.is_none() && (a.sync_with_os || a.theme == "system")) && window.theme().is_ok_and(|t| t == Theme::Dark) { - let _ = window.set_background_color(Some(frame_color(&a, true))); + let color = frame_color(&a, true); + let _ = window.set_background_color(Some(color)); + match_native_theme(&window, Some(color)); } Ok(window) } +/// Pins the native window appearance (outline, shadow, traffic lights) to the light/dark +/// of the app's frame colour; otherwise it follows the OS, so a light app theme in OS dark +/// mode gets a dark window border. +fn match_native_theme(window: &WebviewWindow, frame: Option) { + let Some(Color(r, g, b, _)) = frame else { return }; + let luma = 0.299 * f64::from(r) + 0.587 * f64::from(g) + 0.114 * f64::from(b); + let _ = window.set_theme(Some(if luma < 128.0 { Theme::Dark } else { Theme::Light })); +} + /// Sets the saved IDE zoom before the page loads; applied later by the frontend, /// it would visibly scale up the splash. fn apply_zoom(app: &AppHandle, window: &WebviewWindow) { @@ -747,6 +759,7 @@ pub fn open_settings_window( .and_then(|b| b.build()) .map_err(|e| IdeError::internal(format!("cannot create settings window: {e}")))?; apply_zoom(app, &window); + match_native_theme(&window, config.background_color); // Restore runs during build; fit its size to the parent's current display before showing. #[cfg(target_os = "macos")] if let Err(e) = fit_settings_window(&window, &parent) {