mirror of
https://github.com/brl/mutter.git
synced 2024-09-20 22:46:02 -04:00
c1951ab17a
Describe (with an example) the ordering and meaning of flags for the size negotiation in ClutterActor.
86 lines
3.2 KiB
Plaintext
86 lines
3.2 KiB
Plaintext
Size negotiation in Clutter
|
|
---------------------------
|
|
|
|
Clutter uses a two-pass size negotiation mechanism. Each parent will ask its
|
|
children (if any) for their preferred size, which will affect the parent's own
|
|
preferred size; once this preferred size query returns to the stage, the stage
|
|
will allocate the size of each child, which in turn will allocate each one of
|
|
their own children, until it reaches the end of the scene graph.
|
|
|
|
The preferred size of an actor is defined through the:
|
|
|
|
get_preferred_width()
|
|
get_preferred_height()
|
|
|
|
virtual functions that should be implemented by every actor. The virtual
|
|
functions will only be invoked if the corresponding flags:
|
|
|
|
needs_width_request
|
|
needs_height_request
|
|
|
|
are set; otherwise, the preferred size will be cached inside ClutterActor
|
|
itself.
|
|
|
|
Actors can inform their parents that their preferred size has changed by using:
|
|
|
|
clutter_actor_queue_relayout()
|
|
|
|
on themselves. This function will "bubble up" through the scene graph, and it
|
|
will clear the:
|
|
|
|
needs_width_request
|
|
needs_height_request
|
|
needs_allocation
|
|
|
|
flags inside the actor and its parents up to the stage.
|
|
|
|
At the beginning of the next frame, the stage will check if there is a relayout
|
|
pending, and it will ask each child for its preferred size; depending on the
|
|
state of the flags, the implementations for the virtual functions:
|
|
|
|
get_preferred_width()
|
|
get_preferred_height()
|
|
allocate()
|
|
|
|
will be invoked in that order. Each parent is responsible for calling
|
|
clutter_actor_allocate() on its children.
|
|
|
|
Example
|
|
-------
|
|
|
|
Let's consider a scene composed by actors following this layout:
|
|
|
|
+---------------------------------------+
|
|
|3 +=============+ +==+ +=============+ |
|
|
| | +-+ +-+ +-+ | | | |2 +-+ +----+ | |
|
|
| | | | | | | | | | | | |1| | | | |
|
|
| | +-+ +-+ +-+ | | | | +-+ +----+ | |
|
|
| +=============+ +==+ +=============+ |
|
|
+---------------------------------------+
|
|
|
|
The actor (1) calls queue_relayout(), which clears the needs_* flags on its
|
|
parent (2), and its grand-parent (3); the state of the other siblings will be
|
|
left untouched.
|
|
|
|
+---------------------------------------+
|
|
|a +=============+ +==+ +=============+ |
|
|
| |b+-+ +-+ +-+ | |f | |g +---+ +--+ | |
|
|
| | |c| |d| |e| | | | | |h | |i | | |
|
|
| | +-+ +-+ +-+ | | | | +---+ +--+ | |
|
|
| +=============+ +==+ +=============+ |
|
|
+---------------------------------------+
|
|
|
|
At the beginning of the following frame, clutter_actor_allocate() will be called
|
|
starting from the actor (a). Since its needs_* flags have been cleared, the
|
|
allocate() virtual function will be invoked. This will cause
|
|
clutter_actor_allocate() to be called on its children, starting from (b). The
|
|
size computed by the parent (a) for its child (b) hasn't changed, and its
|
|
needs_* flags haven't been cleared, so clutter_actor_allocate() will
|
|
short-circuit, and will not cause the implementation of the allocate() virtual
|
|
function for (b) to be called, effectively skipping the branch of the scene
|
|
graph. The same will happen for (f).
|
|
|
|
The child (g) has the same size, but its needs_* flags will have been cleared,
|
|
so its allocate() implementation will be invoked; this will cause the (h) and
|
|
(i) children to be allocated as well.
|