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); } /**