clap icon indicating copy to clipboard operation
clap copied to clipboard

GUI on Wayland

Open dekrain opened this issue 2 months ago • 15 comments

I'm currently developing a plugin using CLAP. So far, the API seems clean and nice to work with. However. there is a lack of clarification in certain areas. Specifically, the GUI extension suggests support for Wayland plugin windows. Currently, it seems floating windows can be supported, as Wayland doesn't support embedding surfaces between clients. For floating windows, when I receive a clap_window_t in set_transient, what is the expected method of passing the window reference?

Looking around at existing projects, they all only seem to support X11 and not Wayland, so it seems no one has figured that out yet. Maybe Bitwig, but I haven't given it a closer look.

There's currently an experimental Wayland protocol xdg-foreign, which allows clients to export and import toplevels between different clients, for which the compositor generates a sharable string. It additionally provides a method to set the (transient) parent of a surface to the imported toplevel, which is exactly what we need.

The alternative would be to pass the toplevel surface directly, but that requires sharing a connection to the compositor wl_display as well, so it's a bit of a clunky solution. That would additionally allow for window embedding using sub-surfaces.

dekrain avatar Oct 05 '25 14:10 dekrain

So you are breaking new ground - I don’t think any plugin has done this and I’m not sure any daw has supported the APIs implicit in clap gui. But some thoughts here which are not definitive

  1. The floating api doesn’t get handed a window at all I thought. https://github.com/free-audio/clap/blob/69a69252fdd6ac1d06e246d9a04c0a89d9607a17/include/clap/ext/gui.h#L22 So there’s no set parent call. You have to make and manage your own window. So I don’t quite know if going floating why you need to send any data structure
  2. the api has a clap protocol Wayland so if you only respond true to Wayland / floating in supports then you should work as above
  3. The api has an unused void* for the Wayland window type which I suppose is for an embedded style thing tbd. I don’t know if that is used anywhere and it is certainly not worked out
  4. I worry if you do only respond true to Wayland / floating that most daws will as a result not call create but I haven’t tested this personally
  5. I would like to also disclaim this answer as being way more speculative than my answers on clap questions usually are. Like I said this is all super new ground and some experimentation is required. I’ve never seen a Linux clap which isn’t x11 though so again pretty on the edge I think

I bet @abique will have some useful thoughts too

baconpaul avatar Oct 05 '25 19:10 baconpaul

The floating api doesn’t get handed a window at all I thought.

Passing a window for a floating GUI is indeed not required, however hosts can call the set_transient method I mentioned in the post, which does get handed a window handle. It's used to couple the window with the host's application window, so that they pop-up/hide together whether the app window is. This might be of more importance for Wayland, since by default client's can't force their or other's windows to pop-up to front. If the windows are logically coupled, it might be possible to focus the plugin's window when host window is in focus.

For the case when host doesn't intend to pass a window/call set_transient, it doesn't really care what windowing API is used, and so it can just pass null API to create. The windowing system doesn't need to be declared for that to work.

dekrain avatar Oct 06 '25 03:10 dekrain

Hi,

No we shouldn't pass the wl_display* object, as if we do so, we then inherits all the wayland ABI issues.

Wayland is a protocol, and we should solve this issue using the protocol, not pointers.

Last time I've checked, wayland didn't have the equivalent of xembed and the requirement on the host was far too high to be realistic and wayland's dev were strongly opposed to provide a replacement to xembed.

I'm now waiting for someone to come up with a solution for wayland which involves the protocol and no pointers and with a PoC showing that it works. I've tried to talk to wayland devs without success, so someone else will have to try and come back with a better solution than << the host has to implement a full wayland server in order to embed the plugin's window >>.

In the meantime, if the host is X11, you can maybe manage to talk to x11-wayland and find a way, or simply implement a X11 plugin window (x11-wayland is here to stay...).

If you want to make a plugin that works on Linux today, target X11.

EDIT: To clarify my point regarding pointer vs protocol, is that any plugin should be able to statically link the wayland libraries and talk to the display server just by opening the wayland socket. And a plugin built this way today should still work 15 years later.

abique avatar Oct 06 '25 08:10 abique

Wayland is a protocol, and we should solve this issue using the protocol, not pointers.

I agree. In my first post I mentioned there is an unstable protocol that uses strings/handles to pass parent-hood (in the transient window way). I think for now we could suggest just using that for floating windows, and wait for a proper solution to the embedded case to be developed.

In the meantime, if the host is X11, you can maybe manage to talk to x11-wayland and find a way, or simply implement a X11 plugin window (x11-wayland is here to stay...).

I'm not sure about that idea. The way I see it, the xwayland protocol(s) are mostly for communication between the WM and Xwayland itself. Compositors don't even expose them to regular clients. I think this solution too verges on the implementation details more than stable solutions, even though the xwayland interface is supposed to be somewhat stable for compositors.

