From 8f10c42eaabf456be82aa519dbd8dcc42c936248 Mon Sep 17 00:00:00 2001 From: Sean McCleary Date: Sat, 11 Apr 2026 16:18:54 -0700 Subject: [PATCH] fix: skip wtype on GNOME Wayland for clipboard paste MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit wtype relies on the zwp_virtual_keyboard_manager_v1 Wayland protocol, which Mutter (GNOME) deliberately does not implement — the same reason wtype is already skipped on KDE. On GNOME Wayland, Handy's key-combo dispatch in try_send_key_combo_linux picked wtype first (because !is_kde_wayland() and wtype is typically installed), then propagated the wtype failure via `?`, preventing the cascade from falling through to dotool/ydotool. This broke the ctrl_v, ctrl_shift_v, and shift_insert paste methods entirely on GNOME Wayland. Add is_gnome() and is_gnome_wayland() helpers in utils.rs mirroring the existing KDE detection, and extend the wtype guards in try_send_key_combo_linux and try_direct_typing_linux to skip wtype on GNOME the same way they skip it on KDE. With this change, the cascade on GNOME Wayland falls through to dotool → ydotool, both of which work correctly since they bypass the virtual-keyboard protocol (dotool uses the RemoteDesktop portal; ydotool uses /dev/uinput). Verified locally on CachyOS + GNOME Wayland (Mutter): paste_method "ctrl_shift_v" now logs "Using ydotool for key combo" and pastes in ~120 ms, down from a hard wtype error. Co-Authored-By: Claude Opus 4.6 (1M context) --- src-tauri/src/clipboard.rs | 12 ++++++++---- src-tauri/src/utils.rs | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src-tauri/src/clipboard.rs b/src-tauri/src/clipboard.rs index 57972cb02..791ce2184 100644 --- a/src-tauri/src/clipboard.rs +++ b/src-tauri/src/clipboard.rs @@ -10,7 +10,7 @@ use tauri::{AppHandle, Manager}; use tauri_plugin_clipboard_manager::ClipboardExt; #[cfg(target_os = "linux")] -use crate::utils::{is_kde_wayland, is_wayland}; +use crate::utils::{is_gnome_wayland, is_kde_wayland, is_wayland}; /// Pastes text using the clipboard: saves current content, writes text, sends paste keystroke, restores clipboard. fn paste_via_clipboard( @@ -83,9 +83,11 @@ fn paste_via_clipboard( #[cfg(target_os = "linux")] fn try_send_key_combo_linux(paste_method: &PasteMethod) -> Result { if is_wayland() { - // Wayland: prefer wtype (but not on KDE), then dotool, then ydotool + // Wayland: prefer wtype (but not on KDE or GNOME), then dotool, then ydotool // Note: wtype doesn't work on KDE (no zwp_virtual_keyboard_manager_v1 support) - if !is_kde_wayland() && is_wtype_available() { + // or on GNOME/Mutter (same reason — Mutter deliberately does not implement + // the virtual-keyboard-v1 protocol). + if !is_kde_wayland() && !is_gnome_wayland() && is_wtype_available() { info!("Using wtype for key combo"); send_key_combo_via_wtype(paste_method)?; return Ok(true); @@ -166,7 +168,9 @@ fn try_direct_typing_linux(text: &str, preferred_tool: TypingTool) -> Result bool { pub fn is_kde_wayland() -> bool { is_wayland() && is_kde_plasma() } + +/// Check if running on GNOME desktop environment +#[cfg(target_os = "linux")] +pub fn is_gnome() -> bool { + std::env::var("XDG_CURRENT_DESKTOP") + .map(|v| v.to_uppercase().contains("GNOME")) + .unwrap_or(false) +} + +/// Check if running on GNOME with Wayland +#[cfg(target_os = "linux")] +pub fn is_gnome_wayland() -> bool { + is_wayland() && is_gnome() +}