xdg_surface initial configuration

Michael Forney mforney at mforney.org
Mon Nov 2 13:20:34 PST 2015


On Wed, Sep 23, 2015 at 12:10:02PM -0700, Bill Spitzak wrote:
> Seems like the wl_display.sync() can do the job. The compositor may send
> several configure events, that is harmless. Just use the last one.
> 
> A compositor *may* try to predict where the window is going to be mapped.
> This prediction may change due to methods such as set_app_id. It may also
> change due to actions by other clients or the user which can happen at any
> time (and thus there is no way for the client to put a call after them).
> All of these would send configure events. It is ok that it may send a lot
> of them. Just respond to the last one.

I think that this does not completely solve the problem.

For example, suppose I start client foo, and I have a special rule that
puts foo windows on some other screen. Since the compositor does not yet
know that the client is foo, it sends a configure event to re-tile the
windows to make room for the client on the current screen. It then
receives the set_app_id request and realizes the window should have been
placed on the other screen, so it configures all the windows back to the
way they were before.

The foo client may not have any problems because it is in the middle of
a wl_display_roundtrip, but the other clients may receive the first
event, but not yet the second, causing them to redraw for a new size.
Then they see the original size and redraw the original frame again.
This would cause flicker on the primary screen, even though nothing
changed about those windows.

I suppose that if I delay retiling the other windows until I have
received the initial buffer from the new client, this wouldn't be a
problem, but it would essentially cause the new client resize and the
existing client resize roundtrips to happen sequentially rather than in
parallel. I'll have to do some testing to see if this actually causes
any noticable delay/flicker when retiling due to a new client.

> Note that another client may well do something between that ready() and the
> commit() which means the size will have to change. You have to deal with
> this, so this ready() call is not helping at all.

Just because it doesn't help in these particular cases, doesn't mean it
doesn't help at all. I think it will help in the common case.

> If you are concerned that the compositor may have to display a wrong-sized
> buffer, it can actually delay making the surface appear until a commit of a
> correctly-sized surface is done. This is actually easier than what it has
> to do with already-shown surfaces if the user does a resize: the only way
> to get a glitch-free display there is for the compositor to wait until
> *all* clients send a correctly-sized surface, before updating the composite.
> 
> If you are concerned about the overhead of many configure events, then your
> client is done wrong. Do not do any complex code (such as resizing or
> drawing) until the incoming event queue is empty, or you will have a
> terrible client. This means you are only going to respond to the *last*
> configure.

It's probably not worth worrying too much about broken clients.

> Here is my version of the interaction:
> 
> -> xdg_shell.get_xdg_surface(wl_surface)
> -> xdg_surface.set_title("Foo")
> -> xdg_surface.set_app_id("org.foo.Foo")
> -> xdg_surface.set_maximized()
> -> wl_display.sync()
> ... client waits ...
> <- xdg_surface.configure due to initial creation
> <- xdg_surface.configure due to set_app_id
> <- xdg_surface.configure due to set_maximized
> <- wl_callback.done()
> -> xdg_surface.ack_configure(1)
> -> wl_surface.attach(wl_buffer)
> -> wl_surface.frame()
> -> wl_surface.commit()
> ... client waits ...
> <- xdg_surface.configure due to asynchronous events
> <- wl_callback.done()

Thanks for your suggestions!

-Michael


More information about the wayland-devel mailing list