[mutter/wip/carlosg/frozen-app-behavior: 2/2] wayland: Make the pointer leave non-alive surfaces




commit 10e6f90843835415c4be465cc7679edfad6b249c
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 | 40 +++++++++++++++++++++++++++++++++++++-
 src/wayland/meta-wayland-pointer.h |  1 +
 2 files changed, 40 insertions(+), 1 deletion(-)
---
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index 3132abfd22..6c0956fed2 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -228,6 +228,16 @@ 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);
+
+  return meta_wayland_surface_get_window (toplevel);
+}
+
 static void
 sync_focus_surface (MetaWaylandPointer *pointer)
 {
@@ -257,7 +267,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;
+
+        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;
 
@@ -564,24 +582,44 @@ current_surface_destroyed (MetaWaylandSurface *surface,
   meta_wayland_pointer_set_current (pointer, NULL);
 }
 
+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);
+      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 5eda5276f4..ae18b6a47f 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;
 };


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]