Gtk is quite buggy and "fluid" in how it handles the shadow margins for
windows under X11. The "size" of the window fluctuate between including and
excluding a shadow margin in a way that causes issues, as there are no
atomic update of any state going on.
In order to avoid running into those particular issues now, lets get rid
of shadows so the margins are always zero, when the client is using the
X11 backend.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
To get some kind of consistency between what 'resize' means for the
compositor and the client, make the size correspond to the "frame rect"
of the window, i.e. the window geometry in the Wayland case, and the
window size including the titlebar in the X11 case.
This is so that the window size later can be reliably compared both in
the compositor and in the client using the same expected dimensions.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
When toying with the test client to try to reproduce issues (e.g.
writing commands on stdin to create and manipulate windows), when you
write a command incorrectly you'll get a warning printed to standard
out. The problem, however, is that it doesn't include a line break in
the end, meaning when you type the correct command, it won't be on a new
line.
Fix this minor annoyance by adding line breaks to all warning messages.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
The test client could already understand the resize command, but they
could not be added to metatests as the command was not properly plumbed
via the test runner. Establish the plumbing for the resize command so
that resize tests can be added.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
We only test the meson-build job, so there's no point to save artifacts for
the other test-build only builds.
So, only save meson logs artifacts (with a default gitlab expiration time)
for the other build-without-* jobs
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1236
While we don't have an high number of tests, we still have some code
coverage and so we can track this via gitlab CI, given that it supports it
natively.
So add gcovr to the DockerFile dependency, build with -Db_coverage=true
meson native parameter, and add another manual job to make ninja to generate
the coverage reports on requests or in any master or tag ref.
Keep the artifacts around to be able to browse the generated HTML files and
eventually print the text reports so that they can be parsed by gitlab.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1236
This removes ClutterAnimation and related tests. ClutterAnimation has
been deprecated for a long time, and replacements exist and are used by
e.g. GNOME Shell since a while back.
This also disables a few relatively unrelated interactive tests, as they
rely on ClutterAnimation to implement some animations they use to
illustrate what they actually test.
As interactive tests currently are more or less untestable due to any
interaction with them crashing, as well as they in practice means
rewriting the tests using non-deprecated animation APIs, they are not
ported right now. To actually port the interactive tests, it needs to be
possible to fist interact with them.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1192
In the past, it was a odd mix of possible different types, all coalesced
into an unsigned integer. Now, hovewer, it's always a
ClutterAnimationType, so lets change the name of getter, setter and
property to what it really is.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1192
When memfd_create isn't used, the file isn't sealed. Therefore, we
should skip test_readonly_seals on the fallback case. This fixes
compilation error on FreeBSD 12, which does not support memfd_create.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1229
We were iterating through evcodes, but using API that expects Clutter button
numbers. Instead of transforming those to Clutter numbers to have those translated
back, use the inner seat API that already takes evcodes.
Fixes stuck buttons keys after a virtual device is destroyed while those are
pressed.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1239
The CLUTTER_ACTOR_IN_REPARENT and the CLUTTER_IN_REPARENT flag are never
set and the logic for skipping unmap, unrealize and the emission of the
"parent-set" signal during reparents has been solved differently by
leaving out the CHECK_STATE and EMIT_PARENT_SET flags when calling
add_child_internal() and remove_child_internal().
The only place where those REPARENT flags are theoretically still useful
is in the clutter_actor_verify_map_state() debugging function, but that
is never called during reparent anyway, so simply leave the comment
regarding reparent there.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1228
Move to center uses all monitors for calculating work area.
This can lead to an unexpected behaviour on some monitor
configurations resulting in current window being split between
monitors. We should move window to the center of the active display.
Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/1073
Inhibiting remote access means any current remote access session is
terminated, and no new ones can be created, until remote access is
uninhibited. The inhibitation is ref counted, meaning there can be more
than one inhibitor.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1212
When resizing an X11 window with client side decorations, the shadow is
clipped by the frame bounds so that we don't need to paint the shadow
under the opaque areas covered by the window and its frame.
When the X11 client uses the EMWH synchronization mechanism (like all
gtk-3 based clients), the actual window may not be updated so that the
actual window and it frame may be behind the expected window frame
bounds, which gives the impression of de-synchronized shadows.
To avoid the issue, keep a copy of the frame bounds as a cache and only
update it when the client is not frozen so that the clipping occurs on
the actual content.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1178https://gitlab.gnome.org/GNOME/mutter/merge_requests/1214
The redraw clip that's painted together with the damage region has to be
copied earlier than we do right now. That's because if
PAINT_DAMAGE_REGION is enabled, buffer age is disabled and thus
use_clipped_redraw is FALSE. That means the redraw_clip is updated and
set to the full view-rect. If we copy the queued_redraw_clip after that,
it's also going to be set to the full view-rect. So copy the redraw clip
a bit earlier to make sure we're actually passing the real redraw clip
to paint_damage_region().
Also keep the queued_redraw_clip around a bit longer so it can actually
be used by paint_damage_region() and isn't freed before that.
While at it, move paint_damage_region() from swap_framebuffer() into
clutter_stage_cogl_redraw_view() so we don't have to pass things to
swap_framebuffer() only for debugging.
Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1104https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1208
It takes coordinates in stage coordinate space, and will result in
a screen cast stream consisting of that area, but scaled up by the scale
factor of the view that overlaps with the area and has the highest scale
factor.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1207
Will be used by the stage to not paint the overlays. We skip all
overlays since overlays are only ever used for pointer cursors when the
hardware cursors cannot or should not be used.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1207
These phase callbacks are not intended to be inovked when something
secondary is painting the stage, such as a screen cast stream, or
similar. Thus, only invoke the callbacks when there is a view associated
with the paint context, which will not be the case for offscreen
painting.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1207
Either onto a framebuffer, or into a CPU memory buffer. The latter will
use an former API and then copy the result to CPU memory. The former
allocates an offscreen framebuffer, sets up the relevant framebuffer
matrices and paints part of the stage defined by the passed rectangle.
This will be used by a RecordArea screen cast API. The former to paint
directly onto PipeWire handled dma-buf framebuffers, and the latter for
PipeWire handled shared memory buffers.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1207
If there is a paint context available (i.e. for the phases that are
during the actual stage paint), pass it along the callbacks, so that
the callback implementations can change their operation depending on the
paint context state.
This also means we can get the current view from the paint context,
instead of the temporarily used field in the instance struct.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1207
A paint flag affects a paint operation in ways defined by the flags.
Currently no flags are defined, so no semantical changes are defined
yet. Eventually a flag aiming to avoid painting of cursors is going to
be added, so that screen cast streams can decide whether to include a
cursor or not.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1207
If drmModePageFlip() or custom_page_flip_func fails, process_page_flip() was
forgetting to undo the ref taken for that call. This would leak page_flip_data.
The reference counting works like this:
- when created, ref count is 1
- when calling drmModePageFlip, ref count is increased to 2
- new: if flip failed, ref count is decreased back to 1
- if calling schedule_retry_page_flip(), it takes a ref internally
- if calling mode_set_fallback(), it takes a ref internally
- all return FALSE paths have an explicit unref
- return TRUE path has an explicit unref
This issue was found by code inspection and while debugging an unrelated issue
with debug prints sprinkled around. I am not aware of any end-user visible
issues being fixed by this, as the leak is small and probably very rare.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1209
When testing a laptop with intel and DisplayLink devices, attempting to set the
DL output as the only active output resulted in GNOME/Wayland freezing. The
main event loop was running fine, but nothing on screen would get updated once
the DL output become the only one. This patch fixes that issue.
DisplayLink USB 3 devices use an out-of-tree kernel DRM driver called EVDI.
EVDI can sometimes fail drmModePageFlip(). For me, the flip fails reliably when
hotplugging the DL dock and when changing display configuration to DL only.
Mutter has a workaround for failing flips, it just calls drmModeSetCrtc() and
that succeeds.
What does not work reliably in the fallback path is Mutter keeping track of the
pageflip. Since drmModePageFlip() failed, there will not be a pageflip event
coming and instead Mutter queues a callback in its stead. When you have more
than one output, some other output repainting will attempt to swap buffers and
calls wait_for_pending_flips() which has the side-effect of dispatching any
queued flip callbacks. With multiple outputs, you don't get stuck (unless they
all fail the exact same way at the same time?). When you have only one output,
it cannot proceed to repaint and buffer swap because the pageflip is not marked
complete yet. Nothing dispatches the flip callback, leading to the freeze.
The flip callback is intended to be an idle callback, implemented with a
GSource. It is supposed to be called as soon as execution returns to the main
event loop. The setup of the GSource is incomplete, so it will never dispatch.
Fix the GSource setup by setting its ready-time to be always in the past. That
gets it dispatched on the next cycle of the main event loop. This is now the
default behavior for all sources created by meta_kms_add_source_in_impl().
Sources that need a delay continue to do that by overriding the ready-time
explicitly.
An alternative solution could have been to implement GSource prepare and check
callbacks returning TRUE. However, since meta_kms_add_source_in_impl() is used
by flip retry code as well, and that code needs a delay through the ready-time,
I was afraid I might break the flip retry code. Hence I decided to use
ready-time instead.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1209
According to the XSetSelectionOwner libX11 documentation:
[...] If the owner window it has specified in the request is later
destroyed, the owner of the selection automatically reverts to None,
but the last-change time is not affected.
This is indeed visible through the selection_timestamp field in
XFixesSelectionNotify events.
Use this to check whether the selection time is recent-ish (thus
likely coming from an explicit XSetSelectionOwner request) and honor
the client intent by setting a "NULL" owner. If the selection time
is too old, it's definitely an indication of the owner client being
closed, the scenario where we do want the clipboard manager to take
over.
This fixes two usecases:
- X11 LibreOffice / WPS clear the selection each time before copying
its own content. Mutter's clipboard manager would see each of those
as a hint to take over, competing with the client over selection
ownership. This would simply no longer happen
- Password managers may want to clear the selection, which would be
frustrated by our clipboard manager.
There's a slight window of opportunity for the heuristics to fail
though, if a X11 client sets the selection and closes within 50ms, we
would miss the clipboard manager taking over.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1206
The X11 selection source was being preserved after unsetting its
ownership. This is no leak as it would be eventually replaced by
another source, or destroyed on finalize. But it's pointless to
keep it.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1206
Test the two modes of MetaAnonymousFile, MAPMODE_SHARED and
MAPMODE_PRIVATE and make sure they don't leak data to other FDs when
writing to an FD provided by `meta_anonymous_file_get_fd` even though
the data of both FDs is residing in the same chunk of memory.
We do all the reading tests using mmap instead of read() since using
read() on shared FDs is going to move the read cursor of the fd. That
means using read() once on the shared FD returned by
meta_anonymous_file_get_fd() in MAPMODE_PRIVATE breaks every subsequent
read() call.
Also test the fallback code of MetaAnonymousFile in case `memfd_create`
isn't used for the same issues.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1012
Add MetaAnonymousFile, an abstraction around anonymous read-only files.
Files can be created by calling meta_anonymous_file_new(), passing the
data of the file. Subsequent calls to meta_anonymous_file_open_fd()
return a fd that's ready to be sent over the socket.
When mapmode is META_ANONYMOUS_FILE_MAPMODE_PRIVATE the fd is only
guaranteed to be mmap-able readonly with MAP_PRIVATE but does not
require duplicating the file for each resource when memfd_create is
available. META_ANONYMOUS_FILE_MAPMODE_SHARED may be used when the
client must be able to map the file with MAP_SHARED but it also means
that the file has to be duplicated even when memfd_create is available.
Pretty much all of this code was written for weston by Sebastian Wick,
see https://gitlab.freedesktop.org/wayland/weston/merge_requests/240.
Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net>
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1012
Instead of having everything clumped at MetaWaylandDataManager,
split the primary selection to its own struct. This manager is
handled separately from wl_data_device_manager and other selection
managers, so they would be able to interoperate between them, even.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1193