Squashed version of #57025 laid out for ease of reviewing.
Resolves godotengi…ne/godot-proposals#990.
**See #57025 for further information.**
Not everything is yet implemented, either for Godot or personal limitations (I don't have all hardware in the world). A brief list of the most important issues follows:
- Single-window only: the `DisplayServer` API doesn't expose enough information for properly creating XDG shell windows.
- Very dumb rendering loop: this is very complicated, just know that the low consumption mode is forced to 2000 Hz and some clever hacks are in place to overcome a specific Wayland limitation. This will be improved to the extent possible both downstream and upstream.
**EDIT: better approach available for testing over at #87750**
- Features to implement yet: IME, touch input, native file dialog, drawing tablet (commented out due to a refactor), screen recording.
- Mouse passthrough can't be implement through a poly API, we need a rect-based one.
- The cursor doesn't yet support fractional scaling.
- Auto scale is rounded up when using fractional scaling as we don't have a per-window scale query API (basically we need `DisplayServer::window_get_scale`).
- Building with `x11=no wayland=yes opengl=yes openxr=yes` fails.
This also adds a new project property and editor setting for selecting the default DisplayServer to start, to allow this backend to start first in exported projects (X11 is still the default for now). The editor setting always overrides the project setting.
Special thanks to Drew Devault, toger5, Sebastian Krzyszkowiak, Leandro Benedet Garcia, Subhransu, Yury Zhuravlev and Mara Huldra.
## How to review this PR
Don't let the diff size scare you, it's smaller than you think!
"Wayland" is mostly an IPC; the actual interfaces are defined in XML "protocol" files. It has a very lean core protocol designed to be extended. Each of those XML files is used to generate the C wrappers that the backend uses through an utility named `wayland-scanner` which must be available on the building system (`libwayland-bin` package on Debian). We generate them this way because the result changes between Wayland versions and so it's good practice for all Wayland programs.
The core protocol is present in `thirdparty/wayland` (+3087) and the various extensions are present in `thirdparty/wayland-protocols` (+4303), copied verbatim as in `thirdparty/README.md` (+43).
Talking about `thirdparty`, various dependencies got dynwrapped into `platform/linuxbsd/wayland/dynwrappers` (+1698) and their library headers got put into `thirdparty/linuxbsd_headers/` (+7929), according to `thirdparty/linuxbsd_headers/README.md` (+14).
Note that the dynwrappers are still the handpatched kind, although the latest version of dynload-wrapper, 0.4, should create working equivalents.
Regarding the dependencies, we pull in `wayland-client` (self-explanatory), `wayland-cursor` (cursor handling), `wayland-egl-core` (EGL support) and `libdecor-0` (client-side decorations)
If you're wondering about `libdecor-0`: Wayland allows compositors to not provide SSDs (and thus require CSDs). We don't have yet support for them so I implemented (optional) support for this library that draws CSDs for us. I think that we should eventually implement our own solution (as it's being slowly being done AFAIK) to reap all the benefits of them and, well, to get rid of a dependency and all its handling code :P
As you can see, a good part of the diff (+17048) is actually data or autogenerated stuff. There's not much review that has to be done, outside of a quick glance to verify those claims. I swear I didn't put any malware in there :P
Now we talk about the actually juicy stuff.
Wayland moves a lot of responsibility to the client. Because of that, the logic is actually split between a `DisplayServerWayland` (`platform/linuxbsd/wayland/display_server_wayland.*`, +1615) and a `WaylandThread` (`platform/linuxbsd/wayland/wayland_thread.*`, +4929).
As you can see, most of the Wayland logic is in the thread, which is also probably the hardest to review. It offers various methods (which _don't_ set the internal mutex manually, this has to be done by the caller) and an `InputEvent`-style queue, which gives various notifications to the main thread, like input and rect changes.
The advantage of this design is that we can keep the thing as responsive as possible and that it takes care to translate the information to something that the engine can understand in the same place that it's handled (e.g. HiDPI scaling, `InputEvent` generation). That also moves, well... The main Wayland logic, into one place.
You should be able to understand `DisplayServerWayland` pretty well without any knowledge about the Wayland library, perhaps with the exception of `window_can_draw`. In short, the compositor wants to tell us when to draw, so we do this dirty hack where we set it to `true` only when we get a frame event. This is good enough for now but it will be improved.
Of note there's `platform/linuxbsd/wayland/detect_prime_egl.*` (+296) which is mostly similar to the X11 counterpart, with the exception that it probes up to 4 devices, allowing a bit more of leeway for people with an IGPU, DGPU and a SW rasterizer, as sometimes the DGPU would not be probed at all. That code could be shared somehow but that's a topic for another time I think.
Other than that, there's some plumbing, project/editor setting handling, doc changes, driver implementations (Vulkan, EGL) and licensing information but it should be already familiar to most of us I hope.
That's it really. I hope that this helps with reviewing :)