Blob Blame History Raw
From 77879bdd0fd2ff082804ba109abdfd90efa92d99 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Thu, 25 Apr 2024 23:56:27 +0200
Subject: [PATCH] wayland: Do not forget immediately of key press serials on
 key release

Prior to commit 5dfed8a431, the MetaWaylandKeyboard would always remember
the last key press serial, and consider it valid after the key was released,
as long as no other key presses/releases happened in between.

That commit improved things so that MetaWaylandKeyboard can track multiple
keys being pressed simultaneously, but also changed so that the serial for
a key press is immediately forgotten after the key press event was received.
This may break in situations like testing or keyboard macros where key
press and release is handled in a quick sucession, so the client reaction
to the key press (e.g. popping up a menu) might arrive too late.

Add a sort of spiritual successor to this handling, and make keyboard
press serials corresponding to the last key up forgotten at the next
key press/release received.

Fixes: 5dfed8a431 ("wayland: Preserve serial for all pressed keys")
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3458
---
 src/wayland/meta-wayland-keyboard.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c
index 80c772aec7..3c741a0ae0 100644
--- a/src/wayland/meta-wayland-keyboard.c
+++ b/src/wayland/meta-wayland-keyboard.c
@@ -77,6 +77,7 @@ struct _MetaWaylandKeyboard
   struct wl_array pressed_keys;
   GHashTable *key_down_serials;
   uint32_t last_key_up_serial;
+  uint32_t last_key_up;
 
   MetaWaylandXkbInfo xkb_info;
   enum xkb_state_component mods_changed;
@@ -279,6 +280,13 @@ meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard,
 
       serial = meta_wayland_input_device_next_serial (input_device);
 
+      if (keyboard->last_key_up)
+        {
+          g_hash_table_remove (keyboard->key_down_serials,
+                               GUINT_TO_POINTER (keyboard->last_key_up));
+          keyboard->last_key_up = 0;
+        }
+
       if (state)
         {
           g_hash_table_insert (keyboard->key_down_serials,
@@ -288,9 +296,8 @@ meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard,
         }
       else
         {
-          g_hash_table_remove (keyboard->key_down_serials,
-                               GUINT_TO_POINTER (key));
           keyboard->last_key_up_serial = serial;
+          keyboard->last_key_up = key;
         }
 
       wl_resource_for_each (resource, &keyboard->focus_resource_list)
-- 
GitLab