[mutter/wip/carlosg/grabs-pt2: 10/13] clutter: Add docs and introspection annotations to grabs




commit 3a79b7b066358a5901705d7eae036e23612ed22f
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Nov 17 23:17:14 2021 +0100

    clutter: Add docs and introspection annotations to grabs
    
    Since we want these accessed from bindings this must be a boxed
    type. This has the side effect of making ClutterGrab a refcounted
    object, since we want to avoid JS from pointing to freed memory
    and maybe causing crashes if misusing the object after dismiss.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2099>

 clutter/clutter/clutter-grab.h   | 10 +++++++
 clutter/clutter/clutter-stage.c  | 59 +++++++++++++++++++++++++++++++++++++++-
 src/tests/clutter/conform/grab.c | 14 ++++++++++
 3 files changed, 82 insertions(+), 1 deletion(-)
---
diff --git a/clutter/clutter/clutter-grab.h b/clutter/clutter/clutter-grab.h
index 5d23d634b4..ca3324b68e 100644
--- a/clutter/clutter/clutter-grab.h
+++ b/clutter/clutter/clutter-grab.h
@@ -30,12 +30,22 @@
 
 #include <glib-object.h>
 
+#define CLUTTER_TYPE_GRAB (clutter_grab_get_type ())
 typedef struct _ClutterGrab ClutterGrab;
 
+CLUTTER_EXPORT
+GType clutter_grab_get_type (void) G_GNUC_CONST;
+
 CLUTTER_EXPORT
 void clutter_grab_dismiss (ClutterGrab *grab);
 
 CLUTTER_EXPORT
 ClutterGrabState clutter_grab_get_seat_state (ClutterGrab *grab);
 
