mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 01:50:42 -05:00
wayland: fix pointer focus for destroyed surfaces
We had an assertion in meta_wayland_surface_free() that after a repick() we would not choose the freed surface, but that didn't consider surfaces destroyed while holding the implicit pointer grab (ie, because the user clicked on the X button). In that case, we need to bypass the grab infrastructure and explicitly unfocus the dead surface. https://bugzilla.gnome.org/show_bug.cgi?id=706982
This commit is contained in:
parent
7bd4e6ecb0
commit
ad4053ab84
@ -324,3 +324,21 @@ meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer)
|
|||||||
meta_wayland_pointer_end_grab (pointer);
|
meta_wayland_pointer_end_grab (pointer);
|
||||||
g_slice_free (MetaWaylandPointerGrab, grab);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -35,6 +35,10 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
|||||||
MetaWaylandSurface *surface,
|
MetaWaylandSurface *surface,
|
||||||
wl_fixed_t sx,
|
wl_fixed_t sx,
|
||||||
wl_fixed_t sy);
|
wl_fixed_t sy);
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_pointer_destroy_focus (MetaWaylandPointer *pointer);
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
|
meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
|
||||||
MetaWaylandPointerGrab *grab);
|
MetaWaylandPointerGrab *grab);
|
||||||
|
@ -497,9 +497,14 @@ meta_wayland_surface_free (MetaWaylandSurface *surface)
|
|||||||
|
|
||||||
meta_wayland_compositor_repick (compositor);
|
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);
|
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)
|
if (compositor->implicit_grab_surface == surface)
|
||||||
compositor->implicit_grab_surface = compositor->seat->pointer.current;
|
compositor->implicit_grab_surface = compositor->seat->pointer.current;
|
||||||
|
Loading…
Reference in New Issue
Block a user