Sub-surface protocol

Bill Spitzak spitzak at gmail.com
Thu Dec 13 18:26:53 PST 2012



John Kåre Alsaker wrote:
> On Thu, Dec 13, 2012 at 11:47 PM, Bill Spitzak <spitzak at gmail.com> wrote:
>> I see no reason for extra objects. What I would do is add a "parent" to the
>> normal surface. If it is NULL then it is a "main" surface. If it points at
>> another surface then it is a subsurface or a floating window. The "parent"
>> can be changed arbitrarily.
> We could also go the other way and add a child pointer, but linked
> lists require more operations to do things like raise a surface above
> another.

The implementation would probably use a linked list of *all* surfaces 
that are visible (ie surfaces belonging to every client). But this would 
be a data structure inside the shell, and has nothing to do with the 
client api.

What I am talking about is the method that the client controls how the 
shell puts surfaces into this sorted list. The surfaces linked by the 
parent pointer have an enforced order that the shell should not mix up. 
But this data has little or nothing to do with the shell order since 
that will contain other surfaces that are not in this linked set.

The simpler api also means the shell has to do less checking. I believe 
in mine the only thing the shell has to watch out for is loops. If the 
client provides a list then it has to make sure a surface is not in 
there twice and that a surface is not in two lists.

>> We must be able to change an existing surface
>> from being a "main" to a "subsurface" to a "floating window" at any time, so
>> making them different types is not acceptable.
> I don't see why we have to be able to change the surface type.

If a window is build up of panes that are docked together, and the user 
is allowed to close either pane, there is a requirement that either pane 
be able to become the main window.

> We should probably have a way to atomically update multiple wl_surface
> anyway (which could be shared for subsurfaces and floating windows).
> Too bad atomicity wasn't added generically to the wayland protocol. We
> wouldn't have to add complexity to the code or protocol.

This is what all the "commit" stuff is about. Everybody is in agreement 
that commit is needed to make subsurfaces work. I also think it will fix 
blinking floating windows with almost zero extra effort if we just make 
them be the same thing!

> Do you have an example of an UI which require the client to be in
> control of the stacking order? If that's really desired it probably
> won't hurt if is shared the stacking order protocol with subsurfaces.

Imagine two main windows and a "toolbox" that is intended to be above 
both of them. When the user attempts to raise one of the main windows, 
the toolbox must remain atop them both. The easiest way to do this is to 
have the client switch the toolbox from remaining above window A to be 
above window B along with the raise of window B (as an atomic operation).

Schemes that let the shell handle this would require the client to send 
an arbitary directed acyclic graph of surfaces, rather than a simple 
list or tree. The clients must still be able to make arbitrary changes 
to this DAG when surfaces are created and destroyed or when state 
changes such that the order must change. I suspect the simpler and more 
intunitive list or tree (instead of a DAG) is a big win even though the 
some clients will need to also make changes on window reorder as well as 
create and destroy and state change.

>> Conversely floating windows have a lot of stuff figured out for focus and
>> event handling, like grabs, and cooperation between tasks and threads. All
>> of this is needed for subwindows so it makes sense to reuse it.
> That's mostly wl_surface things which will "just work" for subsurfaces.

I thought all the grab stuff was wl_shell_surface api?

>> CLIP:
>>
>> Main windows need clip as well. This is so they can draw edge decorations
>> that are clipped off when the window is maximized, rather than having to
>> alter their drawings depending on maximization.
> Most existing toolkits alters and redraws for the maximized state or
> even resizes already.

>> More important surfaces should be able to inverse-clip
> I'm not sure what you mean by that.

I want to allow clients to do partially off-screen surfaces by either 
making the buffer only be the clipped area, or making the buffer be 
full-sized and drawing everything, or by making the buffer be full-sized 
and only drawing the clipped area.

To avoid need for the client and shell to agree on the meaning of lots 
of bits, and to allow the client to choose the approach arbitrarily and 
dynamically change it, I would allow the client to tell the shell that 
the window is "clipped" to a larger rectangle than the wl_surface 
actually has. In a correctly-working client all this extra area is not 
really visible (ie it is outside the boundaries of the output, or hidden 
behind panels).

Maximize would be done by the client telling the shell how thick the 
"edges" of the window are (the part that is not seen when maximized). 
The shell would maximize a window by resizing it so that it is larger 
than the output by the thickness of these edges. The client could then 
notice that the edges are not visible (the shell will also give the 
current visible region) and decide to use a smaller surface without the 
edges. A stupid client might just make a bigger window and the edges 
will be hidden anyway.

This may sound silly compared to 1 bit for maximize, but it quickly 
becomes the practical solution when you start thinking about maximizing 
against 2 or 3 edges of the output, or snapping to other windows or 
against panels.


More information about the wayland-devel mailing list