+CLUTTER_EXPORT
+ClutterGrab * clutter_grab_ref (ClutterGrab *grab);
+
+CLUTTER_EXPORT
+void clutter_grab_unref (ClutterGrab *grab);
+
 #endif /* CLUTTER_GRAB_H */
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 1fe5ab9276..67f5f6a654 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -137,6 +137,7 @@ struct _ClutterStagePrivate
 
 struct _ClutterGrab
 {
+  grefcount ref_count;
   ClutterStage *stage;
   ClutterActor *actor;
   ClutterGrab *prev;
@@ -3750,6 +3751,37 @@ clutter_stage_notify_grab (ClutterStage *stage,
   clutter_stage_notify_grab_on_key_focus (stage, cur_actor, old_actor);
 }
 
+ClutterGrab *
+clutter_grab_ref (ClutterGrab *grab)
+{
+  g_ref_count_inc (&grab->ref_count);
+  return grab;
+}
+
+void
+clutter_grab_unref (ClutterGrab *grab)
+{
+  if (g_ref_count_dec (&grab->ref_count))
+    {
+      clutter_grab_dismiss (grab);
+      g_free (grab);
+    }
+}
+
+G_DEFINE_BOXED_TYPE (ClutterGrab, clutter_grab,
+                     clutter_grab_ref, clutter_grab_unref)
+
+/**
+ * clutter_stage_grab:
+ * @stage: The #ClutterStage
+ * @actor: The actor grabbing input
+ *
+ * Grabs input onto a certain actor. Events will be propagated as
+ * usual inside its hierarchy.
+ *
+ * Returns: (transfer none): (nullable): an opaque #ClutterGrab handle, drop
+ *   with clutter_grab_dismiss()
+ **/
 ClutterGrab *
 clutter_stage_grab (ClutterStage *stage,
                     ClutterActor *actor)
@@ -3773,6 +3805,7 @@ clutter_stage_grab (ClutterStage *stage,
     }
 
   grab = g_new0 (ClutterGrab, 1);
+  g_ref_count_init (&grab->ref_count);
   grab->stage = stage;
   grab->actor = actor;
   grab->prev = NULL;
@@ -3833,15 +3866,31 @@ clutter_stage_unlink_grab (ClutterStage *stage,
   grab->prev = NULL;
 }
 
+/**
+ * clutter_grab_dismiss:
+ * @grab: Grab to undo
+ *
+ * Removes a grab. If this grab is effective, crossing events
+ * will be generated to indicate the change in event redirection.
+ **/
 void
 clutter_grab_dismiss (ClutterGrab *grab)
 {
   g_return_if_fail (grab != NULL);
 
   clutter_stage_unlink_grab (grab->stage, grab);
-  g_free (grab);
 }
 
+/**
+ * clutter_grab_get_seat_state:
+ * @grab: a Grab handle
+ *
+ * Returns the windowing-level state of the
+ * grab, the devices that are guaranteed to be
+ * grabbed.
+ *
+ * Returns: The state of the grab.
+ **/
 ClutterGrabState
 clutter_grab_get_seat_state (ClutterGrab *grab)
 {
@@ -3850,6 +3899,14 @@ clutter_grab_get_seat_state (ClutterGrab *grab)
   return grab->stage->priv->grab_state;
 }
 
+/**
+ * clutter_stage_get_grab_actor:
+ * @stage: a #ClutterStage
+ *
+ * Gets the actor that currently holds a grab.
+ *
+ * Returns: (transfer none): The grabbing actor
+ **/
 ClutterActor *
 clutter_stage_get_grab_actor (ClutterStage *stage)
 {
diff --git a/src/tests/clutter/conform/grab.c b/src/tests/clutter/conform/grab.c
index e2ecb96402..b5ee3f41f3 100644
--- a/src/tests/clutter/conform/grab.c
+++ b/src/tests/clutter/conform/grab.c
@@ -217,6 +217,7 @@ grab_under_pointer (void)
   event_log_compare ((EventLog *) &grab_log, data.events);
 
   clutter_grab_dismiss (grab);
+  clutter_grab_unref (grab);
   event_log_compare ((EventLog *) &ungrab_log, data.events);
 
   test_data_shutdown (&data);
@@ -243,6 +244,7 @@ grab_under_pointers_parent (void)
   event_log_compare ((EventLog *) &grab_log, data.events);
 
   clutter_grab_dismiss (grab);
+  clutter_grab_unref (grab);
   event_log_compare ((EventLog *) &ungrab_log, data.events);
 
   test_data_shutdown (&data);
@@ -273,6 +275,7 @@ grab_outside_pointer (void)
   event_log_compare ((EventLog *) &grab_log, data.events);
 
   clutter_grab_dismiss (grab);
+  clutter_grab_unref (grab);
   event_log_compare ((EventLog *) &ungrab_log, data.events);
 
   test_data_shutdown (&data);
@@ -297,6 +300,7 @@ grab_stage (void)
   event_log_compare ((EventLog *) &grab_log, data.events);
 
   clutter_grab_dismiss (grab);
+  clutter_grab_unref (grab);
   event_log_compare ((EventLog *) &ungrab_log, data.events);
 
   test_data_shutdown (&data);
@@ -340,9 +344,11 @@ grab_stack_1 (void)
 
   /* Dismiss orderly */
   clutter_grab_dismiss (grab2);
+  clutter_grab_unref (grab2);
   event_log_compare ((EventLog *) &ungrab2_log, data.events);
 
   clutter_grab_dismiss (grab1);
+  clutter_grab_unref (grab1);
   event_log_compare ((EventLog *) &ungrab1_log, data.events);
 
   test_data_shutdown (&data);
@@ -388,9 +394,11 @@ grab_stack_2 (void)
 
   /* Dismiss orderly */
   clutter_grab_dismiss (grab2);
+  clutter_grab_unref (grab2);
   event_log_compare ((EventLog *) &ungrab2_log, data.events);
 
   clutter_grab_dismiss (grab1);
+  clutter_grab_unref (grab1);
   event_log_compare ((EventLog *) &ungrab1_log, data.events);
 
   test_data_shutdown (&data);
@@ -434,9 +442,11 @@ grab_unordered_ungrab_1 (void)
 
   /* Dismiss disorderly */
   clutter_grab_dismiss (grab1);
+  clutter_grab_unref (grab1);
   event_log_compare ((EventLog *) &ungrab1_log, data.events);
 
   clutter_grab_dismiss (grab2);
+  clutter_grab_unref (grab2);
   event_log_compare ((EventLog *) &ungrab2_log, data.events);
 
   test_data_shutdown (&data);
@@ -478,9 +488,11 @@ grab_unordered_ungrab_2 (void)
 
   /* Dismiss disorderly */
   clutter_grab_dismiss (grab1);
+  clutter_grab_unref (grab1);
   event_log_compare ((EventLog *) &ungrab1_log, data.events);
 
   clutter_grab_dismiss (grab2);
+  clutter_grab_unref (grab2);
   event_log_compare ((EventLog *) &ungrab2_log, data.events);
 
   test_data_shutdown (&data);
@@ -501,6 +513,7 @@ grab_key_focus_in_grab (void)
   g_assert_true (clutter_actor_has_key_focus (data.b));
 
   clutter_grab_dismiss (grab);
+  clutter_grab_unref (grab);
   g_assert_true (clutter_actor_has_key_focus (data.b));
 
   test_data_shutdown (&data);
@@ -521,6 +534,7 @@ grab_key_focus_outside_grab (void)
   g_assert_false (clutter_actor_has_key_focus (data.b));
 
   clutter_grab_dismiss (grab);
+  clutter_grab_unref (grab);
   g_assert_true (clutter_actor_has_key_focus (data.b));
 
   test_data_shutdown (&data);


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