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




commit c07c50d1892e882df506aaea4ea32ac8499178ce
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.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2122>

 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 e513ee2581..d01919f57c 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -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)
diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h
index 86810ebace..088312f2f5 100644
--- a/src/wayland/meta-wayland-pointer.h
+++ b/src/wayland/meta-wayland-pointer.h
@@ -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;
 


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