[mutter/wip/carlosg/grabs-pt2] core: Handle redirection changes in and out of ClutterGrab grabs




commit 78713056bf6ebf9eb40fef13dd91f431e4801cf0
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Nov 17 23:31:11 2021 +0100

    core: Handle redirection changes in and out of ClutterGrab grabs
    
    Wayland event processing and WM operations are themselves outside the
    ClutterGrab loop so far. Until this is sorted out, these pieces of
    event handling have got to learn to stay aside while there is a
    ClutterGrab going on.
    
    So, synchronize foci and other state when grabs come in or out, and
    make it sure that Wayland event processing does not happen while
    grabs happen.

 clutter/clutter/clutter-stage.c        |  9 +++++---
 src/compositor/compositor-private.h    |  3 +++
 src/compositor/compositor.c            |  4 ++--
 src/core/display-private.h             |  1 +
 src/core/events.c                      | 42 ++++++++++++++++++++++++++++++++++
 src/wayland/meta-wayland-pointer.c     | 10 ++++++--
 src/wayland/meta-wayland-tablet-tool.c |  8 +++++++
 7 files changed, 70 insertions(+), 7 deletions(-)
---
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 10f62d9333..d780c93bc0 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -3426,7 +3426,8 @@ clutter_stage_update_device (ClutterStage         *stage,
                                          CLUTTER_LEAVE, 0,
                                          old_actor, new_actor,
                                          point, time);
-          _clutter_actor_handle_event (old_actor, root, event);
+          if (!_clutter_event_process_filters (event))
+            _clutter_actor_handle_event (old_actor, root, event);
 
           clutter_event_free (event);
         }
@@ -3438,7 +3439,8 @@ clutter_stage_update_device (ClutterStage         *stage,
                                          CLUTTER_ENTER, 0,
                                          new_actor, old_actor,
                                          point, time);
-          _clutter_actor_handle_event (new_actor, root, event);
+          if (!_clutter_event_process_filters (event))
+            _clutter_actor_handle_event (new_actor, root, event);
 
           clutter_event_free (event);
         }
@@ -3559,7 +3561,8 @@ clutter_stage_notify_grab_on_entry (ClutterStage       *stage,
                                      grab_actor : old_grab_actor,
                                      entry->coords,
                                      CLUTTER_CURRENT_TIME);
-      _clutter_actor_handle_event (deepmost, topmost, event);
+      if (!_clutter_event_process_filters (event))
+        _clutter_actor_handle_event (deepmost, topmost, event);
       clutter_event_free (event);
     }
 }
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
index 580618e481..4e4194f127 100644
--- a/src/compositor/compositor-private.h
+++ b/src/compositor/compositor-private.h
@@ -82,6 +82,9 @@ gboolean meta_compositor_is_switching_workspace (MetaCompositor *compositor);
 
 MetaLaters * meta_compositor_get_laters (MetaCompositor *compositor);
 
+void meta_compositor_grab_begin (MetaCompositor *compositor);
+void meta_compositor_grab_end (MetaCompositor *compositor);
+
 /*
  * This function takes a 64 bit time stamp from the monotonic clock, and clamps
  * it to the scope of the X server clock, without losing the granularity.
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index ee6be007b8..f33dacefcb 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -374,13 +374,13 @@ grab_devices (MetaModalOptions  options,
   return FALSE;
 }
 
-static void
+void
 meta_compositor_grab_begin (MetaCompositor *compositor)
 {
   META_COMPOSITOR_GET_CLASS (compositor)->grab_begin (compositor);
 }
 
-static void
+void
 meta_compositor_grab_end (MetaCompositor *compositor)
 {
   META_COMPOSITOR_GET_CLASS (compositor)->grab_end (compositor);
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 8efac0b492..6b7821412a 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -197,6 +197,7 @@ struct _MetaDisplay
 
   /* Opening the display */
   unsigned int display_opening : 1;
+  unsigned int grabbed_in_clutter : 1;
 
   /* Closing down the display */
   int closing;
