Blame SOURCES/0001-clutter-actor-Don-t-emit-the-parent-set-signal-on-de.patch

c35f0a
From be7ac5afa6227484b997a1770dab01a42ea2a035 Mon Sep 17 00:00:00 2001
c35f0a
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
c35f0a
Date: Tue, 10 Sep 2019 03:19:58 +0200
c35f0a
Subject: [PATCH 1/2] clutter/actor: Don't emit the parent-set signal on
c35f0a
 destruction
c35f0a
c35f0a
Clutter actors unset their parent on dispose, after emitting the ::destroy
c35f0a
signal, however this could cause ::parent-set signal emission. Since we
c35f0a
assume that after the destruction has been completed the actor isn't valid
c35f0a
anymore, and that during the destroy phase we do all the signal / source
c35f0a
disconnections, this might create unwanted behaviors, as in the signal
c35f0a
callbacks we always assume that the actor isn't in disposed yet.
c35f0a
c35f0a
To avoid this, don't emit ::parent-set signal if the actor is being
c35f0a
destroyed.
c35f0a
c35f0a
Update the actor-destroy test to verify this behavior.
c35f0a
c35f0a
https://gitlab.gnome.org/GNOME/mutter/merge_requests/769
c35f0a
(cherry picked from commit f376a318ba90fc29d3d661df4f55698459f31cfa)
c35f0a
---
c35f0a
 clutter/clutter/clutter-actor.c       |  3 ++-
c35f0a
 clutter/tests/conform/actor-destroy.c | 16 ++++++++++++++++
c35f0a
 2 files changed, 18 insertions(+), 1 deletion(-)
c35f0a
c35f0a
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
c35f0a
index 7111d824d3..0e531eea52 100644
c35f0a
--- a/clutter/clutter/clutter-actor.c
c35f0a
+++ b/clutter/clutter/clutter-actor.c
c35f0a
@@ -4315,7 +4315,8 @@ clutter_actor_remove_child_internal (ClutterActor                 *self,
c35f0a
     }
c35f0a
 
c35f0a
   /* clutter_actor_reparent() will emit ::parent-set for us */
c35f0a
-  if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child))
c35f0a
+  if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child) &&
c35f0a
+      !CLUTTER_ACTOR_IN_DESTRUCTION (child))
c35f0a
     g_signal_emit (child, actor_signals[PARENT_SET], 0, self);
c35f0a
 
c35f0a
   /* if the child was mapped then we need to relayout ourselves to account
c35f0a
diff --git a/clutter/tests/conform/actor-destroy.c b/clutter/tests/conform/actor-destroy.c
c35f0a
index 03092a0108..14ad1a25c8 100644
c35f0a
--- a/clutter/tests/conform/actor-destroy.c
c35f0a
+++ b/clutter/tests/conform/actor-destroy.c
c35f0a
@@ -159,15 +159,28 @@ on_destroy (ClutterActor *actor,
c35f0a
 {
c35f0a
   gboolean *destroy_called = data;
c35f0a
 
c35f0a
+  g_assert_true (CLUTTER_IS_ACTOR (clutter_actor_get_parent (actor)));
c35f0a
+
c35f0a
   *destroy_called = TRUE;
c35f0a
 }
c35f0a
 
c35f0a
+static void
c35f0a
+on_parent_set (ClutterActor *actor,
c35f0a
+               ClutterActor *old_parent,
c35f0a
+               gpointer      data)
c35f0a
+{
c35f0a
+  gboolean *parent_set_called = data;
c35f0a
+
c35f0a
+  *parent_set_called = TRUE;
c35f0a
+}
c35f0a
+
c35f0a
 static void
c35f0a
 actor_destruction (void)
c35f0a
 {
c35f0a
   ClutterActor *test = g_object_new (TEST_TYPE_DESTROY, NULL);
c35f0a
   ClutterActor *child = clutter_rectangle_new ();
c35f0a
   gboolean destroy_called = FALSE;
c35f0a
+  gboolean parent_set_called = FALSE;
c35f0a
 
c35f0a
   g_object_ref_sink (test);
c35f0a
 
c35f0a
@@ -179,6 +192,8 @@ actor_destruction (void)
c35f0a
 
c35f0a
   clutter_actor_set_name (child, "Child");
c35f0a
   clutter_container_add_actor (CLUTTER_CONTAINER (test), child);
c35f0a
+  g_signal_connect (child, "parent-set", G_CALLBACK (on_parent_set),
c35f0a
+                    &parent_set_called);
c35f0a
   g_signal_connect (child, "destroy", G_CALLBACK (on_destroy), &destroy_called);
c35f0a
 
c35f0a
   if (g_test_verbose ())
c35f0a
@@ -186,6 +201,7 @@ actor_destruction (void)
c35f0a
 
c35f0a
   clutter_actor_destroy (test);
c35f0a
   g_assert (destroy_called);
c35f0a
+  g_assert_false (parent_set_called);
c35f0a
   g_assert_null (child);
c35f0a
   g_assert_null (test);
c35f0a
 }
c35f0a
-- 
c35f0a
2.28.0
c35f0a