diff --git a/Client/tauri-client/src-tauri/src/main.rs b/Client/tauri-client/src-tauri/src/main.rs index a427a3ef..c2e04c93 100644 --- a/Client/tauri-client/src-tauri/src/main.rs +++ b/Client/tauri-client/src-tauri/src/main.rs @@ -2,5 +2,16 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] fn main() { + // WebKitGTK's DMABUF renderer is known to crash or produce a blank window + // under Wayland (notably on NVIDIA). Disable it on Wayland sessions unless + // the user has already set the variable themselves (any value wins). + #[cfg(target_os = "linux")] + { + let is_wayland = std::env::var_os("WAYLAND_DISPLAY").is_some() + || std::env::var("XDG_SESSION_TYPE").is_ok_and(|v| v.eq_ignore_ascii_case("wayland")); + if is_wayland && std::env::var_os("WEBKIT_DISABLE_DMABUF_RENDERER").is_none() { + std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1"); + } + } owncord_client_lib::run() } diff --git a/Client/tauri-client/src-tauri/src/ptt.rs b/Client/tauri-client/src-tauri/src/ptt.rs index 44283dfd..e0f8ba9d 100644 --- a/Client/tauri-client/src-tauri/src/ptt.rs +++ b/Client/tauri-client/src-tauri/src/ptt.rs @@ -82,13 +82,24 @@ fn is_key_down(vk: i32) -> bool { use device_query::{DeviceQuery, DeviceState}; // Cache DeviceState per thread — creating it on every call would open/close // /dev/input/ file descriptors every 20ms in the polling loop. + // checked_new() returns None when no X11 display is reachable (e.g. a + // pure-Wayland session without XWayland), so PTT degrades to "key never + // pressed" instead of panicking on every poll. thread_local! { - static DEVICE_STATE: DeviceState = DeviceState::new(); + static DEVICE_STATE: Option = { + let ds = DeviceState::checked_new(); + if ds.is_none() { + log::warn!( + "PTT unavailable: no X11/XWayland display for global key state" + ); + } + ds + }; } let Some(keycode) = linux::vk_to_keycode(vk) else { return false; }; - DEVICE_STATE.with(|ds| ds.get_keys().contains(&keycode)) + DEVICE_STATE.with(|ds| ds.as_ref().is_some_and(|ds| ds.get_keys().contains(&keycode))) } #[cfg(not(any(windows, target_os = "linux")))] @@ -400,7 +411,10 @@ pub async fn ptt_listen_for_key() -> i32 { #[cfg(target_os = "linux")] { use device_query::{DeviceQuery, DeviceState}; - let device_state = DeviceState::new(); + let Some(device_state) = DeviceState::checked_new() else { + log::warn!("PTT key capture unavailable: no X11/XWayland display"); + return 0; + }; let deadline = std::time::Instant::now() + Duration::from_secs(10); while std::time::Instant::now() < deadline { diff --git a/docs/quick-start.md b/docs/quick-start.md index 1f1e8590..b80e335d 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -78,6 +78,9 @@ npm run tauri build - The desktop client uses TOFU certificate pinning: - First connection prompts for trust. - Future connections require the same cert fingerprint. +- Linux/Wayland: the client automatically sets `WEBKIT_DISABLE_DMABUF_RENDERER=1` + on Wayland sessions to work around WebKitGTK rendering crashes. Export the + variable yourself (any value) before launching to override this. ## If Remote Users Cannot Connect