summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ådahl <jadahl@gmail.com>2018-07-25 16:18:36 +0200
committerJonas Ådahl <jadahl@gmail.com>2018-08-15 08:51:14 +0000
commit2dbacfa8d6a520a8099d4c153124497397bea1ee (patch)
tree1fead7873a51c2f55a70a49f303fb33f85fdab31
parent85e5b160ee7dbeec474c3f6877ddbd5310f0fbe8 (diff)
downloadmutter-2dbacfa8d6a520a8099d4c153124497397bea1ee.tar.gz
wayland/keyboard: Accept key down serial after key up for popups
If a client maps a popup in response to a key-down event, but the mapping doesn't occur until after the user has already released the same button, we'd immediately dismiss the popup. This is problematic, as one often presses and releases a key quite quickly, meaning any popup mapped on key-down are likely to be dismissed. Avoid this race condition by accepting serials for key down events, if the most recent key-up event had the same keycode. https://gitlab.gnome.org/GNOME/mutter/merge_requests/180
-rw-r--r--src/wayland/meta-wayland-keyboard.c21
-rw-r--r--src/wayland/meta-wayland-keyboard.h7
2 files changed, 22 insertions, 6 deletions
diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c
index d4ae4508d..7ad14c88a 100644
--- a/src/wayland/meta-wayland-keyboard.c
+++ b/src/wayland/meta-wayland-keyboard.c
@@ -298,14 +298,23 @@ meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard,
{
MetaWaylandInputDevice *input_device =
META_WAYLAND_INPUT_DEVICE (keyboard);
+ uint32_t serial;
- keyboard->key_serial =
- meta_wayland_input_device_next_serial (input_device);
+ serial = meta_wayland_input_device_next_serial (input_device);
- wl_resource_for_each (resource, &keyboard->focus_resource_list)
+ if (state)
+ {
+ keyboard->key_down_serial = serial;
+ keyboard->key_down_keycode = key;
+ }
+ else
{
- wl_keyboard_send_key (resource, keyboard->key_serial, time, key, state);
+ keyboard->key_up_serial = serial;
+ keyboard->key_up_keycode = key;
}
+
+ wl_resource_for_each (resource, &keyboard->focus_resource_list)
+ wl_keyboard_send_key (resource, serial, time, key, state);
}
/* Eat the key events if we have a focused surface. */
@@ -1026,7 +1035,9 @@ gboolean
meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard,
uint32_t serial)
{
- return keyboard->key_serial == serial;
+ return (keyboard->key_down_serial == serial ||
+ ((keyboard->key_down_keycode == keyboard->key_up_keycode) &&
+ keyboard->key_up_serial == serial));
}
void
diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h
index 39f06ef17..88899712d 100644
--- a/src/wayland/meta-wayland-keyboard.h
+++ b/src/wayland/meta-wayland-keyboard.h
@@ -89,7 +89,12 @@ struct _MetaWaylandKeyboard
MetaWaylandSurface *focus_surface;
struct wl_listener focus_surface_listener;
uint32_t focus_serial;
- uint32_t key_serial;
+
+ uint32_t key_down_keycode;
+ uint32_t key_down_serial;
+
+ uint32_t key_up_keycode;
+ uint32_t key_up_serial;
MetaWaylandXkbInfo xkb_info;
enum xkb_state_component mods_changed;