Fixup to "Wayland: Check selection devices before using them"
This slipped under the radar... until for some reason optimized builds
started crashing, perhaps due to timing-related shenanigans, no idea.
Related #106229. The cursor-shape protocol allows us to not have to deal with cursor theming and instead depend on the
compositor for it.
This still does not quite solve the issue when the compositor doesn't implement the protocol
(or running under the x11 backend) but for gnome/kde and a few more this should resolve things.
In #101774, some libdecor-specific code was added, but without adding the guards. This broke the build with
`libdecor=no`.
Add `#ifdef` guard as necessary.
Before, the WSI was unfortunately quite broken and we had work around it
by manually pacing frames. Needless to say it was not an ideal solution.
Now, the WSI can make use of the new fifo_v1 protocol to work properly.
If it's available, we'll trust the WSI by disabling manual frame pacing.
While we're at it, let's clean up the suspension code a bit by removing
some duplicated stuff and handling the suspension state through a switch
case.
The backend is now mature enough to not explode with multiple windows
but the `DisplayServer` API still cannot meet some guarantees required
by the various Wayland protocols we use. To meet those guarantees this
patch adds three new elements to the DisplayServer API, with relative
handling logic for `Window` and `Popup` nodes:
- `WINDOW_EVENT_FORCE_CLOSE`, which tells a window to *forcefully*
close itself and ensure a proper cleanup of its references, as Wayland
enforces this behavior;
- `WINDOW_FLAG_POPUP_WM_HINT`, which explicitly declares a window as a
"popup", as Wayland enforces this distinction and heuristics are not
reliable enough;
- `FEATURE_SELF_FITTING_WINDOWS`, which signals that the compositor can
fit windows to the screen automatically and that nodes should not do
that themselves.
Given the size of this feature, this patch also includes various
`WaylandThread` reworks and fixes including:
- Improvements to frame wait logic, with fixes to various stalls and a
configurable (through a `#define`) timeout amount;
- A proper implementation of `window_can_draw`;
- Complete overhaul of pointer and tablet handling. Now everything is
always accumulated and handled only on each respective `frame` event.
This makes their logic simpler and more robust.
- Better handling of pointer leaving and pointer enter/exit event
sending;
- Keyboard focus tracking;
- More solid window references using IDs instead of raw pointers as
windows can be deleted at any time;
- More aggressive messaging to window nodes to enforce rects imposed by
the compositor.
This fixes once and for all the core issue of different Godot `keycode`s
released from the same raw XKB keycode.
The `InputEventKey` `keycode` value _should_ map to the "unmodified"
key, but unfortunately there's an ambiguity with their encoding for
"special" keys ("delete", "insert", etc.), in witch they ignore their
unicode representation. This means that a key that is special when plain
but a character when modified would never be properly picked up, so we
do indeed change its keycode. As a consequence of this exception, some
Godot keys never receive release events and get "stuck".
This patch adds an extra check through an `HashMap` to "unstuck" keys
that changed while having the same keycode.
I also could not resist simplifying a bit the regular key event
generation method but this makes things more consistent and predictable
IMO.
There were two edge cases in the frame waiting logic (aka manual frame
throttling or emulated vsync) which would cause the editor to stall in
one way or another:
1. Waiting right after starting the editor would cause a deadlock
between both threads until something happened in the Wayland event
queue, in turn unblocking the Wayland thread and kickstartin the whole
thing;
2. Starting the editor (and probably other long-loading stuff) without
low consumption mode would suspend the window and never commit its
surfaces, thus never signaling the compositor that we want frame events.
The `keycode` field of `InputEventKey` is supposed to be "unshifted";
That is, what the key would output if no modifier keys were pressed.
This should match what's written on the key label, but `Key` enumerates
also all keypad keys, which require a modifier. We thus require some
extra checks for them.
Note that this can still allow "stuck keys", but that's an even deeper
problem.
The v1 version is deprecated and bound to be removed in the future from
all compositors. This patch adds a v1/v2 designator to everything
related to the protocol and prefers the v2 protocol if both are
available.
Additionally, renames the event handler to follow the Wayland interface
name, for consistency with the rest of the codebase.
Initially the WaylandThread cursor code was supposed to be as stateless
as possible but, as time went on, this wasn't possible.
This expectation made the resulting API quite convoluted, so this patch
aims to simplify it substantially bot in terms of API surface and, most
importantly, in terms of actual implementation complexity.
This patch also fixes custom cursors since I accidentally changed the
mmap flags to MAP_PRIVATE some time ago. This took me hours to notice.
While experimenting with the recent "extent to title" PR, I noticed that
it's not guaranteed for a "button released" event to be emitted when
the pointer leaves the main surface, leaving some buttons stuck.
Not doing this for tablets since the spec makes this behavior clear and
explicit, so we (hopefully) shouldn't have this issue there.
Before, multiple capability events would instantiate the same object
over and over as long as its bit was set. This caused issues with
hotplug and device suspension.
This reduces even further the amount of work we have to do when scaling
and potentially improves input accuracy as now the input code is free
from any form of rounding.
Before of this patch, as explained in the usual
commented-wall-of-text-longer-than-the-actual-patch-itself™, due to the
multithreaded nature of the Wayland thread, it was possible to commit a
surface while the renderer was doing stuff, which was _very_ wrong.
Initially the consequences of such a sin weren't obvious but, now that
explicit synchronization is becoming more and more common, we can't
commit a buffer randomly without basically guaranteeing a nasty, nasty
crash (and we should have avoided commits altogether in the first place
to ensure atomic surface updates).
We now only trigger a commit _in the main thread_ when low processor usage
mode is on _and_ if we know that we won't be rendering anything as, due to
its intermittent nature, it makes "legacy" (pre xdg_wm_base v6) frame
callback based suspension quite annoying.
Random-access access to `List` when iterating is `O(n^2)` (`O(n)` when
accessing a single element)
* Removed subscript operator, in favor of a more explicit `get`
* Added conversion from `Iterator` to `ConstIterator`
* Remade existing operations into other solutions when applicable