From b887bddbb17c6d08292537171be81e98d4d0a476 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Tue, 3 Jun 2008 20:15:11 +0000 Subject: [PATCH] Applied patch from bug #947 * clutter/clutter-stage.c (clutter_stage_get_default): Don't grab the floating reference when creating the default stage. The stage manager will take a reference to it so it will behave as any other stage. (clutter_stage_new): Don't take the floating reference to the new stage but let the stage manager keep it instead. * clutter/clutter-stage-manager.c (_clutter_stage_manager_add_stage): Take a reference to the stage when it is added to the list. (_clutter_stage_manager_remove_stage): Unref the stage when it is removed from the list. (clutter_stage_manager_dispose): Keep track of the 'next' pointer as a separate variable so we can cope when the stage being destroyed removes itself from the list as the list is being iterated. * clutter/clutter-actor.c (clutter_actor_destroy): Take a reference at the beginning of the function even if there is no parent container so that overall the reference count is not changed when the actor is unref'd again at the bottom of the function. Previously it would have a net effect of leaving the reference count alone unless it is a top level actor in which case it would unref it. --- ChangeLog | 29 +++++++++++++++++++++++++++++ clutter/clutter-actor.c | 7 +++---- clutter/clutter-stage-manager.c | 15 ++++++--------- clutter/clutter-stage.c | 22 ++++++++-------------- 4 files changed, 46 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index a4333dcb4..de9ecb975 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2008-06-03 Neil Roberts + + Applied patch from bug #947 + + * clutter/clutter-stage.c (clutter_stage_get_default): Don't grab + the floating reference when creating the default stage. The stage + manager will take a reference to it so it will behave as any other + stage. + (clutter_stage_new): Don't take the floating reference to the new + stage but let the stage manager keep it instead. + + * clutter/clutter-stage-manager.c + (_clutter_stage_manager_add_stage): Take a reference to the stage + when it is added to the list. + (_clutter_stage_manager_remove_stage): Unref the stage when it is + removed from the list. + (clutter_stage_manager_dispose): Keep track of the 'next' pointer + as a separate variable so we can cope when the stage being + destroyed removes itself from the list as the list is being + iterated. + + * clutter/clutter-actor.c (clutter_actor_destroy): Take a + reference at the beginning of the function even if there is no + parent container so that overall the reference count is not + changed when the actor is unref'd again at the bottom of the + function. Previously it would have a net effect of leaving the + reference count alone unless it is a top level actor in which case + it would unref it. + 2008-06-03 Matthew Allum * clutter/glx/clutter-glx-texture-pixmap.c: diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index f0b89300d..f90fefd5c 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -2488,15 +2488,14 @@ clutter_actor_destroy (ClutterActor *self) priv = self->priv; + g_object_ref (self); + if (priv->parent_actor) { ClutterActor *parent = priv->parent_actor; if (CLUTTER_IS_CONTAINER (parent)) - { - g_object_ref (self); - clutter_container_remove_actor (CLUTTER_CONTAINER (parent), self); - } + clutter_container_remove_actor (CLUTTER_CONTAINER (parent), self); else priv->parent_actor = NULL; } diff --git a/clutter/clutter-stage-manager.c b/clutter/clutter-stage-manager.c index 9e8225993..b6cc32a72 100644 --- a/clutter/clutter-stage-manager.c +++ b/clutter/clutter-stage-manager.c @@ -67,13 +67,14 @@ static void clutter_stage_manager_dispose (GObject *gobject) { ClutterStageManager *stage_manager; - GSList *l; + GSList *l, *next; stage_manager = CLUTTER_STAGE_MANAGER (gobject); - for (l = stage_manager->stages; l; l = l->next) + for (l = stage_manager->stages; l; l = next) { ClutterActor *stage = l->data; + next = l->next; if (stage) clutter_actor_destroy (stage); @@ -245,12 +246,8 @@ _clutter_stage_manager_add_stage (ClutterStageManager *stage_manager, return; } - /* Refing currently disabled as - * - adding/removing internal to clutter and only stage does this - * - stage removes from manager in finalize (and how can it with ref) - * - Maybe a safer way - * g_object_ref_sink (stage); - */ + g_object_ref_sink (stage); + stage_manager->stages = g_slist_append (stage_manager->stages, stage); if (!default_stage) @@ -282,5 +279,5 @@ _clutter_stage_manager_remove_stage (ClutterStageManager *stage_manager, g_signal_emit (stage_manager, manager_signals[STAGE_REMOVED], 0, stage); - /* g_object_unref (stage); */ + g_object_unref (stage); } diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 55f328eb6..1113709ed 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -651,13 +651,11 @@ clutter_stage_get_default (void) stage = clutter_stage_manager_get_default_stage (stage_manager); if (G_UNLIKELY (stage == NULL)) - { - /* this will take care of automatically adding the stage - * to the stage manager and setting it as the default - */ - stage = g_object_new (CLUTTER_TYPE_STAGE, NULL); - g_object_ref_sink (stage); - } + /* This will take care of automatically adding the stage to the + * stage manager and setting it as the default. Its floating + * reference will be claimed by the stage manager. + */ + stage = g_object_new (CLUTTER_TYPE_STAGE, NULL); return CLUTTER_ACTOR (stage); } @@ -1631,8 +1629,6 @@ clutter_fog_get_type (void) ClutterActor * clutter_stage_new (void) { - ClutterActor *retval; - if (!clutter_feature_available (CLUTTER_FEATURE_STAGE_MULTIPLE)) { g_warning ("Unable to create a new stage: the %s backend does not " @@ -1641,11 +1637,9 @@ clutter_stage_new (void) return NULL; } - retval = g_object_new (CLUTTER_TYPE_STAGE, NULL); - if (retval) - return g_object_ref_sink (retval); - - return NULL; + /* The stage manager will grab the floating reference when the stage + is added to it in the constructor */ + return g_object_new (CLUTTER_TYPE_STAGE, NULL); } /**