Use the most recent serial of kinds KeyPress or MousePress when copying (#52053)

Matthew Chisolm created

Release Notes:

- Fix copy for some Wayland users

Change summary

crates/gpui_linux/src/linux/wayland/client.rs |  8 ++++++--
crates/gpui_linux/src/linux/wayland/serial.rs | 12 ++++++++++++
2 files changed, 18 insertions(+), 2 deletions(-)

Detailed changes

crates/gpui_linux/src/linux/wayland/client.rs 🔗

@@ -875,7 +875,9 @@ 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.get(SerialKind::KeyPress);
+            let serial = state
+                .serial_tracker
+                .latest_of(&[SerialKind::KeyPress, SerialKind::MousePress]);
             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());
@@ -895,7 +897,9 @@ 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.get(SerialKind::KeyPress);
+            let serial = state
+                .serial_tracker
+                .latest_of(&[SerialKind::KeyPress, SerialKind::MousePress]);
             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());

crates/gpui_linux/src/linux/wayland/serial.rs 🔗

@@ -46,4 +46,16 @@ impl SerialTracker {
             .map(|serial_data| serial_data.serial)
             .unwrap_or(0)
     }
+
+    /// Returns the latest tracked serial of the provided [`SerialKind`]s
+    ///
+    /// 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)
+            .map(|serial_data| serial_data.serial)
+            .unwrap_or(0)
+    }
 }