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
This commit is contained in:
parent
85e5b160ee
commit
2dbacfa8d6
2 changed files with 23 additions and 7 deletions
|
@ -298,14 +298,23 @@ meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard,
|
||||||
{
|
{
|
||||||
MetaWaylandInputDevice *input_device =
|
MetaWaylandInputDevice *input_device =
|
||||||
META_WAYLAND_INPUT_DEVICE (keyboard);
|
META_WAYLAND_INPUT_DEVICE (keyboard);
|
||||||
|
uint32_t serial;
|
||||||
|
|
||||||
keyboard->key_serial =
|
serial = meta_wayland_input_device_next_serial (input_device);
|
||||||
meta_wayland_input_device_next_serial (input_device);
|
|
||||||
|
if (state)
|
||||||
|
{
|
||||||
|
keyboard->key_down_serial = serial;
|
||||||
|
keyboard->key_down_keycode = key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keyboard->key_up_serial = serial;
|
||||||
|
keyboard->key_up_keycode = key;
|
||||||
|
}
|
||||||
|
|
||||||
wl_resource_for_each (resource, &keyboard->focus_resource_list)
|
wl_resource_for_each (resource, &keyboard->focus_resource_list)
|
||||||
{
|
wl_keyboard_send_key (resource, serial, time, key, state);
|
||||||
wl_keyboard_send_key (resource, keyboard->key_serial, time, key, state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Eat the key events if we have a focused surface. */
|
/* Eat the key events if we have a focused surface. */
|
||||||
|
@ -1026,7 +1035,9 @@ gboolean
|
||||||
meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard,
|
meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard,
|
||||||
uint32_t serial)
|
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
|
void
|
||||||
|
|
|
@ -89,7 +89,12 @@ struct _MetaWaylandKeyboard
|
||||||
MetaWaylandSurface *focus_surface;
|
MetaWaylandSurface *focus_surface;
|
||||||
struct wl_listener focus_surface_listener;
|
struct wl_listener focus_surface_listener;
|
||||||
uint32_t focus_serial;
|
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;
|
MetaWaylandXkbInfo xkb_info;
|
||||||
enum xkb_state_component mods_changed;
|
enum xkb_state_component mods_changed;
|
||||||
|
|
Loading…
Reference in a new issue