diff --git a/crates/gpui_linux/src/linux/wayland/client.rs b/crates/gpui_linux/src/linux/wayland/client.rs index 00b0508e19..6a7c4c76e4 100644 --- a/crates/gpui_linux/src/linux/wayland/client.rs +++ b/crates/gpui_linux/src/linux/wayland/client.rs @@ -951,9 +951,7 @@ impl LinuxClient for WaylandClient { }; if state.mouse_focused_window.is_some() || state.keyboard_focused_window.is_some() { state.clipboard.set_primary(item); - let serial = state - .serial_tracker - .latest_of(&[SerialKind::KeyPress, SerialKind::MousePress]); + let serial = state.serial_tracker.get_latest(); let data_source = primary_selection_manager.create_source(&state.globals.qh, ()); for mime_type in TEXT_MIME_TYPES { data_source.offer(mime_type.to_string()); @@ -973,9 +971,7 @@ impl LinuxClient for WaylandClient { }; if state.mouse_focused_window.is_some() || state.keyboard_focused_window.is_some() { state.clipboard.set(item); - let serial = state - .serial_tracker - .latest_of(&[SerialKind::KeyPress, SerialKind::MousePress]); + let serial = state.serial_tracker.get_latest(); let data_source = data_device_manager.create_data_source(&state.globals.qh, ()); for mime_type in TEXT_MIME_TYPES { data_source.offer(mime_type.to_string()); diff --git a/crates/gpui_linux/src/linux/wayland/serial.rs b/crates/gpui_linux/src/linux/wayland/serial.rs index ed38f14bd1..ffb405727b 100644 --- a/crates/gpui_linux/src/linux/wayland/serial.rs +++ b/crates/gpui_linux/src/linux/wayland/serial.rs @@ -47,15 +47,21 @@ impl SerialTracker { .unwrap_or(0) } - /// Returns the latest tracked serial of the provided [`SerialKind`]s + /// Returns the most recent serial across all tracked kinds. /// - /// Will return 0 if not tracked. - pub fn latest_of(&self, kinds: &[SerialKind]) -> u32 { - kinds - .iter() - .filter_map(|kind| self.serials.get(kind)) - .max_by_key(|serial_data| serial_data.serial) + /// Wayland compositor serial numbers are monotonically increasing, so the + /// highest value is always the most recently received one. This is the + /// correct serial to use for [`set_selection`] when the triggering event + /// may have been a mouse press rather than a key press: using 0 (the + /// default when a kind has never been seen) causes compositors to silently + /// reject the request. + /// + /// Returns 0 only if no serial of any kind has been received yet. + pub fn get_latest(&self) -> u32 { + self.serials + .values() .map(|serial_data| serial_data.serial) + .max() .unwrap_or(0) } }