[mutter/wip/carlosg/repick-on-reactive-42: 2/2] clutter/actor: Handle repicks when actors become reactive




commit 15e2f56aa39babdd4a925447a1b6c228b6b80479
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Jul 26 13:54:22 2022 +0200

    clutter/actor: Handle repicks when actors become reactive
    
    The notification list in the GNOME Shell calendar popup triggers some
    interesting interactions when closing a notification:
    
    - Close button is clicked
    - The notification animates to be hidden
    - The next notification ends up hovered as a result of the animation
    - The notification being hovered sets its close button as non-transparent
      and reactive
    - The pointer is now again over a close button
    
    At this point the reactiveness change should trigger a repick, so that
    the new notification's close button is picked, and future button presses
    are directed to it, but we do not handle this situation.
    
    To fix this, handle actors becoming reactive so that if the closest
    reactive parent has a pointer, it will be repicked again just in case
    the pointer is over the newly reactive actor.
    
    Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2364
    
    (cherry-picked from commit 550b66d4e64b6d2efd122d9e04e91aa31c27a37b)

 clutter/clutter/clutter-actor.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index b31a4d01d6..3d73175dcf 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -12469,6 +12469,30 @@ clutter_actor_set_reactive (ClutterActor *actor,
 
       clutter_stage_invalidate_focus (CLUTTER_STAGE (stage), actor);
     }
+  else if (CLUTTER_ACTOR_IS_REACTIVE (actor))
+    {
+      ClutterActor *parent;
+
+      /* Check whether the closest parent has pointer focus,
+       * and whether it should move to this actor.
+       */
+      parent = priv->parent;
+
+      while (parent)
+        {
+          if (CLUTTER_ACTOR_IS_REACTIVE (parent))
+            break;
+
+          parent = parent->priv->parent;
+        }
+
+      if (parent && parent->priv->has_pointer)
+        {
+          ClutterActor *stage = _clutter_actor_get_stage_internal (actor);
+
+          clutter_stage_maybe_invalidate_focus (CLUTTER_STAGE (stage), parent);
+        }
+    }
 }
 
 /**


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