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:
@ -2614,6 +2614,27 @@ gdk_wayland_seat_get_capabilities (GdkSeat *seat)
|
|||||||
return caps;
|
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
|
static GdkGrabStatus
|
||||||
gdk_wayland_seat_grab (GdkSeat *seat,
|
gdk_wayland_seat_grab (GdkSeat *seat,
|
||||||
GdkWindow *window,
|
GdkWindow *window,
|
||||||
@ -2646,16 +2667,15 @@ gdk_wayland_seat_grab (GdkSeat *seat,
|
|||||||
if (native == NULL || GDK_WINDOW_DESTROYED (native))
|
if (native == NULL || GDK_WINDOW_DESTROYED (native))
|
||||||
return GDK_GRAB_NOT_VIEWABLE;
|
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;
|
wayland_seat->pointer_grab_time = evtime;
|
||||||
_gdk_wayland_window_set_grab_seat (window, seat);
|
|
||||||
|
|
||||||
if (prepare_func)
|
if (prepare_func)
|
||||||
(prepare_func) (seat, window, prepare_func_data);
|
(prepare_func) (seat, window, prepare_func_data);
|
||||||
|
|
||||||
if (!gdk_window_is_visible (window))
|
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",
|
g_critical ("Window %p has not been made visible in GdkSeatGrabPrepareFunc",
|
||||||
window);
|
window);
|
||||||
return GDK_GRAB_NOT_VIEWABLE;
|
return GDK_GRAB_NOT_VIEWABLE;
|
||||||
@ -2740,12 +2760,7 @@ gdk_wayland_seat_ungrab (GdkSeat *seat)
|
|||||||
|
|
||||||
g_clear_object (&wayland_seat->grab_cursor);
|
g_clear_object (&wayland_seat->grab_cursor);
|
||||||
|
|
||||||
if (wayland_seat->pointer_grab_window)
|
gdk_wayland_seat_set_grab_window (wayland_seat, NULL);
|
||||||
{
|
|
||||||
_gdk_wayland_window_set_grab_seat (wayland_seat->pointer_grab_window,
|
|
||||||
NULL);
|
|
||||||
wayland_seat->pointer_grab_window = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wayland_seat->master_pointer)
|
if (wayland_seat->master_pointer)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user