1
0
Fork 0

clutter: Remove DELEGATE_LAYOUT allocation flag

The CLUTTER_DELEGATE_LAYOUT flag is unintuitive and makes the allocation
process inside Clutter unnecessarily complicated. It's very easy for
actors overriding the allocate() vfunc to layout their children
themselves (in fact most of them do this), and it also never made sense
that clutter_actor_set_allocation() does eventually layout children.

There was no ClutterActor implementation in mutter or gnome-shell which
actually used the DELEGATE_LAYOUT flag, but even without it, it's fairly
easy to archive the same behavior now: In the allocate() override,
adjust the allocation as wanted, then chain up to the parent vfunc
without calling clutter_actor_set_allocation().

So remove the CLUTTER_DELEGATE_LAYOUT flag, which will allow making the
relayout code in Clutter a bit easier to follow.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1245
This commit is contained in:
Jonas Dreßler 2020-05-09 18:35:15 +02:00 committed by verdre
parent 4729cb779e
commit 24d7a7ad0b
3 changed files with 9 additions and 114 deletions

View file

@ -2649,43 +2649,9 @@ clutter_actor_maybe_layout_children (ClutterActor *self,
{
ClutterActorPrivate *priv = self->priv;
/* this is going to be a bit hard to follow, so let's put an explanation
* here.
*
* we want ClutterActor to have a default layout manager if the actor was
* created using "g_object_new (CLUTTER_TYPE_ACTOR, NULL)".
*
* we also want any subclass of ClutterActor that does not override the
* ::allocate() virtual function to delegate to a layout manager.
*
* finally, we want to allow people subclassing ClutterActor and overriding
* the ::allocate() vfunc to let Clutter delegate to the layout manager.
*
* on the other hand, we want existing actor subclasses overriding the
* ::allocate() virtual function and chaining up to the parent's
* implementation to continue working without allocating their children
* twice, or without entering an allocation loop.
*
* for the first two points, we check if the class of the actor is
* overridding the ::allocate() virtual function; if it isn't, then we
* follow through with checking whether we have children and a layout
* manager, and eventually calling clutter_layout_manager_allocate().
*
* for the third point, we check the CLUTTER_DELEGATE_LAYOUT flag in the
* allocation flags that we got passed, and if it is present, we continue
* with the check above.
*
* if neither of these two checks yields a positive result, we just
* assume that the ::allocate() virtual function that resulted in this
* function being called will also allocate the children of the actor.
*/
if (CLUTTER_ACTOR_GET_CLASS (self)->allocate == clutter_actor_real_allocate)
goto check_layout;
if ((flags & CLUTTER_DELEGATE_LAYOUT) != 0)
goto check_layout;
return;
check_layout:
@ -2693,7 +2659,6 @@ check_layout:
priv->layout_manager != NULL)
{
ClutterContainer *container = CLUTTER_CONTAINER (self);
ClutterAllocationFlags children_flags;
ClutterActorBox children_box;
/* normalize the box passed to the layout manager */
@ -2701,13 +2666,6 @@ check_layout:
children_box.x2 = (allocation->x2 - allocation->x1);
children_box.y2 = (allocation->y2 - allocation->y1);
/* remove the DELEGATE_LAYOUT flag; this won't be passed to
* the actor's children, since it refers only to the current
* actor's allocation.
*/
children_flags = flags;
children_flags &= ~CLUTTER_DELEGATE_LAYOUT;
CLUTTER_NOTE (LAYOUT,
"Allocating %d children of %s "
"at { %.2f, %.2f - %.2f x %.2f } "
@ -2723,7 +2681,7 @@ check_layout:
clutter_layout_manager_allocate (priv->layout_manager,
container,
&children_box,
children_flags);
flags);
}
}
@ -10344,13 +10302,8 @@ clutter_actor_allocate (ClutterActor *self,
* This function can only be called from within the implementation of
* the #ClutterActorClass.allocate() virtual function.
*
* The allocation should have been adjusted to take into account constraints,
* alignment, and margin properties. If you are implementing a #ClutterActor
* subclass that provides its own layout management policy for its children
* instead of using a #ClutterLayoutManager delegate, you should not call
* this function on the children of @self; instead, you should call
* clutter_actor_allocate(), which will adjust the allocation box for
* you.
* The allocation @box should have been adjusted to take into account
* constraints, alignment, and margin properties.
*
* This function should only be used by subclasses of #ClutterActor
* that wish to store their allocation but cannot chain up to the
@ -10358,59 +10311,6 @@ clutter_actor_allocate (ClutterActor *self,
* #ClutterActorClass.allocate() virtual function will call this
* function.
*
* It is important to note that, while chaining up was the recommended
* behaviour for #ClutterActor subclasses prior to the introduction of
* this function, it is recommended to call clutter_actor_set_allocation()
* instead.
*
* If the #ClutterActor is using a #ClutterLayoutManager delegate object
* to handle the allocation of its children, this function will call
* the clutter_layout_manager_allocate() function only if the
* %CLUTTER_DELEGATE_LAYOUT flag is set on @flags, otherwise it is
* expected that the subclass will call clutter_layout_manager_allocate()
* by itself. For instance, the following code:
*
* |[<!-- language="C" -->
* static void
* my_actor_allocate (ClutterActor *actor,
* const ClutterActorBox *allocation,
* ClutterAllocationFlags flags)
* {
* ClutterActorBox new_alloc;
* ClutterAllocationFlags new_flags;
*
* adjust_allocation (allocation, &new_alloc);
*
* new_flags = flags | CLUTTER_DELEGATE_LAYOUT;
*
* // this will use the layout manager set on the actor
* clutter_actor_set_allocation (actor, &new_alloc, new_flags);
* }
* ]|
*
* is equivalent to this:
*
* |[<!-- language="C" -->
* static void
* my_actor_allocate (ClutterActor *actor,
* const ClutterActorBox *allocation,
* ClutterAllocationFlags flags)
* {
* ClutterLayoutManager *layout;
* ClutterActorBox new_alloc;
*
* adjust_allocation (allocation, &new_alloc);
*
* clutter_actor_set_allocation (actor, &new_alloc, flags);
*
* layout = clutter_actor_get_layout_manager (actor);
* clutter_layout_manager_allocate (layout,
* CLUTTER_CONTAINER (actor),
* &new_alloc,
* flags);
* }
* ]|
*
* Since: 1.10
*/
void

View file

@ -175,9 +175,12 @@ struct _ClutterActor
* @get_preferred_height: virtual function, used when querying the minimum
* and natural heights of an actor for a given width; it is used by
* clutter_actor_get_preferred_height()
* @allocate: virtual function, used when settings the coordinates of an
* actor; it is used by clutter_actor_allocate(); it must chain up to
* the parent's implementation, or call clutter_actor_set_allocation()
* @allocate: virtual function, used when setting the coordinates of an
* actor; it is used by clutter_actor_allocate(); when overriding this
* function without chaining up, clutter_actor_set_allocation() must be
* called and children must be allocated by the implementation, when
* chaining up though, those things will be done by the parent's
* implementation.
* @apply_transform: virtual function, used when applying the transformations
* to an actor before painting it or when transforming coordinates or
* the allocation; it must chain up to the parent's implementation

View file

@ -560,13 +560,6 @@ typedef enum /*< prefix=CLUTTER_OFFSCREEN_REDIRECT >*/
* @CLUTTER_ABSOLUTE_ORIGIN_CHANGED: Whether the absolute origin of the
* actor has changed; this implies that any ancestor of the actor has
* been moved.
* @CLUTTER_DELEGATE_LAYOUT: Whether the allocation should be delegated
* to the #ClutterLayoutManager instance stored inside the
* #ClutterActor:layout-manager property of #ClutterActor. This flag
* should only be used if you are subclassing #ClutterActor and
* overriding the #ClutterActorClass.allocate() virtual function, but
* you wish to use the default implementation of the virtual function
* inside #ClutterActor. Added in Clutter 1.10.
*
* Flags passed to the #ClutterActorClass.allocate() virtual function
* and to the clutter_actor_allocate() function.
@ -577,7 +570,6 @@ typedef enum
{
CLUTTER_ALLOCATION_NONE = 0,
CLUTTER_ABSOLUTE_ORIGIN_CHANGED = 1 << 1,
CLUTTER_DELEGATE_LAYOUT = 1 << 2
} ClutterAllocationFlags;
/**