Commit Graph

30410 Commits

Author SHA1 Message Date
Carlos Garnacho
60ef069aa8 backends/native: Log event modifiers in input event debug output
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3094>
2023-06-26 16:41:50 +02:00
Carlos Garnacho
4b3a38a589 meta: Add docs description to META_DEBUG_INPUT_EVENTS MetaDebugTopic value
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3094>
2023-06-26 16:28:51 +02:00
Jonas Ådahl
ee6f1f9246 seat/impl: Add 'input-events' debug topic
This will log all input events we forward from libinput.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3052>
2023-06-26 12:36:04 +00:00
Jonas Ådahl
d67d22f948 backend: Init settings before initable_init
This means the settings instance is there before the backend backend's
initable_init() function gets called.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3085>
2023-06-23 11:52:08 +00:00
Florian Müllner
9f46258ff9 clutter/actor: Make sure expand_set flags are set correctly
If an actor's expand properties haven't been set explicitly, its
expand flags are computed by traversing its children.

However we currently also traverse into children when explicitly
setting "expand" to FALSE, because that is the default value and
the properties are only marked as explicitly-set when the value
actually changed.

Fix this, so propagating expand flags can be stopped without
hacks like
```c
  g_object_set (actor, "x-expand", TRUE, NULL);
  g_object_set (actor, "x-expand", FALSE, NULL);
``

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3088>
2023-06-22 21:58:23 +02:00
Shmuel Melamud
993c42e11f compositor: Mirror window placement in RTL environment
If RTL environment (such as Hebrew or Arabic) is detected, the usual new
window placement algorithm is mirrored. New windows appear near the
right side of the screen and cascading is built from the top-right
corner of the screen.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1873
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3009>
2023-06-22 13:59:24 +00:00
Sebastian Wick
985d0dc3ab tests/stage-view-tests: Unref clutter timelines
If the timelines don't get destroyed they keep references to frame
clocks. Later tests check for the destruction of those frame clocks and
then can fail if the frame clock is implemented slightly differenty.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3084>
2023-06-20 23:19:28 +00:00
Pascal Nowack
712c9a1700 screencast: Do not stop remote desktop session when a stream closes
In remote desktop sessions, streams can be created and destroyed
on-the-fly.
If a stream is gone, it is not necessarily an error.
So, don't treat that situation like an erroneous one.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2911>
2023-06-20 20:13:47 +00:00
Bilal Elmoussaoui
01ecaf10ef cogl: Drop debug helper for generating an image of the atlas
As it is the only place where cogl depends directly on cairo minus
the whole cairo_region_t.

The motivation behind the removal of this helper is to reduce the usage
of cairo in libmutter is to potentially completely drop it in
certain places or replace it with pixman.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3079>
2023-06-20 15:53:48 +00:00
Dor Askayo
56580ea7c9 backends/native: Assume zero rendering time for direct scanout buffers
The previous logic didn't work correctly at least when priority-based
preeption wasn't supported by the DRM driver, such as in the case
of amdgpu. The call to glGetQueryObjecti64v would block on client
work which is already in progress (most likely for the next frame)
and delay notifying the ClutterFrameClock about presentation.

Conveniently, the Wayland transactions mechanism guarantees that all
fences of a dma-buf buffer are signalled before the buffer is
included in a frame, which means that dma-buf buffers are ready for
presentation when being directly scanned-out.

Direct scanout is only supported for dma-buf buffers too, which means
that all buffers going through direct scanout are effectively ready
and require no GPU rendering before presentation.

Assuming zero rendering time for dma-buf buffers going through direct
scanout simplifies the code and removes the need for
glGetQueryObjecti64v, thus avoiding the aforementioned issue where it
could block for longer than expected.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2766
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3080>
2023-06-20 15:32:25 +00:00
Dor Askayo
e30eb78891 clutter/frame-clock: Treat GPU rendering duration of 0 as valid
This is expected for the common case of direct scanout of Wayland
buffers where transactions guarantee that all buffer fences are
signalled before a buffer is included in a frame.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3080>
2023-06-20 15:32:25 +00:00
Dor Askayo
b43fb9fd98 cogl/onscreen/egl: Record CPU time only when GPU time can be queried
These are only useful together at the moment.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3080>
2023-06-20 15:32:25 +00:00
Daniel van Vugt
e7a210d963 clutter/frame-clock: Add dispatch jitter to frame timing measurements
Dispatch jitter is how much the dispatch interval has changed between
frames. It's a measure of sampling smoothness for events that are occurring
at a higher rate than the screen is refreshing:

 * Mouse movement
 * Clients rendering at swap interval zero
 * Keyframe animation position

Zero jitter is ideal but will practically never happen, and a jitter value
of several thousand microseconds will be visible to the naked eye as stutter
even if you're maintaining a perfect frame rate.

To make the numbers easier to interpret we also log the jitter as a
percentage of the refresh interval.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3082>
2023-06-20 10:35:51 +00:00
Daniel van Vugt
be0aa2976e clutter/frame-clock: Avoid rapidly toggling dynamic max render time
This could happen when moving the cursor over GUIs that only redraw
in response to cursor movement. Mutter would experience alternating
cursor-only updates and page flips, and so the `max_render_time_allowed_us`
would jump between pessimised and optimised resulting in inconsistent
frame pacing.

Aside from fixing the smoothness problem this should also provide
lower latency cursor movement.

Fixes: https://launchpad.net/bugs/2023766
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3074>
2023-06-20 09:47:23 +00:00
Florian Müllner
5e5065c2b5 ci: Use libadwaita from git
The extensions app now depends on a development version of
libadwaita, so include it in the image.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3081>
2023-06-19 21:11:07 +02:00
Florian Müllner
c8b019a265 ci: Check out virtme-ng tag instead of branch
The upstream branch is gone, so use the corresponding tag instead.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3081>
2023-06-19 21:11:07 +02:00
Carlos Garnacho
c858ad7f91 wayland: Unset keyboard focus if surface is destroyed
Depending on the ordering of the surface-associated resources
being destroyed, we may fall into the following situation:

 - wl_surface is destroyed
 - destruction notifications for the surface runs
 - The MetaWaylandKeyboard attempts to synchronize the window
   focus
 - The MetaWindow is not destroyed yet, so the focused window
   remains the same, and the MetaWaylandKeyboard keeps the same
   focus MetaWaylandSurface.
 - wl_surface finalizes destruction, MetaWaylandSurface now has
   a NULL resource
 - xdg_toplevel destructor kicks in, it unmanages the window
 - The current focus window is again looked up, forced to look
   a different window
 - The MetaWaylandKeyboard focus now changes, tries to leave the
   old surface, but it has a NULL resource already, and raises
   a protocol error.

If the order is inverted, the window being unmanaged triggers a
focus change into a different window, the MetaWaylandKeyboard
triggers a focus change while the MetaWaylandSurface is still
intact, it succeeds, and the window gets properly destroyed.

In order to make this independent of the order, it makes sense
to make MetaWaylandKeyboard do like the other objects tracking
focus surfaces, and have it care of its own little parcel. The
surface destructor changed to simply unsetting the keyboard focus
to NULL (guaranteeing that the old focus is left while the surface
resource is still up), and leaving potential focus changes to
the xdg_toplevel_destructor->unmanage->update_focus paths.

Doing that alone is basically a revert of commit 228d681b, thus
is still subject to keyboard focus being lost after a popup is
destroyed. Change the approach to trigger the focus sync (and
new focus surface lookup) so it happens from xdg_popup_destructor
specifically to popups and alike xdg_toplevel.

Fixes: 228d681b ("wayland: Trigger full focus sync after keyboard focus surface is destroyed")

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2853
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3077>
2023-06-19 13:13:54 +00:00
Florian Müllner
a95a3a0d30 prefs: Remove titlebar-font preference
It has been unused since decorations moved into the frames client.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3075>
2023-06-15 16:51:20 +00:00
Carlos Garnacho
c01580cec6 clutter: Remove some unused code
The drag actors were practically unused, and became wholly
unused API with commit eb6e1f694a. There is no provision for
using this in the future, so drop this internal API.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3058>
2023-06-15 16:27:48 +00:00
Sebastian Wick
87bd574598 core/window: Change MRU behavior for windows on secondary output
Current behavior pushes a window which receives focus to the start of
the MRU list on every workspace it is on. By focusing a sticky window
the default focus on all other workspaces changes as well. This is fine
for sticky windows explicitly marked as sticky by the user but if a
window is on a secondary output and workspaces are only on the primary
output the behavior is unexpected. Instead we want the window to be the
default focus only on the current workspace but also keep those windows
in a relative MRU order to each other on all workspaces.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2681
Fixes: 058981dc1 ("workspace: Focus the default window only if no window is focused")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2909>
2023-06-15 12:39:58 +02:00
Sebastian Wick
3bbff537d9 Revert "workspace: Focus the default window only if no window is focused"
This reverts commit 058981dc12.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2909>
2023-06-15 12:09:31 +02:00
Dor Askayo
a738132486 profiler: Actually free ThreadInfo when a thread unregisters
The previous commit only freed the list node.

Fixes: a731017ec ("profiler: Free ThreadInfo when a thread unregisters")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3078>
2023-06-14 23:54:41 +03:00
Dor Askayo
edc5d2a933 profiler: Free ThreadInfo when a thread unregisters
This avoids leaking the the ThreadInfo object when a thread unregisters.

Fixes: e16d68372 ("profiler: Add API to register profiler threads")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3076>
2023-06-14 19:48:12 +03:00
Dor Askayo
f49b2a3c7d profiler: Free ThreadInfo list on MetaProfiler finalize
This avoids use-after-free when handle_start() is called following
handle_stop() during the lifetime of the MetaProfiler. This happens
on repeated profiling sessions using Sysprof.

Fixes: e16d68372 ("profiler: Add API to register profiler threads")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3076>
2023-06-14 19:44:48 +03:00
Carlos Garnacho
bc04fcb89d core: Change MetaWaylandTextInput event forwarding to IMs
We need to juggle with some things here to keep key event ordering
and accounting consistent.

The keyboard internal state changes (and maybe modifier event emission)
happening through meta_wayland_seat_update() should ideally happen
from the same key events that reach the client through wl_keyboard.key,
so that wl_keyboard.modifier events are emitted in the right relative
order to other key events.

In order to fix this, we need to decide at an earlier point whether
the event will get processed through IM (and maybe be reinjected),
thus ignored in wait of IM-postprocessed events.

This means we pay less attention to whether events are first-hand
hardware events for some things and go with the event that does
eventually reach to us (hardware or IM).

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5890
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3044>
2023-06-13 14:21:41 +00:00
Carlos Garnacho
eaa09be17c wayland: Account for doubly pressed/released keys in MetaWaylandKeyboard
Given the presence of IMs and the different paths in event handling to reach
one of them, we cannot make guesses about whether should stick to the original
hardware-triggered event, or wait/prefer a second hand IM event that might or
might not arrive. We also have no say for other IM foci unrelated to wayland
(e.g. ClutterText) triggering the double event emission.

So go with it and maintain our own internal state for keys, we already kinda
do, but mainly for warning purposes, at the time of updating the
MetaWaylandKeyboard state.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3044>
2023-06-13 14:21:41 +00:00
Carlos Garnacho
7b26aab08d wayland: Add compositor API to get the text input object
We need to open code a bit the event handling of MetaWaylandTextInput,
in order to avoid out of order events.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3044>
2023-06-13 14:21:41 +00:00
Carlos Garnacho
7716b62fa2 clutter: Separate ClutterInputFocus event processing and filtering
Currently, we let the same function handle key event filtering as they
are passed to the IM, and the IM events resulting in actions like text
commit or preedit changes.

Split these two aspects into filter/process functions, and port
ClutterText to it. MetaWaylandTextInput still handles everything in
a single place, but that will be split in later commits.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3044>
2023-06-13 14:21:41 +00:00
Carlos Garnacho
ff4953caa6 wayland: Remove redundant ifdef
It's already surrounded by the same ifdef

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3044>
2023-06-13 14:21:41 +00:00
Jonas Ådahl
63767df59a backend: Initialize cursor renderer position too
This means initializing the pointer position in MetaSeatImpl
synchronously too, otherwise it's not guaranteed querying the seat state
will result in the expected position.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3071>
2023-06-13 13:22:59 +00:00
Jonas Ådahl
0b0f863428 seat/native/impl: Also init core pointer coordinates
Otherwise clutter_seat_query_state() doesn't give us the expected value,
since it doesn't check the seat pointer coordinates.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3071>
2023-06-13 13:22:59 +00:00
Michel Dänzer
4d664fd797 output/kms: Use meta_kms_connector_get_preferred_mode in init_output_modes
I have a monitor which can report two preferred modes: 5120x1440@240
and 3840x1080@60. Since they are enumerated in this order by KMS,
init_output_modes would end up using 3840x1080@60 (and it was impossible
to select any 5120x1440 mode in the GNOME display settings).

Fix this by using meta_kms_connector_get_preferred_mode, which returns
the first KMS mode with DRM_MODE_TYPE_PREFERRED.

v2:
* Use meta_kms_connector_get_preferred_mode. (Jonas Ådahl)

Signed-off-by: Michel Dänzer <mdaenzer@redhat.com>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3055>
2023-06-12 18:59:06 +00:00
Jonas Ådahl
49e6ce459c backend: Dispatch initial burst of events synchronously on init
This will consist of device-added events, meaning before init finishes,
we can derive some state that depends on the set of input devices
available on startup, such as cursor visibility.

This avoids cursor visibility switching between hidden and visibility
during startup.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3070>
2023-06-12 18:16:01 +00:00
Jonas Ådahl
27606cf1fb seat/native/impl: Start reading input device events when starting
This opens up for a possibility to handle initial events (devices
discovered on startup) during initialization, meaning we can figure out
a more correct initial state that depends on available input devices.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3070>
2023-06-12 18:16:01 +00:00
Jonas Ådahl
af078264fa backend: Init pointer position with clutter_seat_init_pointer_position()
Also fix a function name and remove an unused struct field.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3070>
2023-06-12 18:16:01 +00:00
Jonas Ådahl
060c4c2dfc clutter/seat: Add API to initialize pointer position
This is different from "warping" as it doesn't necessarily result in a
pointer motion event. This can be helpful during initializing so we can
avoid faked pointer events that would otherwise need to be special cased
to not appear as actual pointer movements.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3070>
2023-06-12 18:16:01 +00:00
Timotej Šulík
97f0e2e691 monitor: Ensure the preferred mode is always included
If there are two display modes present with the same flags,
and one of them is the preferred mode, it could have been
excluded from the resulting list of display modes.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2858
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3061>
2023-06-12 15:26:47 +00:00
Jonas Ådahl
bea2fdc12b profiler: Add missing call to stop profiling
Otherwise the profiling backend (cogl-trace.c) doesn't actually stop,
and will complain if we try to start it up again.

Fixes: ab39eaf131 ("cogl/trace: Make global start/stop more explicit")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3068>
2023-06-12 12:20:38 +00:00
Olivier Fourdan
d65883e0d7 cogl/gl-framebuffer: Remove conditional on HAVE_COGL_GL
By testing the features flag, we can get rid of the conditional build
on HAVE_COGL_GL entirely.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3047>
2023-06-07 07:16:10 +00:00
Olivier Fourdan
c3af4c1b15 cogl/gl-framebuffer: Fail without QUERY_FRAMEBUFFER_BITS
glGetIntegerv() with GL_RED_BITS/GL_GREEN_BITS/GL_BLUE_BITS/etc. is not
supported with the GL core context, so there is no point in falling back
to that without supporting COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS,
as this will cause an GL error.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3047>
2023-06-07 07:16:10 +00:00
Olivier Fourdan
fad240f437 cogl/gl-framebuffer: Match testing features
The function ensure_bits_initialized() in cogl-gl-framebuffer-fbo.c
checks for COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS whereas the same
in cogl-gl-framebuffer-back.c simply checks for the driver being
COGL_DRIVER_GL3.

Change the later to use the COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS
flag as well.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3047>
2023-06-07 07:16:10 +00:00
Olivier Fourdan
a2203df9f4 cogl/gl-framebuffer: Fix inverted test in ensure_bits_initialized()
Cogl's feature COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS is required
to use the GL_FRAMEBUFFER_ATTACHMENT_* queries.

Unfortunately, the test for the availability of the private feature is
actually inverted in ensure_bits_initialized() which causes that whole
portion of code to be ignored, falling back to the glGetIntegerv()
method which isn't supported in core profiles.

As Mesa has recently started to be more strict about these, this causes
the CI tests to fail in mutter.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3047>
2023-06-07 07:16:10 +00:00
Olivier Fourdan
5a83e8ef82 cogl/gl-framebuffer: Fix spurious trailing spaces
Purely cosmetic fix, no functional change.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3047>
2023-06-07 07:16:10 +00:00
Robert Mader
c36f3f0101 clutter/actor: Some code-style fixes
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2679>
2023-06-06 11:41:01 +00:00
Jonas Dreßler
b408be0b1e clutter/actor: Return NULL instead of FALSE when type check fails
Fix a small oversight in clutter_actor_peek_stage_views(), it should return
NULL instead of FALSE when the check fails.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2679>
2023-06-06 11:41:01 +00:00
Jonas Dreßler
26344fb533 clutter/actor: Don't store a second stage-views list for the stage
The stage already maintains its own list of stage-views via
clutter_stage_peek_stage_views(), it's a bit superfluous to copy that list
around all the time into priv->stage_views of ClutterActor. Let's deal with
that by returning clutter_stage_peek_stage_views() when
clutter_actor_peek_stage_views() gets called for the stage.

In order to make sure ClutterActor::stage-views-changed still gets emitted
correctly for the stage, always emit that signal on the ClutterStage when
the stage views get invalidated. This now depends on the backend only
actually invalidating the views and calling
clutter_stage_clear_stage_views() when things have actually changed, but
that should be the case.

This needs a change in one of the stage-views tests, namely the one which
tests stage-view-changed emission on the stage: Here we now see an emission
of stage-views-changed, but that signal emission actually seems correct.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2679>
2023-06-06 11:41:01 +00:00
Jonas Dreßler
2ef4960b4f clutter/actor: Cache absolute modelview matrices
While we're now doing a fairly good job at not needing those matrices
all the time anymore, we still need it multiple times during every paint
cycle, so it definitely makes sense to introduce some caching here.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2679>
2023-06-06 11:41:01 +00:00
Jonas Dreßler
4579e86330 clutter/actor: Avoid always traversing actor tree on finish_layout
With commit 5a565b4258, we changed
clutter_actor_finish_layout() to be not only about updating stage views,
but also take care of updating the visible_paint_volume, for that we
started doing a full tree traversal of all mapped actors.

This can be quite a performance issue, apparently especially on certain
ARM devices, where the simple tree traversal can take as long as 2ms.
This is precious time we need to paint our next frame, so lets do a bit
more work to avoid those useless traversals.

Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/2459

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2679>
2023-06-06 11:41:01 +00:00
Jonas Dreßler
261f516af4 clutter/stage: Avoid queueing stage updates when they're already queued
We're using clutter_stage_schedule_update() now from ClutterActor to kick
off the stage updating machinery when a redraw needs to happen.

This introduced a bunch of unnecessary calls to
clutter_stage_schedule_update() and thus
clutter_stage_view_schedule_update() when multiple actors request redraws
during the same stage update cycle, which is a very common case.

Cut off all those unnecessary calls by bailing out in
clutter_stage_schedule_update() when updates are already queued.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2679>
2023-06-06 11:41:00 +00:00
Jonas Dreßler
d2d730ec0b clutter/actor: Use GArray to store redraw clips
Using a list of heap allocated ClutterPaintVolumes adds quite a bit of
unnecessary overhead: It means for every single redraw clip we allocate a
list and a paint volume on the heap.

Let's avoid all those heap allocations by using a GArray with static
ClutterPaintVolumes instead.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2679>
2023-06-06 11:41:00 +00:00