diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index fcab0b6a1..bfb4d8496 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -74,8 +74,8 @@ * clutter_actor_set_width(); or it can have a preferred width and * height, which then allows a layout manager to implicitly size and * position it by "allocating" an area for an actor. This allows for - * actors to be manipulate in both a fixed or static parent container - * (i.e. children of #ClutterGroup) and a more automatic or dynamic + * actors to be manipulated in both a fixed (or static) parent container + * (i.e. children of #ClutterGroup) and a more automatic (or dynamic) * layout based parent container. * * When accessing the position and size of an actor, the simple accessors @@ -880,6 +880,7 @@ clutter_actor_real_map (ClutterActor *self) g_assert (!CLUTTER_ACTOR_IS_MAPPED (self)); CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_MAPPED); + /* notify on parent mapped before potentially mapping * children, so apps see a top-down notification. */ @@ -993,20 +994,29 @@ clutter_actor_real_show (ClutterActor *self) ClutterActorPrivate *priv = self->priv; CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_VISIBLE); + /* we notify on the "visible" flag in the clutter_actor_show() * wrapper so the entire show signal emission completes first * (?) */ clutter_actor_update_map_state (self, MAP_STATE_CHECK); - /* While an actor is hidden the parent may not have allocated/requested - * so we need to start from scratch and avoid the short-circuiting - * in clutter_actor_queue_relayout(). + /* we queue a relayout unless the actor is inside a + * container that explicitly told us not to */ - priv->needs_width_request = FALSE; - priv->needs_height_request = FALSE; - priv->needs_allocation = FALSE; - clutter_actor_queue_relayout (self); + if (priv->parent_actor && + (!(priv->parent_actor->flags & CLUTTER_ACTOR_NO_LAYOUT))) + { + /* While an actor is hidden the parent may not have + * allocated/requested so we need to start from scratch + * and avoid the short-circuiting in + * clutter_actor_queue_relayout(). + */ + priv->needs_width_request = FALSE; + priv->needs_height_request = FALSE; + priv->needs_allocation = FALSE; + clutter_actor_queue_relayout (self); + } } } @@ -1081,6 +1091,8 @@ clutter_actor_real_hide (ClutterActor *self) { if (CLUTTER_ACTOR_IS_VISIBLE (self)) { + ClutterActorPrivate *priv = self->priv; + CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_VISIBLE); /* we notify on the "visible" flag in the clutter_actor_hide() @@ -1089,7 +1101,12 @@ clutter_actor_real_hide (ClutterActor *self) */ clutter_actor_update_map_state (self, MAP_STATE_CHECK); - clutter_actor_queue_relayout (self); + /* we queue a relayout unless the actor is inside a + * container that explicitly told us not to + */ + if (priv->parent_actor && + (!(priv->parent_actor->flags & CLUTTER_ACTOR_NO_LAYOUT))) + clutter_actor_queue_relayout (priv->parent_actor); } } diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index 2f190a5ed..e1622dd85 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -93,21 +93,26 @@ typedef void (*ClutterCallback) (ClutterActor *actor, /** * ClutterActorFlags: - * @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside a toplevel, and all parents visible) + * @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside + * a toplevel, and all parents visible) * @CLUTTER_ACTOR_REALIZED: the resources associated to the actor have been * allocated * @CLUTTER_ACTOR_REACTIVE: the actor 'reacts' to mouse events emmitting event * signals * @CLUTTER_ACTOR_VISIBLE: the actor has been shown by the application program + * @CLUTTER_ACTOR_NO_LAYOUT: the actor provides an explicit layout management + * policy for its children; this flag will prevent Clutter from automatic + * queueing of relayout and will defer all layouting to the actor itself * * Flags used to signal the state of an actor. */ typedef enum { - CLUTTER_ACTOR_MAPPED = 1 << 1, - CLUTTER_ACTOR_REALIZED = 1 << 2, - CLUTTER_ACTOR_REACTIVE = 1 << 3, - CLUTTER_ACTOR_VISIBLE = 1 << 4 + CLUTTER_ACTOR_MAPPED = 1 << 1, + CLUTTER_ACTOR_REALIZED = 1 << 2, + CLUTTER_ACTOR_REACTIVE = 1 << 3, + CLUTTER_ACTOR_VISIBLE = 1 << 4, + CLUTTER_ACTOR_NO_LAYOUT = 1 << 5 } ClutterActorFlags; /** diff --git a/clutter/clutter-group.c b/clutter/clutter-group.c index ef3a5a22c..a0ef32c05 100644 --- a/clutter/clutter-group.c +++ b/clutter/clutter-group.c @@ -441,6 +441,12 @@ clutter_group_init (ClutterGroup *self) self->priv->layout = clutter_fixed_layout_new (); g_object_ref_sink (self->priv->layout); + + /* signal Clutter that we don't impose any layout on + * our children, so we can shave off some relayout + * operations + */ + CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_NO_LAYOUT); } /**