Window stacking / raising design
Bill Spitzak
spitzak at gmail.com
Thu Jan 26 13:04:03 PST 2012
Bill Spitzak wrote:
> Pekka Paalanen suggested I come up with a design for the Wayland
> compositor to control window stacking and raising.
This is a new version of the proposal, including his ideas for full
screen atomic raise+resize:
COMPOSITOR BEHAVIOR:
The compositor never reorders surfaces itself. It can *only* reorder
them in response to a "raise" command from a client.
RAISE NOTIFY:
If the compositor thinks a surface should be on top, it will send a
"raise notify" to the client that owns the window.
This is NOT sent by mouse clicks. The client must be able to decide
whether to raise a window on click itself, otherwise we cannot implement
usable drag & drop.
I'm not sure if this will ever be used (as opposed to "activation
notify") but it probably should be included for completeness.
RAISE COMMAND:
If a client wants to raise a set of surfaces, it sends a "raise
command". This contains the id of the event that triggered the raise, so
the compositor can produce the correct stacking even if several clients
respond asynchronously. The compositor can expect this in response to
raise, activate, and configure notify, and also mouse down, mouse up,
and keyboard events, and possibly others.
The command contains a list of surfaces indicating the order they must
end up in, from back to front. It also contains a single extra surface
id for the "raised surface" (which is likely equal to one of the windows
in the list), or it can contain None for this.
The compositor must figure out a new stacking order for all the
surfaces. This is done by:
- If the "raised surface" is not None, put it at the top.
- Do not move entry 0 in the list of surfaces.
- For each of entry 1..n in the list of surfaces, see if it is below
entry n-1. If so, move it up to immediately above entry n-1. Otherwise
leave it exactly where it is.
- Mark every surface in the list as "awaiting attach"
- *Stable* sort the list to obey any rules about surface "roles" (put
the sprites on top and desktop on the bottom, etc).
If several raise commands from multiple clients arrive, the compositor
should change the result to match what it would get if it had obeyed
them in triggering event order.
Ideally the compositor must not recompose the main screen until an
"attach" is done for *every* "awaiting attach" window. When the last
"attach" is done it recomposes the screen image.
To avoid it blocking for slow/bad clients, the compositor is also
allowed to do this:
- If the client sends anything other than an "attach" for one of the
"awaiting attach" surfaces, the compositor can assume it screwed up and
just use the old buffers for all the remaining ones.
- It can also do this if the client does nothing for a much longer
(several seconds?) timeout.
- After a short timeout (< 1 second?) the compositor can recompose with
a partial update. All surfaces that are higher than the highest
"awaiting attach" surface can be put on top and composed with their new
buffers. All other surfaces must remain in the order they were and with
their old buffers. This rule will only produce minimal glitches for
antialiased edges and transparent areas.
FULL SCREEN:
- Client sends fullscreen request
- Compositor sends configure notify with new fullscreen size (for the
scaling ones the client is allowed to ignore this and choose a different
size).
- Client sends a raise command, which should include the fullscreen
surface. Compositor can adjust it's stacking rules because it knows the
surface will be full-screen, but any surfaces later in the list must be
atop the fullscreen one!
- Client renders and attaches all the surfaces in the raise command.
- Only now does the screen change to show the results.
ARBITRARY DIALOG CHANGES:
- Client suddenly decides that a whole new set of dialogs is needed,
with different stacking order, size, contents, and some new and removed
ones.
- Client allocates surface id's for all the new ones
- Client sends raise command with everything in the order wanted, but
with "none" for the raised window. For any "don't care about the order"
dialogs the client has kept track of the order they already are in, so
it reuses this order in the raise command
- Client renders and attaches all the surfaces in the raise command.
- Only now does the screen change to show the results
- Client then destroys all the removed surfaces. Since it knows what
order they are in, it should destroy them from back to front, to
minimize glitches. They are also now guaranteed to be below the raised
windows.
NEW WINDOW WITH DIALOGS:
- Client allocates surface id for the new window and all the dialogs
- Client sends raise command with the new window and the dialogs atop it.
- Client renders and attaches all the surfaces in the raise command.
- Only now does the screen change to show the results
More information about the wayland-devel
mailing list