[PATCH 1/2] protocol: Allow versioned message arguments
Alexander Larsson
alexl at redhat.com
Mon May 13 01:23:44 PDT 2013
On ons, 2013-05-08 at 15:40 -0500, Jason Ekstrand wrote:
>
> In short, I think this is far too complex for what it achieves. In
> the case of scaling factor stuff, you can just do it with a second
> event.
I agree that what I posted have some open issues, and it was mostly
meant as a start of a discussion of how to handle this. But I completely
disagree with this. Adding a second event is totally a bad thing. I'll
try to explain my reasoning in this case, but also consider that over
time this will happen in other events too, so the complexity will
accumulate over time.
So, wl_output. This API is meant to be used to find out the initial
monitor geometry and later dynamic updates of it. One of the primary
consumers of this will be GdkScreen/GdkMonitor which is the Gtk+ api
that gives this information. We never want Gtk+ to report some partial
state to the application, so a multi-event geometry notification means
that Gtk+ would have to have some code like:
// just got a geometry event
if (wl_output.version <= 2)
update GdkMonitor based on event
screeen.emit("changed");
else
// Can't update the data or notify until we have all parts
screen.saved_geometry_event_data = event;
screen.waiting_for_geometry_scaling_factor = 1;
There are multiple issues here:
* The code becomes much more complex (imagine a third event added later)
* Message ordering suddenly becomes important
* The client depends on a complex behaviour of the server (send the 2nd
event if wl_output.version > 2) which some compositors may not
implement (due to a bug or mistake) which leads to client
"livelocks".
Or maybe I misunderstood you? Did you mean that the new event would be a
copy of the first event with the extra field added? So, there would be
geometry & geometry2. That would be a lot easier on the client side, all
you have to do is listen to both and fill in a default value for the new
fields in the handler for the old one. There are still some minor issues
in this apprach though:
* You need to send both messages over the wire. (Technically there is
some version negotiation when you bind the wl_output, but I don't think
it seems right that incrementing the output version breaks old code that
used the old geometry event.)
* The two events are separate things that we force the compositor to
handle in the right way, introducing uncertainty in behaviour. With my
patch an old server with a new client will automatically work, and a
compositor building against a newer server library will fail to build
until its fixed to pass the new event members. Without this you may get
compositors that build against the new server version but still don't
emit the new signals.
Now, that doesn't mean we have to implement versioned events the way my
patch does. Its important that we get event versioning right though,
because this is gonna show up more in the future. I think the basic
properties we want from this are:
* It should be easy to update compositors to the new event, just switch
to the new marshaller call with no need to manually handle back compat.
* Old clients should keep working on the new server even though the
server just calls the new event version marshaller.
* New clients should be able to listen to *either* the new event version
or the old version (i.e. allow being lazy on version update), without
having to somehow care about which version the server is.
This can be implemented several ways though, and I agree that the way
the patch did it is very rough on non-C languages. Another approach is
to add a new event that "extends" the old one. I.e. like the "copy the
event and extend it" approach above, but with support from the wayland
machinery itself. That way the client can demarshal old events as the
new one, and the dispatching of the new events can be done for all the
versions of the event. This way we can avoid servers and clients having
to manually support backwards compatibility.
More information about the wayland-devel
mailing list