Window stacking diagram

Pekka Paalanen ppaalanen at gmail.com
Mon Dec 31 03:08:24 PST 2012


On Sun, 30 Dec 2012 16:29:09 -0800
Bill Spitzak <spitzak at gmail.com> wrote:

> Not sure how useful this is, but I made a graph showing the necessary 
> window transitions that Wayland should support, in an attempt to show 
> why "layers" are not sufficient.
> 
> In this example window C must always remain above windows A and B, but 
> there is no other restrictions. There are 8 possible window arrangements 
> where C is above both A and B. This diagram shows all the transitions 
> (the head of the arrows is marked with which window is raised). I would 
> consider it a bug if any of these transitions do not work, especially if 
> it means that not all 8 states can be reached.
> 
> There are several scenarios where the desire to arrange windows like 
> this comes up:
> 
> 1. A and B are two documents, C is a "toolbox" to work on A and B, and D 
> is an unrelated client.
> 
> 2. A and B are two windows in an application, C is a mac-like menubar 
> for that application, and D is an unrelated client (which may have it's 
> own menubar).
> 
> 3. A and B are non-fullscreen windows, C is the "panel", and D is a 
> fullscreen window.
> 
> 4. A and B are normal clients. C is a "notification". D is a client that 
> wants to raise above notifications.
> 
> No current window system supports this correctly:
> 
> 1. A "layer" system, where C is in a "layer" that keeps it above A and 
> B, prevents the blue states.
> 
> 2. A "transient-for" system, with C being transient-for B, does not 
> allow the red states.
> 
> 3. A "layer+application" system such as used on OSX, where A,B,C belong 
> to the same application and C is marked as a "dialog" does not allow the 
> green states.
> 
> Most programs work around these problems by destroying and recreating 
> surfaces (usually C) but this results in on-screen blinking. They also 
> just give up and resort to a single tiled window, in effect implementing 
> their own window manager because they cannot use the system's.
> 
> My proposal is to use a "transient-for" system except to allow the 
> "transient for" to be changed arbitrarily. The client would change C's 
> transient-for between A and B before raising A or B. Otherwise it would 
> just tell Wayland to raise surfaces as they are clicked.
> 
> Other possibilities are:
> 
> 1. Communicate an entire DAG (directed acyclic graph) to the compositor. 
>   Thus the fact that C remains above both A and B is known by the 
> compositor. I don't like this due to the difficulty of clients reliably 
> editing this data structure (such as accidentally not breaking an edge 
> that they don't want).
> 
> 2. Don't send anything, instead the client has a "put A under C" as well 
> as plain raise. This certainly allows any combinations, but does not 
> send useful information about window connections to the compositor, and 
> has race conditions if the windows are from different clients.

Thanks Bill,

that's a nice collection of cases to compare any future stacking
mechanics against. I would like to add some notes.

Layers, as they are in Weston today, are purely an implementation
detail. They are not reflected in any public protocol at all. Therefore
I don't think we are tied in any way to any "layers" design yet. It's
good to keep that in mind and avoid tying our hands with it, I agree.

Any public stacking protocol cannot have references to other clients'
windows. Juggling the stacking order between windows from different
clients must be left as a compositor implementation detail.

It is a bit unclear when you talk about "Wayland". Stacking in this
case is quite unrelated to Wayland the core protocol and libwayland-*
libraries. When we talk about protocol, I would prefer to say wl_shell
in short for "the public desktop shell protocol", just to be explicit.

Quite some time ago there was an idea of some kind of a stacking
negotiation protocol in wl_shell, foremost to solve the problem of
"should this window be raised on click" and similar. Currently we do
not have any stacking related protocol. We only have a few window
types, which only loosely imply something about stacking. The same
idea applies for keyboard focus, by the way (hm, or maybe it was
discussed for kbd focus originally?).

Designing a good re-stacking protocol, which include the "raise or not"
solution, will be quite a trick.

My hunch on the matter is some sort of negotiation with atomic
reassignment of stacking order for all the client's windows. A client
gets an input event, that gives it a chance to "raise" a subset of its
windows and arbitrarily reorder all its windows in the same go. By
"raise" I mean reordering with respect to other clients' windows, which
I think could be just a boolean, raise or not, since it cannot
explicitly refer to other clients' objects. I have no idea how this
protocol should look like, nor if it should have interactions with
wl_surface.commit behaviour. For clarity and easier debugging, I think
we might want to avoid simple protocol requests like "put A on top of
B" since that means the whole protocol history would have to be
replayed to see what the ordering should be, and do the client and the
server agree. But on the other hand, a protocol request for "this is
the ordering of all my windows" raises questions like: is it
inefficient to send a full list of window references for every
re-stacking? What if the client does not include all of its windows?

Ah, a bit more brain dump than I meant to write, but it seems to be a
complex topic.


Disappearing back to his remaining winter holidays,
pq


More information about the wayland-devel mailing list