diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2016-01-18 14:05:00 +0100 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2016-01-19 00:00:06 +0100 |
commit | be016ad7454f446f8b28cedb3412cd8fe636dd19 (patch) | |
tree | cbbfb19ea16b59479e40f7f6c3aa3a93e2edbc62 | |
parent | 9038313a1a736ff125131e4398477ac355fe7554 (diff) | |
download | gtk+-be016ad7454f446f8b28cedb3412cd8fe636dd19.tar.gz |
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.
-rw-r--r-- | gdk/wayland/gdkdevice-wayland.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index cf98849931..b8f92fef68 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -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) { |