dekrain avatar Oct 06 '25 09:10 dekrain

We can't promote temporary solutions, as temporary is forever in that context.

We need first a working PoC using stable wayland APIs, then I'll check the code and we can move forward 👍

abique avatar Oct 06 '25 12:10 abique

In case you have missed it, the latest VST SDK release [1] includes (preliminary) Wayland support [2]. It appears to follow the recommendation of a Wayland dev [3] where the host implements a nested compositor which delegates requests/responses to/from the system compositor. (I believe that was the discussion @abique was referring to above).

From the release notes:

Preview Wayland support on Linux (originally written and contributed to VST SDK by PreSonus Software Ltd. and integrated in Studio One Pro 7.2 and higher on Linux):

So it looks like we finally have a working solution to be part of the leading audio plug-in standard and already supported by a major DAW vendor. I admit I'm not deep enough into the Wayland architecture to comment on potential technical flaws with this approach. However, given that no matter which approach you choose the burden to support Wayland on host or plug-in side is considerable, I think that CLAP should seriously consider a similar approach. My fear is that if CLAP decided to go with a substatially different, incompatible approach, this would further increase the effort for vendors (who generally want to support both VST and CLAP) and hence harm adoption.

[1] https://forums.steinberg.net/t/vst-3-8-0-sdk-released/1011988 [2] https://github.com/steinbergmedia/vst3_pluginterfaces/blob/master/gui/iwaylandframe.h [3] https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/74

dwuertz avatar Nov 03 '25 20:11 dwuertz

I think they are doing a mistake. I'm quite surprised to be honest.

They are making VST3's ABI dependent on the wayland library's ABI.

abique avatar Nov 03 '25 21:11 abique

To elaborate, on my system I have libwayland-client.so.0 which means it is at ABI 0.

And I also have: /lib/libxcb.so.1, /lib/libxcb-sync.so.1, /lib/libxcb-util.so.1, /lib/libxcb-xkb.so.1, /lib/libxcb-ewmh.so.2, /lib/libxcb-icccm.so.4, ...

So I conclude that this kind of libraries breaks their ABI sometimes. It didn't happen yet for libwayland-client but it might happen one day.

Also there's the risk that one plugin statically links the wayland client, and then you pass a pointer from one library version to another... 💥

abique avatar Nov 03 '25 22:11 abique

Yeah this is the presonus extension they shipped with S1 linux adopted into VST3

The fact that wayland is not ABI stable means as alex says that this is indeed concerning.

I'm not sure what we should do. Follow Presonus/Fender/Studio1 into that or do something harder and different.

baconpaul avatar Nov 03 '25 22:11 baconpaul

We should probably talk to some wayland devs.

abique avatar Nov 03 '25 23:11 abique

yeah

baconpaul avatar Nov 04 '25 00:11 baconpaul

They are making VST3's ABI dependent on the wayland library's ABI.

Thanks for elaborating. I think I get your point and realized that the implications are actually even more far-reaching than just the risk of a potential future ABI break in libwayland-client. In fact the current API is now strictly tied to a single Wayland client implementation, so for example hosts/plug-ins written in other languages than C/C++ would be forced to use FFI bindings to the C lib instead of some native implemention.

dwuertz avatar Nov 04 '25 20:11 dwuertz

They are making VST3's ABI dependent on the wayland library's ABI.

Thanks for elaborating. I think I get your point and realized that the implications are actually even more far-reaching than just the risk of a potential future ABI break in libwayland-client. In fact the current API is now strictly tied to a single Wayland client implementation, so for example hosts/plug-ins written in other languages than C/C++ would be forced to use FFI bindings to the C lib instead of some native implemention.

Yes, this is actually a good point. Especially since wayland client is auto generated (I believe 🤔) from the protocol description, we can easily imagine that native code could be generated for other popular languages as well (rust?).

We actually have this situation with X11, where you can choose between Xlib and xcb.

abique avatar Nov 05 '25 14:11 abique

This "problem" also affects APIs like Vulkan and EGL. Applications which use those will then be forced to use libwayland-client (or -server). Assuming most GUIs (though not all) will want to use those, they are already forced to use this approach, unless they want to implement window system integration themselves, like firefox mentioned in discussions sending dma-bufs manually, using EGL's GBM backend or Vulkan's object export extensions.

dekrain avatar Nov 06 '25 07:11 dekrain

@dekrain curious why you put problem in quotes? Do you mean to imply that its not a problem and the ABIs will de-facto freeze where we are today?

Getting a set of dynamic libraries which match a build and runtime system for closed source or binary distributed software is the hardest part about support linux in plugins I find.

baconpaul avatar Nov 06 '25 21:11 baconpaul