[mutter/wip/carlosg/undo-grabs-harder: 1/2] clutter: Undo actor grabs along with ::unrealize




commit e8a4182a63128b1b23d907b2ae2a343947cb8b69
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Oct 18 12:06:17 2022 +0200

    clutter: Undo actor grabs along with ::unrealize
    
    If an actor is being unrealized or otherwise unparented, it's a good
    indication that its grabs are now stale and possibly harmful. Ensure
    these are dropped when the actor is unparented.
    
    This is now an unlikely event, since there is code to also dismiss
    grabs when a visible grabbed actor goes unmapped. But that may be
    prevented from happening, or the ordering of circumstances allow a
    grab to be created and an actor destroyed without going unmapped
    first. This grab dismission on unmap stays as it matches the UI-level
    expectatives that an actor must be visible to be grabbed.
    
    Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/2475

 clutter/clutter/clutter-actor.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 5e25bfba45..4d1856ef77 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -2141,11 +2141,17 @@ unrealize_actor_before_children_cb (ClutterActor *self,
                                     int depth,
                                     void *user_data)
 {
+  ClutterActor *stage;
+
   /* If an actor is already unrealized we know its children have also
    * already been unrealized... */
   if (!CLUTTER_ACTOR_IS_REALIZED (self))
     return CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN;
 
+  stage = _clutter_actor_get_stage_internal (self);
+  if (stage != NULL)
+    clutter_actor_clear_grabs (self);
+
   g_signal_emit (self, actor_signals[UNREALIZE], 0);
 
   return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE;
@@ -5620,7 +5626,7 @@ clutter_actor_finalize (GObject *object)
                 _clutter_actor_get_debug_name ((ClutterActor *) object),
                 g_type_name (G_OBJECT_TYPE (object)));
 
-  /* No new grabs should have happened after unmapping */
+  /* No new grabs should have happened after unrealizing */
   g_assert (priv->grabs == NULL);
   g_free (priv->name);
 


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