wayland: Set weak reference on the current grab window

If the grab window is destroyed the grab will be implicitly removed,
although we won't get GdkSeat:ungrab called in order to clear our
internal window<->seat relation entirely. Setting a weak ref will
nullify the pointer we keep on the seat to the window, avoiding the
expected crashes.
This commit is contained in:
Carlos Garnacho 2016-01-18 14:05:00 +01:00
parent be3f0dad82
commit 5b1d96234d

View File

@ -2614,6 +2614,27 @@ gdk_wayland_seat_get_capabilities (GdkSeat *seat)
return caps;
}
static void
gdk_wayland_seat_set_grab_window (GdkWaylandSeat *seat,
GdkWindow *window)
{
if (seat->pointer_grab_window)
{
_gdk_wayland_window_set_grab_seat (seat->pointer_grab_window, NULL);
g_object_remove_weak_pointer (G_OBJECT (seat->pointer_grab_window),
(gpointer *) &seat->pointer_grab_window);
seat->pointer_grab_window = NULL;
}
if (window)
{
seat->pointer_grab_window = window;
g_object_add_weak_pointer (G_OBJECT (window),
(gpointer *) &seat->pointer_grab_window);
_gdk_wayland_window_set_grab_seat (window, GDK_SEAT (seat));
}
}
static GdkGrabStatus
gdk_wayland_seat_grab (GdkSeat *seat,
GdkWindow *window,
@ -2646,16 +2667,15 @@ gdk_wayland_seat_grab (GdkSeat *seat,
if (native == NULL || GDK_WINDOW_DESTROYED (native))
return GDK_GRAB_NOT_VIEWABLE;
wayland_seat->pointer_grab_window = window;
gdk_wayland_seat_set_grab_window (wayland_seat, window);
wayland_seat->pointer_grab_time = evtime;
_gdk_wayland_window_set_grab_seat (window, seat);
if (prepare_func)
(prepare_func) (seat, window, prepare_func_data);
if (!gdk_window_is_visible (window))
{
_gdk_wayland_window_set_grab_seat (window, NULL);
gdk_wayland_seat_set_grab_window (wayland_seat, NULL);
g_critical ("Window %p has not been made visible in GdkSeatGrabPrepareFunc",
window);
return GDK_GRAB_NOT_VIEWABLE;
@ -2740,12 +2760,7 @@ gdk_wayland_seat_ungrab (GdkSeat *seat)
g_clear_object (&wayland_seat->grab_cursor);
if (wayland_seat->pointer_grab_window)
{
_gdk_wayland_window_set_grab_seat (wayland_seat->pointer_grab_window,
NULL);
wayland_seat->pointer_grab_window = NULL;
}
gdk_wayland_seat_set_grab_window (wayland_seat, NULL);
if (wayland_seat->master_pointer)
{