0

I am currently writing a library that can be used by a wayland client software. The library is intended to be mostly independent of the client toolkit (currently only Qt, but other wayland-enabled toolkits should be able to use it as well). It requires only a wl_display pointer passed to the initialization routine, which is retrieved from the GUI toolkit. After the initialization is done, the library should be able to work without contact to the toolkit to make it cross-toolkit compatible.

The problem arises when my library requires a couple of global object proxies (ie. wl_output). The library uses a custom wl_registry to bind custom proxies to required global objects. However, from the server's perspective all proxies to these objects are equivalent. When events that contain object proxies are sent by the server, they may contain either toolkit's or library's proxy reference. This leads to problems because there is no easy way to differentiate these. When the toolkit receives such events, it blindly assumes that the user data of the proxy belongs to the toolkit and uses it, even if the proxy it received belongs to my library.

Is there any way to reconcile such unrelated code, or is such use beyond the scope of the wayland library/protocol and I should re-design my solution?

j_kubik
  • 6,062
  • 1
  • 23
  • 42

1 Answers1

0

Qt Wayland developer here.

When the toolkit receives such events, it blindly assumes that the user data of the proxy belongs to the toolkit and uses it, even if the proxy it received belongs to my library.

Are you sure about this part? When you bind to the global, you create a new proxy object, I don't see how the toolkit can know about this... Or are you talking about the arguments in events sent by globals. I.e. wl_pointer.set_cursor and the like? Would be nice if you could be more specific about what goes wrong...

bobbaluba
  • 3,584
  • 2
  • 31
  • 45
  • Yes, the event parameters is what I mean. The events do not need to be sent by globals, just need to use an argument like that. At the moment I am crashing with Qt because of the `wl_surface.enter` and `wl_surface.leave` events. If I create my own proxy to a `wl_output`, then the events `wl_surface.enter` events may contain either Qt's internal wl_output proxy or the proxy I created. In the latter case Qt will try to access user data on my object and crash. – j_kubik Mar 19 '19 at 02:58
  • @j_kubik, have you tried moving your wl_output proxy to a different event queue? Also, what compositor are you using? – bobbaluba Mar 19 '19 at 08:56
  • My custom proxies are assigned to my own event queue as soon as they are bound. But if I understand the libwayland correctly, this only applies to the events sent to a particular proxy, not to event parameters. The problem is architectural: each wl_proxy on the client side correspond to a wl_resource on the server side. You can have multiple proxies to a particular global, and on the server side the corresponding wl_resource are indistinguishable, server knows only to which client they belong to. When picking the correct wl_resource to send as argument, it has no choice but to pick arbitrarily – j_kubik Mar 19 '19 at 13:06
  • I currently use weston, but I believe the problem is related to the architecture of the libwayland and not to a particular compositor. Iff I have a free moment I will test the behavior under GNOME on fedora. – j_kubik Mar 19 '19 at 13:09
  • I just looked at the code for our compositor APIs, and we do keep a list of wl_resources for each client. I.e. there are multiple proxy objects. Like you say, we just pick the first one and ignore the rest, at least for wl_surface.enter. Maybe file an issue in the libwayland repo? – bobbaluba Mar 20 '19 at 14:29
  • As indicated by my short query on wayland-devel list (https://lists.freedesktop.org/archives/wayland-devel/2019-March/040344.html), the "just pick the first one and ignore the rest" approach is wrong. This means that problem is not within the wayland library, but within both the server and the client code. The server needs to send more events, and the client needs to be able to detect "foregin" proxies as arguments and ignore events that contain it. Do you think this is worthy of filing a Qt bug? – j_kubik Mar 25 '19 at 11:28
  • @j_kubik: On the compositor side, a fix would probably involve getting rid of `QWaylandOutput::resourceForClient` and replace it with a `resourcesForClient`, which should be straightforwawrd. On the client side, however, I guess we'd have to keep a hash of proxies Qt created, which would probably add a bit of overhead and complexity, which is why it's probably a good idea to explain what your use case is when you report the issue. Also, [this issue](https://bugreports.qt.io/browse/QTBUG-74085) is sort related, and you should probably link them as such. – bobbaluba Mar 26 '19 at 12:53
  • As the conversation in the thread I started suggests, it is not necessary to use a hash. You can just check the value of `wl_proxy_get_listener` and compare it against the listener used by Qt. It would probably be best to do it in methods like `QWaylandScreen::fromWlOutput` - they should return null in case the listener is 'wrong'. AFIK Qt uses mostly (only?) dispatchers and not listeners, but the above thread reveals that the raw pointer value is intended to be always the same (ie. both fields share same storage), which should be sufficient for comparisons. – j_kubik Mar 30 '19 at 04:03
  • @j_kubik: I wrote a [patch](https://codereview.qt-project.org/#/c/258788/) for Qt to make it use `wl_proxy_get_listener`, reviews welcome ;) – bobbaluba Apr 17 '19 at 09:15