diff --git a/ges/ges-container.c b/ges/ges-container.c index 016b6ddab8..1543d09b62 100644 --- a/ges/ges-container.c +++ b/ges/ges-container.c @@ -77,6 +77,10 @@ struct _GESContainerPrivate */ GHashTable *mappings; guint nb_effects; + + /* List of GESTimelineElement being in the "child-added" signal + * emission stage */ + GList *adding_children; }; enum @@ -380,6 +384,9 @@ ges_container_class_init (GESContainerClass * klass) * @element: the #GESTimelineElement that was added. * * Will be emitted after a child was added to @container. + * Usually you should connect with #g_signal_connect_after + * as in the first emission stage, the signal emission might + * get stopped internally. */ ges_container_signals[CHILD_ADDED_SIGNAL] = g_signal_new ("child-added", G_TYPE_FROM_CLASS (klass), @@ -687,8 +694,10 @@ ges_container_add (GESContainer * container, GESTimelineElement * child) _ges_container_add_child_properties (container, child); + priv->adding_children = g_list_prepend (priv->adding_children, child); g_signal_emit (container, ges_container_signals[CHILD_ADDED_SIGNAL], 0, child); + priv->adding_children = g_list_remove (priv->adding_children, child); return TRUE; } @@ -733,8 +742,13 @@ ges_container_remove (GESContainer * container, GESTimelineElement * child) _ges_container_remove_child_properties (container, child); - g_signal_emit (container, ges_container_signals[CHILD_REMOVED_SIGNAL], 0, - child); + if (!g_list_find (container->priv->adding_children, child)) { + g_signal_emit (container, ges_container_signals[CHILD_REMOVED_SIGNAL], 0, + child); + } else { + GST_INFO_OBJECT (container, "Not emitting 'child-removed' signal as child" + " removal happend during 'child-added' signal emission"); + } gst_object_unref (child); return TRUE; diff --git a/ges/ges-timeline.c b/ges/ges-timeline.c index e45106ce1c..8eabdbd3cb 100644 --- a/ges/ges-timeline.c +++ b/ges/ges-timeline.c @@ -2276,13 +2276,14 @@ clip_track_element_added_cb (GESClip * clip, if (!tracks || tracks->len == 0) { GST_WARNING_OBJECT (timeline, "Got no Track to add %p (type %s), removing" - " from clip", + " from clip (stopping 'child-added' signal emission).", track_element, ges_track_type_name (ges_track_element_get_track_type (track_element))); if (tracks) g_ptr_array_unref (tracks); + g_signal_stop_emission_by_name (clip, "child-added"); ges_container_remove (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (track_element)); @@ -2306,8 +2307,9 @@ clip_track_element_added_cb (GESClip * clip, } } else { GST_INFO_OBJECT (clip, "Already had a Source Element in %" GST_PTR_FORMAT - " of type %s, removing new one.", track, - G_OBJECT_TYPE_NAME (track_element)); + " of type %s, removing new one. (stopping 'child-added' emission)", + track, G_OBJECT_TYPE_NAME (track_element)); + g_signal_stop_emission_by_name (clip, "child-added"); ges_container_remove (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (track_element)); } @@ -2331,8 +2333,9 @@ clip_track_element_added_cb (GESClip * clip, continue; } else { GST_INFO_OBJECT (clip, "Already had a Source Element in %" GST_PTR_FORMAT - " of type %s, removing new one.", track, - G_OBJECT_TYPE_NAME (track_element)); + " of type %s, removing new one. (stopping 'child-added' emission)", + track, G_OBJECT_TYPE_NAME (track_element)); + g_signal_stop_emission_by_name (clip, "child-added"); ges_container_remove (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (track_element)); }