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




commit eef7d19e43e3368c7907d5841470ebce4ff5d492
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]