diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 758d60a85..f6c23d049 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -324,3 +324,21 @@ meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer) meta_wayland_pointer_end_grab (pointer); g_slice_free (MetaWaylandPointerGrab, grab); } + +/* Called when the focused resource is destroyed */ +void +meta_wayland_pointer_destroy_focus (MetaWaylandPointer *pointer) +{ + if (pointer->grab == &pointer->default_grab) + { + /* The surface was destroyed, but had the implicit pointer grab. + Bypass the grab interface. */ + g_assert (pointer->button_count > 0); + + /* Note: we focus the NULL interface, not the current one, because + we have button down, and the clients would be confused if the + pointer enters the surface. + */ + meta_wayland_pointer_set_focus (pointer, NULL, 0, 0); + } +} diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index db6d3bf9b..491cdbcc7 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -35,6 +35,10 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, MetaWaylandSurface *surface, wl_fixed_t sx, wl_fixed_t sy); + +void +meta_wayland_pointer_destroy_focus (MetaWaylandPointer *pointer); + void meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer, MetaWaylandPointerGrab *grab); diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index ba3726f7c..56ac249ba 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -497,9 +497,14 @@ meta_wayland_surface_free (MetaWaylandSurface *surface) meta_wayland_compositor_repick (compositor); - /* Check that repick didn't pick the freed surface */ - g_assert (surface != compositor->seat->pointer.focus); g_assert (surface != compositor->seat->keyboard.focus); + if (surface == compositor->seat->pointer.focus) + { + meta_wayland_pointer_destroy_focus (&compositor->seat->pointer); + + g_assert (surface != compositor->seat->pointer.focus); + g_assert (surface != compositor->seat->pointer.grab->focus); + } if (compositor->implicit_grab_surface == surface) compositor->implicit_grab_surface = compositor->seat->pointer.current;