summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2021-09-03 23:49:46 +0200
committerCarlos Garnacho <carlosg@gnome.org>2021-11-01 18:27:23 +0100
commit258d5c7d0389722c5ae9b6f8e6891e82f28caac1 (patch)
tree464c70b08ddcfc9c0b0c39953519ef6cc80d2fbb
parent2e92eba642d5e203ed4f699f2d2027ac2fa76c40 (diff)
downloadmutter-wip/carlosg/frozen-app-behavior.tar.gz
wayland: Make the pointer leave non-alive surfaceswip/carlosg/frozen-app-behavior
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.
-rw-r--r--src/wayland/meta-wayland-pointer.c47
-rw-r--r--src/wayland/meta-wayland-pointer.h1
2 files changed, 47 insertions, 1 deletions
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index abd779ad7..aed72a4e4 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)
{
@@ -270,7 +282,15 @@ sync_focus_surface (MetaWaylandPointer *pointer)
case META_EVENT_ROUTE_WAYLAND_POPUP:
{
const MetaWaylandPointerGrabInterface *interface = pointer->grab->interface;
- interface->focus (pointer->grab, pointer->current);
+ MetaWindow *window = NULL;
+
+ if (pointer->current)
+ window = surface_get_effective_window (pointer->current);
+
+ if (window && meta_window_get_alive (window))
+ interface->focus (pointer->grab, pointer->current);
+ else
+ meta_wayland_pointer_set_focus (pointer, NULL);
}
break;
@@ -577,23 +597,48 @@ current_surface_destroyed (MetaWaylandSurface *surface,
}
static void
+current_surface_alive_notify (MetaWindow *window,
+ GParamSpec *pspec,
+ MetaWaylandPointer *pointer)
+{
+ sync_focus_surface (pointer);
+}
+
+static void
meta_wayland_pointer_set_current (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface)
{
+ MetaWindow *window;
+
if (pointer->current)
{
+ window = surface_get_effective_window (pointer->current);
+
g_clear_signal_handler (&pointer->current_surface_destroyed_handler_id,
pointer->current);
+
+ if (window)
+ {
+ g_clear_signal_handler (&pointer->current_surface_alive_notify_id,
+ window);
+ }
+
pointer->current = NULL;
}
if (surface)
{
+ window = surface_get_effective_window (surface);
+
pointer->current = surface;
pointer->current_surface_destroyed_handler_id =
g_signal_connect (surface, "destroy",
G_CALLBACK (current_surface_destroyed),
pointer);
+ pointer->current_surface_alive_notify_id =
+ g_signal_connect (window, "notify::is-alive",
+ G_CALLBACK (current_surface_alive_notify),
+ pointer);
}
}
diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h
index 5eda5276f..ae18b6a47 100644
--- a/src/wayland/meta-wayland-pointer.h
+++ b/src/wayland/meta-wayland-pointer.h
@@ -86,6 +86,7 @@ struct _MetaWaylandPointer
ClutterInputDevice *device;
MetaWaylandSurface *current;
gulong current_surface_destroyed_handler_id;
+ gulong current_surface_alive_notify_id;
guint32 button_count;
};