wayland: Unset keyboard focus if surface is destroyed
Depending on the ordering of the surface-associated resources being destroyed, we may fall into the following situation: - wl_surface is destroyed - destruction notifications for the surface runs - The MetaWaylandKeyboard attempts to synchronize the window focus - The MetaWindow is not destroyed yet, so the focused window remains the same, and the MetaWaylandKeyboard keeps the same focus MetaWaylandSurface. - wl_surface finalizes destruction, MetaWaylandSurface now has a NULL resource - xdg_toplevel destructor kicks in, it unmanages the window - The current focus window is again looked up, forced to look a different window - The MetaWaylandKeyboard focus now changes, tries to leave the old surface, but it has a NULL resource already, and raises a protocol error. If the order is inverted, the window being unmanaged triggers a focus change into a different window, the MetaWaylandKeyboard triggers a focus change while the MetaWaylandSurface is still intact, it succeeds, and the window gets properly destroyed. In order to make this independent of the order, it makes sense to make MetaWaylandKeyboard do like the other objects tracking focus surfaces, and have it care of its own little parcel. The surface destructor changed to simply unsetting the keyboard focus to NULL (guaranteeing that the old focus is left while the surface resource is still up), and leaving potential focus changes to the xdg_toplevel_destructor->unmanage->update_focus paths. Doing that alone is basically a revert of commit228d681b
, thus is still subject to keyboard focus being lost after a popup is destroyed. Change the approach to trigger the focus sync (and new focus surface lookup) so it happens from xdg_popup_destructor specifically to popups and alike xdg_toplevel. Fixes:228d681b
("wayland: Trigger full focus sync after keyboard focus surface is destroyed") Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2853 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3077>
This commit is contained in:
parent
a95a3a0d30
commit
c858ad7f91
@ -231,13 +231,8 @@ keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandKeyboard *keyboard =
|
||||
wl_container_of (listener, keyboard, focus_surface_listener);
|
||||
MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (keyboard);
|
||||
MetaWaylandSeat *seat = meta_wayland_input_device_get_seat (input_device);
|
||||
MetaWaylandCompositor *compositor = meta_wayland_seat_get_compositor (seat);
|
||||
MetaContext *context = meta_wayland_compositor_get_context (compositor);
|
||||
MetaDisplay *display = meta_context_get_display (context);
|
||||
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
meta_wayland_keyboard_set_focus (keyboard, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -590,10 +590,15 @@ xdg_popup_destructor (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandXdgPopup *xdg_popup =
|
||||
META_WAYLAND_XDG_POPUP (wl_resource_get_user_data (resource));
|
||||
MetaWaylandSurfaceRole *surface_role =
|
||||
META_WAYLAND_SURFACE_ROLE (xdg_popup);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
dismiss_popup (xdg_popup);
|
||||
|
||||
xdg_popup->resource = NULL;
|
||||
|
||||
meta_display_sync_wayland_input_focus (display_from_surface (surface));
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user