Instead of using `clutter_actor_get_resource_scale()`, we now deduce the
intended buffer scale from the window by dividing the unscaled size by
the final actor size. This is more correct as while the return value of
`clutter_actor_get_resource_scale()` depends only on the monitor where
the surface resides, the actual scale of the surface is determined
solely by the application itself. `get_resource_scale` will differ from
the actual buffer scale if the application only supports 100% scaling
(Xwayland), or is performing scaling with wp_viewporter (clients using
fractional_scale_v1).
This also fixes a mismatch between the calculated buffer sizes between
`meta_window_actor_get_buffer_bounds` and
`meta_window_actor_blit_to_framebuffer` which causes broken
screencasting for Chromium 114 and later when using the native Ozone
Wayland backend.
Additionally, this commit also changes
`meta_window_actor_blit_to_framebuffer` from using a simple translation
to using an inverted matrix transformation of the transformation matrix
between the parent of the window actor and the surface actor to ensure
maximum sharpness for fractionally scaled windows.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3053>
Previously, restarting mutter in an X11 session resulted in
the previously set color temperature not being applied.
Fix that by applying the color temperature right after
the org.gnome.SettingsDaemon.Color proxy has been created.
Furthermore, only call `update_all_gamma()` from `on_gsd_color_ready()`
when the temperature has actually changed. Otherwise there is no need
since the current temperature has already been (or will soon be) applied
to all ready color devices.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3008>
We'd get a re-entry like scenario when destroying the PipeWire stream
object, where PipeWire would call the stream process vfunc. When this
happened, we had already destroyed the stream, so don't try to dequeue
or anything, just do an early exit. Fixes the following crash in the
test case client:
#0 pw_stream_dequeue_buffer() in /usr/lib64/libpipewire-0.3.so.0.367.0
#1 on_stream_process() at ../src/tests/screen-cast-client.c:348
#2 do_call_process() in /usr/lib64/libpipewire-0.3.so.0.367.0
#3 flush_items() in /usr/lib64/spa-0.2/support/libspa-support.so
#4 loop_invoke() in /usr/lib64/spa-0.2/support/libspa-support.so
#5 impl_send_command.lto_priv.0() in /usr/lib64/libpipewire-0.3.so.0.367.0
#6 suspend_node.lto_priv.0() in /usr/lib64/libpipewire-0.3.so.0.367.0
#7 pw_impl_node_set_state() in /usr/lib64/libpipewire-0.3.so.0.367.0
#8 client_node_removed() in /usr/lib64/pipewire-0.3/libpipewire-module-client-node.so
#9 pw_proxy_destroy() in /usr/lib64/libpipewire-0.3.so.0.367.0
#10 pw_stream_disconnect() in /usr/lib64/libpipewire-0.3.so.0.367.0
#11 pw_stream_destroy() in /usr/lib64/libpipewire-0.3.so.0.367.0
#12 stream_free() at ../src/tests/screen-cast-client.c:530
#13 main() at ../src/tests/screen-cast-client.c:803
#14 __libc_start_call_main() at ../sysdeps/nptl/libc_start_call_main.h:58
#15 __libc_start_main() at ../csu/libc-start.c:360
#16 _start() in /home/jonas/Dev/gnome/mutter/build/src/tests/mutter-screen-cast-client
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3095>
Setting up the image with a custom default user broke gnome-shell's
toolbox images. While running tests as non-root user seems like a
good idea, keeping people's development environment working should
be figured out first.
This partially reverts commit 69cc65d15f.
Keep the image to have a local user and use it to run tests so that
we can ensure that permissions are respected
Co-authored-by: Florian Müllner <fmuellner@gnome.org>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3083>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>