diff --git a/src/core/events.c b/src/core/events.c
index 8afc720efd..748b350e28 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -28,6 +28,7 @@
 #include "backends/meta-idle-manager.h"
 #include "backends/x11/meta-backend-x11.h"
 #include "backends/x11/meta-input-device-x11.h"
+#include "compositor/compositor-private.h"
 #include "compositor/meta-window-actor-private.h"
 #include "core/display-private.h"
 #include "core/window-private.h"
@@ -66,6 +67,15 @@ stage_has_key_focus (void)
   return clutter_stage_get_key_focus (CLUTTER_STAGE (stage)) == stage;
 }
 
+static gboolean
+stage_has_grab (void)
+{
+  MetaBackend *backend = meta_get_backend ();
+  ClutterActor *stage = meta_backend_get_stage (backend);
+
+  return clutter_stage_get_grab_actor (CLUTTER_STAGE (stage)) != NULL;
+}
+
 static MetaWindow *
 get_window_for_event (MetaDisplay        *display,
                       const ClutterEvent *event)
@@ -206,6 +216,31 @@ meta_display_handle_event (MetaDisplay        *display,
   G_GNUC_UNUSED gboolean bypass_wayland = FALSE;
   MetaGestureTracker *gesture_tracker;
   ClutterEventSequence *sequence;
+  ClutterActor *grab_actor;
+
+  grab_actor = clutter_stage_get_grab_actor (event->any.stage);
+
+  if (display->grabbed_in_clutter != (grab_actor != NULL))
+    {
+      MetaCompositor *compositor = meta_display_get_compositor (display);
+
+#ifdef HAVE_WAYLAND
+      if (meta_is_wayland_compositor ())
+        meta_display_sync_wayland_input_focus (display);
+#endif
+
+      if (!display->grabbed_in_clutter && grab_actor)
+        {
+          display->grabbed_in_clutter = TRUE;
+          meta_display_cancel_touch (display);
+          meta_compositor_grab_begin (compositor);
+        }
+      else if (display->grabbed_in_clutter && !grab_actor)
+        {
+          display->grabbed_in_clutter = FALSE;
+          meta_compositor_grab_end (compositor);
+        }
+    }
 
   sequence = clutter_event_get_event_sequence (event);
 
@@ -393,6 +428,13 @@ meta_display_handle_event (MetaDisplay        *display,
       goto out;
     }
 
+  if (stage_has_grab ())
+    {
+      bypass_wayland = TRUE;
+      bypass_clutter = FALSE;
+      goto out;
+    }
+
   if (window)
     {
       /* Events that are likely to trigger compositor gestures should
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index abd779ad79..cae8860c8e 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -249,9 +249,11 @@ sync_focus_surface (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);
+  ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
 
-  if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) &&
-      !clutter_seat_is_unfocus_inhibited (clutter_seat))
+  if (clutter_stage_get_grab_actor (stage) != NULL ||
+      (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) &&
+       !clutter_seat_is_unfocus_inhibited (clutter_seat)))
     {
       meta_wayland_pointer_set_focus (pointer, NULL);
       return;
@@ -422,10 +424,14 @@ default_grab_focus (MetaWaylandPointerGrab *grab,
   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);
+  ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
 
   if (!meta_wayland_seat_has_pointer (seat))
     return;
 
+  if (clutter_stage_get_grab_actor (stage) != NULL)
+    return;
+
   if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) &&
       !clutter_seat_is_unfocus_inhibited (clutter_seat))
     return;
diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c
index 51e4e7d5d4..8d4b9c942c 100644
--- a/src/wayland/meta-wayland-tablet-tool.c
+++ b/src/wayland/meta-wayland-tablet-tool.c
@@ -549,6 +549,14 @@ sync_focus_surface (MetaWaylandTabletTool *tool,
                     const ClutterEvent    *event)
 {
   MetaDisplay *display = meta_get_display ();
+  MetaBackend *backend = meta_get_backend ();
+  ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
+
+  if (clutter_stage_get_grab_actor (stage))
+    {
+      meta_wayland_tablet_tool_set_focus (tool, NULL, event);
+      return;
+    }
 
   switch (display->event_route)
     {


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