Sharing a single wl_display (client) by multiple toolkits

Pekka Paalanen ppaalanen at gmail.com
Mon Mar 25 09:20:16 UTC 2019


On Sat, 23 Mar 2019 12:13:27 +0000
Simon Ser <contact at emersion.fr> wrote:

> On Saturday, March 23, 2019 1:50 PM, Scott Anderson <scott.anderson at collabora.com> wrote:
> > On 22/03/19 8:37 am, Jaroslaw Kubik wrote:
> >  
> > > Hi,
> > > Does wayland-client support sharing a single connection object between
> > > unrelated pieces of code? Such feature could be useful for integrating
> > > multiple toolkits (ie. showing GTK widget in a Qt application). I am trying
> > > to get something similar (but less spectacular) done at the moment, and
> > > I am facing the following issue: When two unrelated pieces of code
> > > (ie. GTK and Qt) use the same wl_display and both create a proxy to a
> > > global object (ie. wl_output), then from the server perspective both these
> > > proxies are indistinguishable. When sending events like wl_surface.enter,
> > > the server has to pick a single wl_resource as an argument. That wl_resource
> > > is bound to a specific wl_output proxy on the client side. If the server
> > > chooses wrong, then the window created and managed by Qt will receive
> > > wl_surface.enter event with wl_output proxy instance that belongs to GTK.
> > > It will attempt to access it's user-data and crash because it's not the data
> > > it is expecting.
> > > In the above scenario the server has no way of knowing which of the proxies
> > > are expected as parameters in any given case. And the client has no way of
> > > "discovering" equivalent proxies in case it would like to straighten it out.
> > > This leads me to believe that the design of the wayland protocol makes it
> > > impossible to share a connection object between unrelated code and that
> > > use-case is simply not supported.
> > > Is that correct? Are there any plans to address this?
> > > Best Regards,
> > > Jaroslaw Kubik  
> >
> > Hi,
> >
> > Wayland can handle this perfectly fine. Separate sections of code can
> > create their own wl_registries and bind their own wl_globals
> > independently of each other, including using different versions of each
> > global. The only requirement is that they use the same wl_display
> > object, otherwise they will actually be two separate clients to the
> > compositor.  
> 
> The question is about "sharing a single connection object". This isn't
> possible, an object (ie. proxy) can only be owned by a single consumer.
> 
> However, it's possible to make pieces of code use different objects,
> and Scott gives here EGL's example. There are over examples too, for
> instance some libraries can draw to a subsurface and the main program
> can attach the subsurface to one of its surfaces.
> 
> tl;dr "sharing an object" is not possible, though the use-case you're
> asking about can probably work.

Hi,

sharing the connection is indeed possible, though currently not too
nice. There are several ways one could go about it in a toolkit. All
solutions depend on compositors sending the relevant event for all
proxies, there is no way a compositor can or even should differentiate
between proxies for the same underlying (global) object. A proxy can
only have one owner, so toolkits need to create their own wl_registry
and from that create their own proxies if they want to do something on
their own. This also puts some implications on protocol extension
design, mind.

One idea is arguably a hack: the first word pointed to by a wl_proxy
userdata could be a magic value, that allows the toolkit to identify
its own userdata.

Another option is for a toolkit to store all potentially confusable
userdata (or wl_proxy) pointers in a hash table, and then check the
hash table if the userdata of a wl_proxy is known.

I touched the topic in "Multiple input handlers" in
https://ppaalanen.blogspot.com/2013/11/sub-surfaces-now.html
It highlights another variant of the same problem: input 'enter'
events, which carry a wl_surface argument.

One more idea that might be interesting is to use
wl_proxy_get_listener() to check that the listener was installed by the
toolkit. If it was, then the userdata is owned by the toolkit as well.
An advantage of this is that the listener is often a static const, so
the overhead of tracking will be insignificant, and the method is
reliable unlike the magic value hack. The disadvantage is that it gets
more complicated if a toolkit has various listeners per object type.

Toolkits do not need to all agree to use the same method. Toolkits only
need to check if the proxy is owned by them. If even one toolkit does
not verify the proxy ownership, it cannot be co-used with any other
toolkit.

To recap, the problem is this:

- There are two toolkits using the same wl_display.
- Each toolkit creates its own wl_registry.
- Each toolkit binds its own wl_output globals, creating separate
  proxies owned by exactly one toolkit.
- When a compositor send wl_surface.enter(wl_output), it will actually
  send one 'enter' for every wl_output proxy that exists for the client
  and the specific wl_output.
- The toolkit who owns the wl_surface, will necessarily receive both
  'enter' events, and it needs to decide which one to use and ignore
  the rest.

It would be very cool to have this problem handled better by
libwayland-client. It might be possible to add more API to set and get
some kind of owner ID, e.g. a void*, which would be easy for toolkits
to use. However, if someone wants to work on this, I would like to see
justification on why using wl_proxy_get_listener() is not practical in
a real use case.


Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20190325/0e429018/attachment.sig>


More information about the wayland-devel mailing list