[mutter] clutter/actor: Don't emit property changes after ::destroy



commit 105a3f757a31299ed4eaafa0615e1fcd0b4ffeec
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Tue Sep 10 03:34:09 2019 +0200

    clutter/actor: Don't emit property changes after ::destroy
    
    Clutter actors might emit property changes in dispose, while unparenting.
    However we assume that the ::destroy signal is the last one we emit for an
    actor, and that starting from this moment the object is not valid anymore,
    and so we don't expect any signal emission from it.
    
    To avoid this, freeze the object notifications on an actor during its
    disposition, just before the ::destroy signal emission.
    
    Update the actor-destroy test to verify this behavior.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/769

 clutter/clutter/clutter-actor.c           |  3 +++
 src/tests/clutter/conform/actor-destroy.c | 13 +++++++++++++
 2 files changed, 16 insertions(+)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 313317de3d..fbef49c296 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -6069,6 +6069,9 @@ clutter_actor_dispose (GObject *object)
                 object->ref_count,
                g_type_name (G_OBJECT_TYPE (self)));
 
+  /* Stop the emission of any property change */
+  g_object_freeze_notify (object);
+
   g_signal_emit (self, actor_signals[DESTROY], 0);
 
   /* avoid recursing when called from clutter_actor_destroy() */
diff --git a/src/tests/clutter/conform/actor-destroy.c b/src/tests/clutter/conform/actor-destroy.c
index 3de0fef7de..8a67456c2c 100644
--- a/src/tests/clutter/conform/actor-destroy.c
+++ b/src/tests/clutter/conform/actor-destroy.c
@@ -176,6 +176,16 @@ on_parent_set (ClutterActor *actor,
   *parent_set_called = TRUE;
 }
 
+static void
+on_notify (ClutterActor *actor,
+           ClutterActor *old_parent,
+           gpointer      data)
+{
+  gboolean *property_changed = data;
+
+  *property_changed = TRUE;
+}
+
 static void
 actor_destruction (void)
 {
@@ -183,6 +193,7 @@ actor_destruction (void)
   ClutterActor *child = clutter_rectangle_new ();
   gboolean destroy_called = FALSE;
   gboolean parent_set_called = FALSE;
+  gboolean property_changed = FALSE;
 
   g_object_ref_sink (test);
 
@@ -196,6 +207,7 @@ actor_destruction (void)
   clutter_container_add_actor (CLUTTER_CONTAINER (test), child);
   g_signal_connect (child, "parent-set", G_CALLBACK (on_parent_set),
                     &parent_set_called);
+  g_signal_connect (child, "notify", G_CALLBACK (on_notify), &property_changed);
   g_signal_connect (child, "destroy", G_CALLBACK (on_destroy), &destroy_called);
 
   if (g_test_verbose ())
@@ -204,6 +216,7 @@ actor_destruction (void)
   clutter_actor_destroy (test);
   g_assert (destroy_called);
   g_assert_false (parent_set_called);
+  g_assert_false (property_changed);
   g_assert_null (child);
   g_assert_null (test);
 }


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