wayland: Make the pointer leave non-alive surfaces
Listen to changes in MetaWindow::is-alive, so that the pointer can logically leave the surface as soon as that happens. This helps prevent flooding the client socket while it is stalled. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2122>
This commit is contained in:
parent
26676a829e
commit
c07c50d189
@ -248,6 +248,18 @@ meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resourc
|
||||
client);
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
surface_get_effective_window (MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandSurface *toplevel;
|
||||
|
||||
toplevel = meta_wayland_surface_get_toplevel (surface);
|
||||
if (!toplevel)
|
||||
return NULL;
|
||||
|
||||
return meta_wayland_surface_get_window (toplevel);
|
||||
}
|
||||
|
||||
static void
|
||||
sync_focus_surface (MetaWaylandPointer *pointer)
|
||||
{
|
||||
@ -453,6 +465,17 @@ default_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
break;
|
||||
}
|
||||
|
||||
if (surface)
|
||||
{
|
||||
MetaWindow *window = NULL;
|
||||
|
||||
window = surface_get_effective_window (surface);
|
||||
|
||||
/* Avoid focusing a non-alive surface */
|
||||
if (!window || !meta_window_get_alive (window))
|
||||
surface = NULL;
|
||||
}
|
||||
|
||||
meta_wayland_pointer_set_focus (pointer, surface);
|
||||
}
|
||||
|
||||
@ -901,6 +924,16 @@ focus_surface_destroyed (MetaWaylandSurface *surface,
|
||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
focus_surface_alive_notify (MetaWindow *window,
|
||||
GParamSpec *pspec,
|
||||
MetaWaylandPointer *pointer)
|
||||
{
|
||||
if (!meta_window_get_alive (window))
|
||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||
sync_focus_surface (pointer);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface)
|
||||
@ -910,6 +943,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
MetaWindow *toplevel_window;
|
||||
|
||||
g_return_if_fail (meta_cursor_tracker_get_pointer_visible (cursor_tracker) ||
|
||||
clutter_seat_is_unfocus_inhibited (clutter_seat) ||
|
||||
@ -932,6 +966,13 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
pointer->focus_client = NULL;
|
||||
}
|
||||
|
||||
toplevel_window = surface_get_effective_window (pointer->focus_surface);
|
||||
if (toplevel_window)
|
||||
{
|
||||
g_clear_signal_handler (&pointer->focus_surface_alive_notify_id,
|
||||
toplevel_window);
|
||||
}
|
||||
|
||||
g_clear_signal_handler (&pointer->focus_surface_destroyed_handler_id,
|
||||
pointer->focus_surface);
|
||||
pointer->focus_surface = NULL;
|
||||
@ -960,6 +1001,15 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
clutter_get_current_event_time (),
|
||||
pos.x, pos.y);
|
||||
|
||||
toplevel_window = surface_get_effective_window (pointer->focus_surface);
|
||||
if (toplevel_window)
|
||||
{
|
||||
pointer->focus_surface_alive_notify_id =
|
||||
g_signal_connect (toplevel_window, "notify::is-alive",
|
||||
G_CALLBACK (focus_surface_alive_notify),
|
||||
pointer);
|
||||
}
|
||||
|
||||
pointer->focus_client =
|
||||
meta_wayland_pointer_get_pointer_client (pointer, client);
|
||||
if (pointer->focus_client)
|
||||
|
@ -72,6 +72,7 @@ struct _MetaWaylandPointer
|
||||
|
||||
MetaWaylandSurface *focus_surface;
|
||||
gulong focus_surface_destroyed_handler_id;
|
||||
gulong focus_surface_alive_notify_id;
|
||||
guint32 focus_serial;
|
||||
guint32 click_serial;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user