[PATCH] wl_shell: Add surface state changed event

Pekka Paalanen ppaalanen at gmail.com
Sun May 19 23:45:12 PDT 2013


On Wed, 15 May 2013 11:37:19 -0700
Mikko Levonmaa <mikko.levonmaa at gmail.com> wrote:

> On Wed, May 15, 2013 at 12:12:43PM -0500, Jason Ekstrand wrote:
> > On Wed, May 15, 2013 at 9:39 AM, Mikko Levonmaa <mikko.levonmaa at gmail.com>
> > wrote:
> > 
> >     This allows the shell to inform the surface that it has changed
> >     state, current supported states are default, minimized, maximized
> >     and fullscreen. The shell implementation is free to interpret the
> >     meaning for the state, i.e. the minimized might not always mean
> >     that the surface is fully hidden for example.
> > 
> > 
> > We cannot simply have the shell telling clients it changed their state.  The
> > clients need to be in control of the state of each surface.  This is because
> > minimizing a client (for example) might not be as simple as hiding a specific
> > window.  Only the client can actually know how to minimize/maximize it.
> 
> Hmm... not sure I fully understand nor agree (perhaps lack of
> understanding;). So to me it seems that the compositor should be the
> driver, not the passenger, i.e. it know how to animate the surface when
> it gets minimized and when maximied. How would the client know this?
> Also wouldn't this imply more knowledge on the toolkits side as well?

I think this got already clear at other points, but here's a recap:

1. the server suggests a state to the client
2. the client issues a new state with a new drawing etc.
3. the server performs the state change as the client issued

This has to work whether the server-client interaction starts in step 1
or 2. Ever starting at step 3 results almost certainly in some user
visible glitches.

A good example of this is surface resizing:

0. the client asks to start a shell resize operation with a pointer
(drag from a resize handle), and tells from which sides the
resize happens
1. the server suggests a new size, and tells from which sides the
resize happens
2. the client decides to use the new size, or something close to it,
sends a new drawing in the new size, and also tells in which direction
it resized (wl_surface.attach arguments x,y).
3. the server executes the resize and move (in case resized from
top/left) on screen

All that always works whether the interaction starts in steps 0, 1, or
2. It just cannot work without bad user visible effects if it starts in
step 3.

> > Please read earlier min/max discussions or yesterday's IRC logs for more
> > details.
> 
> Neato, seems to be a hot topic, good to see someone else looking into
> this as well. I read through the email and pq's commmets about avoiding flicker
> make sense, so having the compositor and the client be in sync about whats
> going on is needed. Also naturally the client can be the originator, so
> clearly a request is needed. However in some cases the request might not be
> honored by the compositor, especially in an embedded environment. And
> actually also the compositor might only show window only in certain
> state, i.e. fullscreen so having the client full to decline a request
> might not be good either.

"Not honored by a compositor" and the *compositor* misbehaving when a
client does not comply to a state suggestion are not an option. If a
client uses the defined protocol according to the spec, any
misbehaviour is the server's bug.

This may be a little side-step in the topic, but I want this out of my
system now. One thing is that Wayland protocol is very asynchronous, and
it has no "return values". The only possibilities for failing a request
are to disconnect the client with a protocol error, or in some rare
cases just ignoring the request and guarantee that the following
protocol exchange corrects the situation without any user visible
effects. In other words, requests cannot really fail, unless the client
does something illegal, in which case it is fatal.

If we did have "return fail or success" in the protocol, all such
requests would become synchronous. Issuing such a request would always
require an immediate round-trip. Without a round-trip, the client and
the server will generally go out of sync on protocol state, when the
client sends more requests assuming the first request succeeded, and if
it instead fails, how does it track happens with the rest.

I think what you work on here is not something like the cursor change
or move/resize requests, which rely on other protocol to correct for
the state mismatch between the client and the server immediately. These
auto-correcting state mismatches are essentially due to races, and can
be recognized by the requests needing a specific serial number as an
argument.

So, you must design the protocol to pre-emptively avoid requests that
may fail or "not be honored".

In this case, if we really wanted desktop shells that only ever support
just some of the window states, you have to advertise the supported
states beforehand. If a client uses an unsupported state, it will
trigger a protocol error and get disconnected. Not only does this make
the protocol clear, it allows the client to adapt its GUI, e.g. by not
drawing a maximize button, if it would serve no purpose.

If you talk about embedded, I mean *real* embedded and not something
that is a standard-desktop wannabe, then I think you will have a
different shell protocol to begin with. We have to limit the scope of
the desktop shell protocol to the desktop, and I understand drawing the
line is not easy.

With that in mind, "not honoured" is not an option. You MUST honour the
client window state change requests somehow. However, the "somehow" is
a pretty vague definition, and should give enough room for any desktop
style. But if that really is not possible, then, advertise supported
states and design with that.

I also do not think, that when the server suggests a window state to a
client, we should require the client to obey. I do not think we could
write such a specification in a way that it would not be extremely
limiting. Instead, it should really be only a suggestion. So how it
works in practice? I assume the suggestion would originate from some
window manager menu action, and if a client then does not obey, is just
doesn't work. No bad rendering (that is, window state and contents
disagreeing), no protocol errors, no dead kittens. The client simply
refuses (or malfunctions).

There is more to it than this, though. If the server knew, what window
states a client supports on a particular window, it could avoid
exposing e.g. WM menu actions from panel window list that attempt to
do something the client will not do. That needs more protocol. And
in the other direction, we are accustomed to have a WM menu pop up by
right-clicking on a window title bar. How would that work? Do we
communicate all the menu content to a client and let the client draw
and handle the menu, which would need even more protocol, or do we just
have one request "pop up the WM window actions menu at this point" and
then the server somehow gets the menu up (in weston case,
weston-desktop-shell would draw it)?

I hope we can still design all this piece by piece, since coming up
with a grand total design from scratch is too slow and cumbersome.


With "Look, I can fly!" amount of hand-waving, ;-)
thanks,
pq

PS. Please use reply-to-all.


More information about the wayland-devel mailing list