[mutter/wip/carlosg/frozen-app-behavior2: 2/2] wayland: Make the pointer leave non-alive surfaces
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/carlosg/frozen-app-behavior2: 2/2] wayland: Make the pointer leave non-alive surfaces
- Date: Wed, 1 Dec 2021 16:20:33 +0000 (UTC)
commit e223b709cd9b71d17c7a543cb0cdbda6b7c93551
Author: Carlos Garnacho <carlosg gnome org>
Date: Fri Sep 3 23:49:46 2021 +0200
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.
src/wayland/meta-wayland-pointer.c | 50 ++++++++++++++++++++++++++++++++++++++
src/wayland/meta-wayland-pointer.h | 1 +
2 files changed, 51 insertions(+)
---
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index abd779ad79..abeff1b7a3 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -241,6 +241,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)
{
@@ -446,6 +458,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);
}
@@ -890,6 +913,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)
@@ -899,6 +932,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) ||
@@ -921,6 +955,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;
@@ -949,6 +990,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)
diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h
index 5eda5276f4..3740cac7cc 100644
--- a/src/wayland/meta-wayland-pointer.h
+++ b/src/wayland/meta-wayland-pointer.h
@@ -70,6 +70,7 @@ struct _MetaWaylandPointer
MetaWaylandSurface *focus_surface;
gulong focus_surface_destroyed_handler_id;
+ gulong focus_surface_alive_notify_id;
guint32 focus_serial;
guint32 click_serial;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]