From e57b42ae521406e87c6ed5f9b87d412322074034 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 23 Nov 2007 11:20:14 +0000 Subject: [PATCH] 2007-11-23 Emmanuele Bassi * clutter/clutter-actor.c (clutter_actor_destroy): Bail out if clutter_actor_destroy() was called on the stage: the stage is not for the user to destroy. * clutter/x11/clutter-backend-x11.c: * clutter/eglnative/clutter-backend-egl.c: * clutter/sdl/clutter-backend-sdl.c: * clutter/osx/clutter-backend-osx.c: Unset the top-level private flag on the stage when disposing it, so the backends can safely call clutter_actor_destroy(). * clutter/clutter-private.h: Tweak the private flags accessors, to avoid the typecheck. --- ChangeLog | 16 ++++++++++++++++ clutter/clutter-actor.c | 21 ++++++++++++++++++--- clutter/clutter-private.h | 6 +++--- clutter/eglnative/clutter-backend-egl.c | 2 ++ clutter/osx/clutter-backend-osx.c | 2 ++ clutter/sdl/clutter-backend-sdl.c | 2 ++ clutter/x11/clutter-backend-x11.c | 7 ++++++- 7 files changed, 49 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3bdf0ebf6..e04596f66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2007-11-23 Emmanuele Bassi + + * clutter/clutter-actor.c (clutter_actor_destroy): Bail out + if clutter_actor_destroy() was called on the stage: the stage + is not for the user to destroy. + + * clutter/x11/clutter-backend-x11.c: + * clutter/eglnative/clutter-backend-egl.c: + * clutter/sdl/clutter-backend-sdl.c: + * clutter/osx/clutter-backend-osx.c: Unset the top-level private + flag on the stage when disposing it, so the backends can safely + call clutter_actor_destroy(). + + * clutter/clutter-private.h: Tweak the private flags accessors, + to avoid the typecheck. + 2007-11-22 Emmanuele Bassi * clutter/clutter-label.c (clutter_label_new_full): Set the diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 7ded186ad..6e8b683e2 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -1619,15 +1619,30 @@ clutter_actor_init (ClutterActor *self) * container, the actor will be removed. * * When you destroy a container its children will be destroyed as well. + * + * Note: you cannot destroy the #ClutterStage returned by + * clutter_stage_get_default(). */ void clutter_actor_destroy (ClutterActor *self) { + ClutterActorPrivate *priv; + g_return_if_fail (CLUTTER_IS_ACTOR (self)); - if (self->priv->parent_actor) + if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL) { - ClutterActor *parent = self->priv->parent_actor; + g_warning ("Calling clutter_actor_destroy() on an actor of type `%s' " + "is not possible. This is usually an application bug.", + g_type_name (G_OBJECT_TYPE (self))); + return; + } + + priv = self->priv; + + if (priv->parent_actor) + { + ClutterActor *parent = priv->parent_actor; if (CLUTTER_IS_CONTAINER (parent)) { @@ -1635,7 +1650,7 @@ clutter_actor_destroy (ClutterActor *self) clutter_container_remove_actor (CLUTTER_CONTAINER (parent), self); } else - self->priv->parent_actor = NULL; + priv->parent_actor = NULL; } if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_DESTRUCTION)) diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index 6ed01bb92..67738fba4 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -98,9 +98,9 @@ struct _ClutterMainContext #define CLUTTER_CONTEXT() (clutter_context_get_default ()) ClutterMainContext *clutter_context_get_default (void); -#define CLUTTER_PRIVATE_FLAGS(a) (CLUTTER_ACTOR ((a))->private_flags) -#define CLUTTER_SET_PRIVATE_FLAGS(a,f) G_STMT_START{ (CLUTTER_PRIVATE_FLAGS (a) |= (f)); }G_STMT_END -#define CLUTTER_UNSET_PRIVATE_FLAGS(a,f) G_STMT_START{ (CLUTTER_PRIVATE_FLAGS (a) &= ~(f)); }G_STMT_END +#define CLUTTER_PRIVATE_FLAGS(a) (((ClutterActor *) (a))->private_flags) +#define CLUTTER_SET_PRIVATE_FLAGS(a,f) (CLUTTER_PRIVATE_FLAGS (a) |= (f)) +#define CLUTTER_UNSET_PRIVATE_FLAGS(a,f) (CLUTTER_PRIVATE_FLAGS (a) &= ~(f)) #define CLUTTER_PARAM_READABLE \ G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB diff --git a/clutter/eglnative/clutter-backend-egl.c b/clutter/eglnative/clutter-backend-egl.c index 7ff879627..3cc10788b 100644 --- a/clutter/eglnative/clutter-backend-egl.c +++ b/clutter/eglnative/clutter-backend-egl.c @@ -132,6 +132,8 @@ clutter_backend_egl_dispose (GObject *gobject) if (backend_egl->stage) { + CLUTTER_UNSET_PRIVATE_FLAGS (backend_egl->stage, + CLUTTER_ACTOR_IS_TOPLEVEL); clutter_actor_destroy (backend_egl->stage); backend_egl->stage = NULL; } diff --git a/clutter/osx/clutter-backend-osx.c b/clutter/osx/clutter-backend-osx.c index c3919e6dc..0efe58f44 100644 --- a/clutter/osx/clutter-backend-osx.c +++ b/clutter/osx/clutter-backend-osx.c @@ -24,6 +24,7 @@ #include "clutter-osx.h" #include "clutter-backend-osx.h" #include "clutter-stage-osx.h" +#include "../clutter-private.h" #include #import @@ -145,6 +146,7 @@ clutter_backend_osx_dispose (GObject *object) if (self->stage) { + CLUTTER_UNSET_PRIVATE_FLAGS (self->stage, CLUTTER_ACTOR_IS_TOPLEVEL); clutter_actor_destroy (self->stage); self->stage = NULL; } diff --git a/clutter/sdl/clutter-backend-sdl.c b/clutter/sdl/clutter-backend-sdl.c index 52286cc0f..f06256803 100644 --- a/clutter/sdl/clutter-backend-sdl.c +++ b/clutter/sdl/clutter-backend-sdl.c @@ -148,6 +148,8 @@ clutter_backend_sdl_dispose (GObject *gobject) if (backend_sdl->stage) { + CLUTTER_UNSET_PRIVATE_FLAGS (backend_sdl->stage, + CLUTTER_ACTOR_IS_TOPLEVEL); clutter_actor_destroy (backend_sdl->stage); backend_sdl->stage = NULL; } diff --git a/clutter/x11/clutter-backend-x11.c b/clutter/x11/clutter-backend-x11.c index 7cb8ca9e7..97048a899 100644 --- a/clutter/x11/clutter-backend-x11.c +++ b/clutter/x11/clutter-backend-x11.c @@ -244,7 +244,12 @@ clutter_backend_x11_dispose (GObject *gobject) if (backend_x11->stage) { CLUTTER_NOTE (BACKEND, "Disposing the main stage"); - + + /* we unset the private flag on the stage so we can safely + * destroy it without a warning from clutter_actor_destroy() + */ + CLUTTER_UNSET_PRIVATE_FLAGS (backend_x11->stage, + CLUTTER_ACTOR_IS_TOPLEVEL); clutter_actor_destroy (backend_x11->stage); backend_x11->stage = NULL; }