wayland: Use keyboard serial for implicit grab
An xdg-popup requires a serial that the compositor will compare against its own serial and will dismiss the popup if it doesn't match. gtk+ uses either a pointer or touch serial for its helper function _gdk_wayland_seat_get_last_implicit_grab_serial() but if the menu is triggered before the user has had any pointer or touch interaction with the client, using a keyboard shortcut, there is neither pointer nor touch serial available, and gtk+ will use 0 as the default. As a result, the compositor will instantly dismiss the xdg-popup. In this case, gtk+ should use the keyboard serial instead. Track keyboard serial as well and use the keyboard serial as the value if there is no newer pointer or touch serial available. https://bugzilla.gnome.org/show_bug.cgi?id=768017
This commit is contained in:

committed by
Matthias Clasen

parent
967e2e0cd3
commit
f9b91197c0
@ -184,6 +184,7 @@ struct _GdkWaylandSeat
|
|||||||
gint64 repeat_deadline;
|
gint64 repeat_deadline;
|
||||||
GSettings *keyboard_settings;
|
GSettings *keyboard_settings;
|
||||||
uint32_t keyboard_time;
|
uint32_t keyboard_time;
|
||||||
|
uint32_t keyboard_key_serial;
|
||||||
|
|
||||||
struct gtk_primary_selection_device *primary_data_device;
|
struct gtk_primary_selection_device *primary_data_device;
|
||||||
struct wl_data_device *data_device;
|
struct wl_data_device *data_device;
|
||||||
@ -1992,6 +1993,7 @@ keyboard_handle_key (void *data,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
seat->keyboard_time = time;
|
seat->keyboard_time = time;
|
||||||
|
seat->keyboard_key_serial = serial;
|
||||||
seat->repeat_count = 0;
|
seat->repeat_count = 0;
|
||||||
_gdk_wayland_display_update_serial (display, serial);
|
_gdk_wayland_display_update_serial (display, serial);
|
||||||
deliver_key_event (data, time, key + 8, state_w);
|
deliver_key_event (data, time, key + 8, state_w);
|
||||||
@ -4336,7 +4338,7 @@ _gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat *seat,
|
|||||||
GdkWaylandSeat *wayland_seat;
|
GdkWaylandSeat *wayland_seat;
|
||||||
GdkWaylandTouchData *touch;
|
GdkWaylandTouchData *touch;
|
||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
uint32_t serial = 0;
|
uint32_t serial;
|
||||||
|
|
||||||
wayland_seat = GDK_WAYLAND_SEAT (seat);
|
wayland_seat = GDK_WAYLAND_SEAT (seat);
|
||||||
g_hash_table_iter_init (&iter, wayland_seat->touches);
|
g_hash_table_iter_init (&iter, wayland_seat->touches);
|
||||||
@ -4344,6 +4346,8 @@ _gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat *seat,
|
|||||||
if (sequence)
|
if (sequence)
|
||||||
*sequence = NULL;
|
*sequence = NULL;
|
||||||
|
|
||||||
|
serial = wayland_seat->keyboard_key_serial;
|
||||||
|
|
||||||
if (wayland_seat->pointer_info.press_serial > serial)
|
if (wayland_seat->pointer_info.press_serial > serial)
|
||||||
serial = wayland_seat->pointer_info.press_serial;
|
serial = wayland_seat->pointer_info.press_serial;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user