From 9298a0cc936288564239e48b033a9f5f47167466 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Sat, 20 Jun 2026 22:10:42 +0800 Subject: [PATCH] fix(linux): keep native window decorations --- .../src/composables/useWindowControls.ts | 4 +-- apps/desktop/src/lib/platform.ts | 4 +++ src-tauri/src/lib.rs | 31 +++++++++++++++++-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/apps/desktop/src/composables/useWindowControls.ts b/apps/desktop/src/composables/useWindowControls.ts index 94e311151..abc478c58 100644 --- a/apps/desktop/src/composables/useWindowControls.ts +++ b/apps/desktop/src/composables/useWindowControls.ts @@ -1,6 +1,6 @@ import { ref, onMounted, onUnmounted } from "vue"; import { isTauriRuntime } from "@/lib/tauriRuntime"; -import { isMacOS } from "@/lib/platform"; +import { isMacOS, isWindows } from "@/lib/platform"; export function shouldReserveMacTrafficLightInset(isMac: boolean, isFullscreen: boolean, isDesktop = true): boolean { return isDesktop && isMac && !isFullscreen; @@ -11,7 +11,7 @@ export function useWindowControls() { const isFullscreen = ref(false); const isMac = isMacOS(); const isDesktop = isTauriRuntime(); - const showControls = isDesktop && !isMac; + const showControls = isDesktop && isWindows(); let unlisten: (() => void) | null = null; diff --git a/apps/desktop/src/lib/platform.ts b/apps/desktop/src/lib/platform.ts index bb1e70846..4a50009c5 100644 --- a/apps/desktop/src/lib/platform.ts +++ b/apps/desktop/src/lib/platform.ts @@ -11,3 +11,7 @@ export function getPlatform(): Platform { export function isMacOS(): boolean { return getPlatform() === "macos"; } + +export function isWindows(): boolean { + return getPlatform() === "windows"; +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index f1601f480..46f2b2c1a 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -38,6 +38,20 @@ fn should_show_main_window_after_setup() -> bool { true } +fn should_disable_native_window_decorations(target_os: &str) -> bool { + matches!(target_os, "windows") +} + +#[cfg(target_os = "linux")] +fn apply_linux_webkit_rendering_workarounds() { + const DISABLE_DMABUF_RENDERER: &str = "WEBKIT_DISABLE_DMABUF_RENDERER"; + if std::env::var_os(DISABLE_DMABUF_RENDERER).is_none() { + // WebKitGTK's DMABUF renderer can produce a blank AppImage window on + // Fedora/Wayland/NVIDIA systems. This must be set before WebKit starts. + std::env::set_var(DISABLE_DMABUF_RENDERER, "1"); + } +} + fn show_main_window(app: &tauri::AppHandle) { if let Some(window) = app.get_webview_window("main") { let _ = window.show(); @@ -172,7 +186,10 @@ pub(crate) fn apply_desktop_settings(app: &tauri::AppHandle, desktop_settings: & #[cfg(test)] #[allow(clippy::items_after_test_module)] mod tests { - use super::{should_hide_window_on_close, should_setup_desktop_tray, should_show_main_window_after_setup}; + use super::{ + should_disable_native_window_decorations, should_hide_window_on_close, should_setup_desktop_tray, + should_show_main_window_after_setup, + }; #[test] fn hides_window_on_close_for_windows_and_macos() { @@ -198,11 +215,20 @@ mod tests { fn shows_main_window_after_regular_startup_setup() { assert!(should_show_main_window_after_setup()); } + + #[test] + fn disables_native_window_decorations_only_on_windows() { + assert!(should_disable_native_window_decorations("windows")); + assert!(!should_disable_native_window_decorations("linux")); + assert!(!should_disable_native_window_decorations("macos")); + } } #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { rustls::crypto::aws_lc_rs::default_provider().install_default().expect("Failed to install rustls crypto provider"); + #[cfg(target_os = "linux")] + apply_linux_webkit_rendering_workarounds(); let startup_begin = Instant::now(); @@ -297,8 +323,7 @@ pub fn run() { commands::mcp_bridge::start(app_handle, state); eprintln!("[STARTUP] setup complete in {:?} (total {:?})", setup_start.elapsed(), startup_begin.elapsed()); - #[cfg(not(target_os = "macos"))] - { + if should_disable_native_window_decorations(std::env::consts::OS) { if let Some(window) = app.get_webview_window("main") { let _ = window.set_decorations(false); }