From 9c5bd9f8479feacc431aca4c9f9a3b625ae877d1 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 17 Nov 2023 21:38:51 +0100 Subject: [PATCH] clutter: Add "revoked" property to ClutterGrab Users of Clutter grabs may listen for notify::revoked changes in order to know that their grab is no longer in charge of event propagation, without the use of crossing events. Since a ClutterGrab may stay in the stack and regain effects, this notification also happens the other way around. Part-of: --- clutter/clutter/clutter-grab-private.h | 2 + clutter/clutter/clutter-grab.c | 54 ++++++++++++++++++++++++++ clutter/clutter/clutter-grab.h | 3 ++ clutter/clutter/clutter-stage.c | 6 +++ 4 files changed, 65 insertions(+) diff --git a/clutter/clutter/clutter-grab-private.h b/clutter/clutter/clutter-grab-private.h index 26085add9..bc9a79c52 100644 --- a/clutter/clutter/clutter-grab-private.h +++ b/clutter/clutter/clutter-grab-private.h @@ -42,4 +42,6 @@ ClutterGrab * clutter_grab_new (ClutterStage *stage, ClutterActor *actor, gboolean owns_actor); +void clutter_grab_notify (ClutterGrab *grab); + G_END_DECLS diff --git a/clutter/clutter/clutter-grab.c b/clutter/clutter/clutter-grab.c index 57fa0ecf9..bdd2d4333 100644 --- a/clutter/clutter/clutter-grab.c +++ b/clutter/clutter/clutter-grab.c @@ -23,6 +23,17 @@ #include "clutter-grab-private.h" +#include "clutter-private.h" + +enum +{ + PROP_0, + PROP_REVOKED, + N_PROPS, +}; + +static GParamSpec *props[N_PROPS] = { 0, }; + G_DEFINE_FINAL_TYPE (ClutterGrab, clutter_grab, G_TYPE_OBJECT) static void @@ -43,6 +54,25 @@ clutter_grab_finalize (GObject *object) G_OBJECT_CLASS (clutter_grab_parent_class)->finalize (object); } +static void +clutter_grab_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterGrab *grab = CLUTTER_GRAB (object); + + switch (prop_id) + { + case PROP_REVOKED: + g_value_set_boolean (value, clutter_grab_is_revoked (grab)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void clutter_grab_class_init (ClutterGrabClass *klass) { @@ -50,6 +80,16 @@ clutter_grab_class_init (ClutterGrabClass *klass) object_class->dispose = clutter_grab_dispose; object_class->finalize = clutter_grab_finalize; + object_class->get_property = clutter_grab_get_property; + + props[PROP_REVOKED] = + g_param_spec_boolean ("revoked", NULL, NULL, + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS | + G_PARAM_EXPLICIT_NOTIFY); + + g_object_class_install_properties (object_class, N_PROPS, props); } static void @@ -73,3 +113,17 @@ clutter_grab_new (ClutterStage *stage, return grab; } + +void +clutter_grab_notify (ClutterGrab *grab) +{ + g_object_notify (G_OBJECT (grab), "revoked"); +} + +gboolean +clutter_grab_is_revoked (ClutterGrab *grab) +{ + g_return_val_if_fail (CLUTTER_IS_GRAB (grab), FALSE); + + return grab->prev != NULL; +} diff --git a/clutter/clutter/clutter-grab.h b/clutter/clutter/clutter-grab.h index 1e4eb67ff..36199acc9 100644 --- a/clutter/clutter/clutter-grab.h +++ b/clutter/clutter/clutter-grab.h @@ -41,3 +41,6 @@ void clutter_grab_dismiss (ClutterGrab *grab); CLUTTER_EXPORT ClutterGrabState clutter_grab_get_seat_state (ClutterGrab *grab); + +CLUTTER_EXPORT +gboolean clutter_grab_is_revoked (ClutterGrab *grab); diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index e1804fa88..498408ec3 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -3930,6 +3930,9 @@ clutter_stage_grab_full (ClutterStage *stage, if (was_grabbed != !!priv->topmost_grab) g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_IS_GRABBED]); + if (grab->next) + clutter_grab_notify (grab->next); + return grab; } @@ -4035,6 +4038,9 @@ clutter_stage_unlink_grab (ClutterStage *stage, if (grab->owns_actor) g_clear_pointer (&grab->actor, clutter_actor_destroy); + + if (priv->topmost_grab) + clutter_grab_notify (priv->topmost_grab); } /**