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.
We should only include the vendored headers for Wayland and libdecor-0 when
we use `so_wrap`, i.e. when we *don't* build against system libraries.
The libdecor-0 pkg-config file includes the `libdecor-0/` prefix already,
so its header should be included without it, and likewise in our so wrappers.
Fixes#102671.
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.
Images don't have RIDs and this way of checking stuff broke the cursor
cache. Let's do like all other platforms and check the resource
reference instead.
Before, we would check both methods together, leading to loops.
Now we track the actual reason we suspended and only unsuspend when
that same reason triggers. For example, if we suspend because of the
suspended flag we'll unsuspend only because it got unset. Conversely, if
we suspend because of a timeout we'll unsuspend only if we get a new
frame event.
We do this because, while some compositors properly report a "suspended"
state (hinting us to stop repainting), most don't and we need a "safety
net" anyways as we do not want to constantly stay at 1fps (the max time
we'll wait before giving up) either.
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.
Godot checks if there's Vulkan or GLES3 support.
If no support is found, it shows an error message.
However the code for this error message is left out when building with
opengl3=no
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.
Features:
- Debug-only tracking of objects by type. See
get_driver_allocs_by_object_type et al.
- Debug-only Breadcrumb info for debugging GPU crashes and device lost
- Performance report per frame from get_perf_report
- Some VMA calls had to be modified in order to insert the necessary
memory callbacks
Functionality marked as "debug-only" is only available in debug or dev
builds.
Misc fixes:
- Early break optimization in RenderingDevice::uniform_set_create
============================
The work was performed by collaboration of TheForge and Google. I am
merely splitting it up into smaller PRs and cleaning it up.
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.
This avoids any assumption from the driver, which would otherwise select
a specific platform and potentially mess up everything, resulting
usually in a display server failure.
Mainly, this fixes auto UI scaling with _single-monitor_ fractional
setups (see the comment in `display_server_wayland.cpp` for more info).
This is the result of a bunch of current limitations, mainly the fact
that the UI scale is static (it's probed at startup) and the fact that
Wayland exposes fractional scales only at the window-level, by design.
The `screen_get_scale` special case should help in 99% of cases, while
the auto UI scale part will unfortunately only help with single-screen
situations, as multi-screen fractional scaling requires dynamic UI
scale changing.