Hi all,
For some time now I have been working on a Wayland driver for Wine, and it has now reached a good enough state to present it to the wider community. This driver allows users to run Windows GDI and OpenGL applications directly on Wayland compositors without an intermediate layer to translate from X11 to Wayland. This leads to a leaner and more efficient stack.
The code currently resides at:
https://gitlab.collabora.com/alf/wine/-/commits/wayland
Get it with:
$ git clone -b wayland https://gitlab.collabora.com/alf/wine/
Configure with (you need the wayland-client and wayland-egl packages):
$ ./configure --with-wayland
To run, ensure there is a Wayland compositor running, unset DISPLAY (so that Wayland is picked instead of X11) and set WAYLAND_DISPLAY (if needed):
$ DISPLAY= WAYLAND_DISPLAY=wayland-0 ./wine ...
Here is video showcasing a few Windows applications running with the Wayland driver on the Weston reference compositor:
The Wayland protocol is by design more constrained compared to more traditional display systems like X11. These constraints add some special challenges in the integration of Wayland with Win32.
Since Wayland's window model is not based on a single flat 2D co-ordinate space, as X11's was, the Wayland protocol doesn't allow applications to control their absolute position on the screen. For Win32 transient windows (menus, tooltips, etc) the driver tries to work around the lack of absolute positioning by "anchoring" them to an owning Wayland surface and treating them as subsurfaces of that owner. Screen coordinates for such windows are transformed to local coordinates relative to the owning surface, allowing correct placement through relative subsurface movement, which is supported by Wayland. By using heuristics to select the proper owning surface, this approach has led to very good results.
Absolute positioning of non-transient top level windows is not supported at this time, and will likely require a (possibly controversial) Wayland extension if it is to ever be pursued. The lack of absolute positioning also has an adverse effect on input handling, when parts of windows reside outside the visible windows display space, but are still full accessible in the Wayland compositor display space (and thus the user). Input events to such areas don't reach their intended coordinates (are clamped to Windows display bounds) leaving the user mystified about why they are unable to interact with a perfectly visible area in their Wayland compositor. The current partial workaround is to force all windows at (0,0) windows display coordinates, to maximize the area which can be interacted with. With this workaround, and as long as windows remain smaller than the display size, input works without issues.
Here what's supported at the moment (modulo bugs):
* GDI apps, including layered/translucent windows * OpenGL apps * Window resizing * Maximized and fullscreen window states * Mouse and keyboard (only QWERTY) input * Mouse cursors * Menus, tooltips, etc * Single display
What needs more work (or is completely missing):
* Minimize * Better z-order and activation handling * Keyboard layout support * Grabs * GTK menu mouse handling bug (cannot click to select items) * Multiple displays * Vulkan. Note that that there is another effort at https://github.com/varmd/wine-wayland/ focusing solely on vulkan. My hope is that we will be able to share efforts going forward.
Programs I have tried and which are working well (again modulo bugs):
* Native Wine/Win32 apps (notepad, regedit etc) * Supertuxkart * 010Editor * Firefox * Stellarium * Battle For Wesnoth * GIMP (except clicking items in GTK menus as noted above) * Unigine Valley
My first question to the Wine community is how complete the driver should be before being considered for inclusion. Is the current Wayland driver state enough? If there is interest, I was hoping to get the driver in earlier rather than later, in an experimental capacity, in order to provide a single, official point of development for people wanting to contribute.
My second question is about the best way to move forward with upstreaming. The code is currently split between just a few commits, mostly as a result of the experimental nature of this effort, and also because I used existing code from winex11 and wineandroid as my starting point. I would like to split this into smaller commits to make it more review-friendly for the mailing list. I was thinking of splitting by user32 function (and internal dependencies), but since this is going to be an artificial split, I am open to other ideas to make reviewers' lives easier.
Looking forward to your feedback and questions!
Thanks, Alexandros