diff --git a/src-tauri/src/app_runtime.rs b/src-tauri/src/app_runtime.rs index 0894b5c3..3d35179e 100644 --- a/src-tauri/src/app_runtime.rs +++ b/src-tauri/src/app_runtime.rs @@ -5,9 +5,23 @@ use tauri::{ #[cfg(target_os = "linux")] mod linux_webkit_workaround { + const APPIMAGE_ENV: &str = "APPIMAGE"; + const APPDIR_ENV: &str = "APPDIR"; + const GDK_BACKEND_ENV: &str = "GDK_BACKEND"; const WEBKIT_DISABLE_DMABUF_RENDERER_ENV: &str = "WEBKIT_DISABLE_DMABUF_RENDERER"; const WAYLAND_DISPLAY_ENV: &str = "WAYLAND_DISPLAY"; + fn should_set_gdk_backend_env( + existing_value: Option<&std::ffi::OsStr>, + wayland_display: Option<&std::ffi::OsStr>, + appimage: Option<&std::ffi::OsStr>, + appdir: Option<&std::ffi::OsStr>, + ) -> bool { + existing_value.is_none() + && wayland_display.is_some() + && (appimage.is_some() || appdir.is_some()) + } + fn should_set_webkit_dmabuf_renderer_env( existing_value: Option<&std::ffi::OsStr>, wayland_display: Option<&std::ffi::OsStr>, @@ -16,6 +30,18 @@ mod linux_webkit_workaround { } pub(super) fn configure(log: impl Fn(&str)) { + if should_set_gdk_backend_env( + std::env::var_os(GDK_BACKEND_ENV).as_deref(), + std::env::var_os(WAYLAND_DISPLAY_ENV).as_deref(), + std::env::var_os(APPIMAGE_ENV).as_deref(), + std::env::var_os(APPDIR_ENV).as_deref(), + ) { + std::env::set_var(GDK_BACKEND_ENV, "x11"); + log(&format!( + "applied Linux AppImage WebKit workaround: set {GDK_BACKEND_ENV}=x11" + )); + } + if should_set_webkit_dmabuf_renderer_env( std::env::var_os(WEBKIT_DISABLE_DMABUF_RENDERER_ENV).as_deref(), std::env::var_os(WAYLAND_DISPLAY_ENV).as_deref(), @@ -29,7 +55,41 @@ mod linux_webkit_workaround { #[cfg(test)] mod tests { - use super::should_set_webkit_dmabuf_renderer_env; + use super::{should_set_gdk_backend_env, should_set_webkit_dmabuf_renderer_env}; + + #[test] + fn appimage_wayland_workaround_uses_x11_unless_overridden() { + assert!(should_set_gdk_backend_env( + None, + Some(std::ffi::OsStr::new("wayland-0")), + Some(std::ffi::OsStr::new("/tmp/.mount_AstrBot/AppRun")), + None + )); + assert!(should_set_gdk_backend_env( + None, + Some(std::ffi::OsStr::new("wayland-0")), + None, + Some(std::ffi::OsStr::new("/tmp/.mount_AstrBot")) + )); + assert!(!should_set_gdk_backend_env( + Some(std::ffi::OsStr::new("wayland")), + Some(std::ffi::OsStr::new("wayland-0")), + Some(std::ffi::OsStr::new("/tmp/.mount_AstrBot/AppRun")), + None + )); + assert!(!should_set_gdk_backend_env( + None, + None, + Some(std::ffi::OsStr::new("/tmp/.mount_AstrBot/AppRun")), + None + )); + assert!(!should_set_gdk_backend_env( + None, + Some(std::ffi::OsStr::new("wayland-0")), + None, + None + )); + } #[test] fn webkit_dmabuf_workaround_is_set_only_for_wayland_without_override() { @@ -225,10 +285,12 @@ fn handle_run_event(app_handle: &tauri::AppHandle, event: RunEvent) { } } -pub(crate) fn run() { - #[cfg(target_os = "linux")] +#[cfg(target_os = "linux")] +pub(crate) fn configure_linux_webkit_workaround() { linux_webkit_workaround::configure(append_startup_log); +} +pub(crate) fn run() { append_startup_log("desktop process starting"); append_startup_log(&format!( "desktop log path: {}", diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 4e90c999..15cc5b4b 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -45,5 +45,8 @@ pub(crate) use app_types::{ pub(crate) use desktop_settings::DesktopSettingsCache; fn main() { + #[cfg(target_os = "linux")] + app_runtime::configure_linux_webkit_workaround(); + app_runtime::run(); }