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);
|
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
|
static void
|
||||||
sync_focus_surface (MetaWaylandPointer *pointer)
|
sync_focus_surface (MetaWaylandPointer *pointer)
|
||||||
{
|
{
|
||||||
@ -453,6 +465,17 @@ default_grab_focus (MetaWaylandPointerGrab *grab,
|
|||||||
break;
|
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);
|
meta_wayland_pointer_set_focus (pointer, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -901,6 +924,16 @@ focus_surface_destroyed (MetaWaylandSurface *surface,
|
|||||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
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
|
void
|
||||||
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||||
MetaWaylandSurface *surface)
|
MetaWaylandSurface *surface)
|
||||||
@ -910,6 +943,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
|||||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||||
ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_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) ||
|
g_return_if_fail (meta_cursor_tracker_get_pointer_visible (cursor_tracker) ||
|
||||||
clutter_seat_is_unfocus_inhibited (clutter_seat) ||
|
clutter_seat_is_unfocus_inhibited (clutter_seat) ||
|
||||||
@ -932,6 +966,13 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
|||||||
pointer->focus_client = NULL;
|
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,
|
g_clear_signal_handler (&pointer->focus_surface_destroyed_handler_id,
|
||||||
pointer->focus_surface);
|
pointer->focus_surface);
|
||||||
pointer->focus_surface = NULL;
|
pointer->focus_surface = NULL;
|
||||||
@ -960,6 +1001,15 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
|||||||
clutter_get_current_event_time (),
|
clutter_get_current_event_time (),
|
||||||
pos.x, pos.y);
|
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 =
|
pointer->focus_client =
|
||||||
meta_wayland_pointer_get_pointer_client (pointer, client);
|
meta_wayland_pointer_get_pointer_client (pointer, client);
|
||||||
if (pointer->focus_client)
|
if (pointer->focus_client)
|
||||||
|
@ -72,6 +72,7 @@ struct _MetaWaylandPointer
|
|||||||
|
|
||||||
MetaWaylandSurface *focus_surface;
|
MetaWaylandSurface *focus_surface;
|
||||||
gulong focus_surface_destroyed_handler_id;
|
gulong focus_surface_destroyed_handler_id;
|
||||||
|
gulong focus_surface_alive_notify_id;
|
||||||
guint32 focus_serial;
|
guint32 focus_serial;
|
||||||
guint32 click_serial;
|
guint32 click_serial;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user