This will query a device state; position and modifiers.
Note that ClutterSeat subclasses don't implement the vmethod yet,
so calling clutter_seat_query_state() may crash ATM.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
While multiple built-in panels isn't actually supported in any
meaningful manner, if we would ever end up with such a situation, e.g.
due to kernel bugs[0], we shouldn't crash when trying to set an
'external only' without any external monitors.
While we could handle this with more degraded functionality (e.g. don't
support the 'switch' method of monitor configuration at all), handle it
by simply not trying to switch to external-only when there are no,
according to the kernel, external monitors available. This would e.g.
still allow betwene 'mirror-all', and 'linear' switches.
The crash itself was disguised as an arbitrary X11 BadValue error, due
to mutter trying to resize the root window to 0x0, as the monitor
configuration that was applied consisted of zero logical monitors, thus
was effectively empty.
[0] https://bugzilla.redhat.com/show_bug.cgi?id=1896904
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1899260
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1607>
xkb recently gained support for user-specified keymaps, which means we
can no longer assume that the configuration data is necessarily fully
complete or correct; and the configuration language is quite a labyrinth,
so it's easy to get wrong. If setting the keymap fails, leave it in
whatever state it previously had, since that seems preferable to crashing
with a NULL pointer dereference.
Resolves: https://gitlab.gnome.org/GNOME/mutter/-/issues/1555
Signed-off-by: Simon McVittie <smcv@debian.org>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1605>
Testing points and rays against boxes is substantially cheaper - in
fact, almost trivial - compared to triangles. Check if the actor's
paint volume doesn't intersect with the current pick point / ray,
and skip recursing altogether in those cases.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1520>
The cached pick mode never actually cached anything, since it is
always, unconditionally reset when painting. Furthermore, next
commits will cull out actors during pick, which makes the pick
stack uncacheable.
Remove the cached pick mode.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1520>
Users of Debian arm64 (aarch64) report that on at least some GPUs
or screens, after time-based screen blanking has occurred, it is not
possible to unlock the screen. Bisection indicates that this regressed
in commit 209b1ba3, so presumably this is because a refresh rate of 0
is reported while the screen is blanked, leading to the frame clock
pausing forever.
Fixes: 209b1ba3 "clutter/frame-clock: Adapt refresh rate from to frame info"
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1536
Bug-Debian: https://bugs.debian.org/974172
Signed-off-by: Simon McVittie <smcv@debian.org>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1601>
It's currently possible that some last_paint_volumes don't get updated
during a paint cycle, this can happen when a ClutterOffscreenEffect is
used: The offscreen effect might skip painting the content and the
children of an actor because it uses its own offscreened texture
instead. This means the offscreen effect doesn't call
clutter_actor_continue_paint(), and thus the the last_paint_volumes of
the children won't be updated.
Now one might think that isn't a problem, because as soon as a child
changes it's size or position, the offscreened texture would get
invalidated and clutter_actor_continue_paint() would get called. It's
not that easy though: Because the last_paint_volume includes all the
transformation matrices up to eye-coordinates, it has to be updated on
any changes to matrices, which includes position/transformation changes
to any actor up the hierarchy.
Now that's where get into problems with the offscreen effect: In case of
transformation changes to the offscreened actor or an actor up the
hierarchy, the offscreened texture won't get invalidated (that makes
sense, we can simply paint it transformed) and the last_paint_volumes
won't get updated even though they should.
This leaves us around with outdated last_paint_volumes where
last_paint_volume_valid is still set to TRUE. It can cause issues with
culling and clipped redraws.
So fix that by ensuring that all children that would get painted by
Clutter get their last_paint_volumes updated in case a ClutterEffect
decided not to call clutter_actor_continue_paint().
This ignores the case where a paint() vfunc override does the same and
doesn't call clutter_actor_paint() on children. Let's ignore this case
for now, there shouldn't be any implementation which does that and
ideally in a world that's painted solely by ClutterContent, we can get
rid of that vfunc in the future.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1591>
The first comment isn't really needed anymore since
the is_full_stage_redraw_queued() underneath is quite self-explaining.
Also rephrase the second comment a bit, including that
_clutter_paint_volume_get_stage_paint_box() does the aligning to the
pixel grid.
Finally, the last comment also looks out of date since we do that
rounding inside _clutter_paint_volume_get_stage_paint_box(), so remove
it.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1511>
We currently pass actors a reference to their associated
ClutterStageQueueRedrawEntry when queueing a redraw. This "splitting" of
the ownership of the entry has introduced quite a few bugs in the past
and is hard to follow.
So give up the "splitting" of the ownership and exclusively handle those
entries inside ClutterStage. To still allow removing the entry when an
actor gets unrealized introduce clutter_stage_dequeue_actor_redraw()
similar to what we already have for relayouts.
To be able to efficiently find entries when actors queue redraws, make
pending_queue_redraws a GHashTable, which fits quite nicely and also
allows removing the QueueRedrawEntries actor pointer in favour of the
key of the hashtable.
Since the struct is now private to ClutterStage, we can also rename it
to QueueRedrawEntry.
While at it, also sneak in the removal of the leading underscore from
clutter_stage_queue_actor_redraw().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1511>
The "queue-redraw" signal is not used anywhere in Clutter and we now
also removed the vfunc implementation of the stage. So stop emitting it
and remove it, but keep the propagate_queue_redraw infrastructure to
make sure clones still get their redraws queued.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1511>
Since we now decoupled the "queue-redraw" signal from creating the stage
clip, we can move signal emission into
_clutter_actor_queue_redraw_full() and emit the signal right away when
queueing a redraw on an actor. With that we now no longer have to
accommodate for the stage pending_queue_redraws list changing while
iterating over it.
To ensure we don't emit the signal too often when multiple redraws are
queued on one actor, use the propagated_one_redraw flag to limit the
number of emissions to a single one for every update cycle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1511>
Putting together the redraw clip of the stage never really fitted nicely
with the "queue-redraw" signal emission, it forces us to emit the
signals in a batch and we also use a weird trick to get the old paint
volume that's already on-screen into the final redraw clip (we call
_clutter_actor_propagate_queue_redraw() on the stage).
So start breaking up this association by making the stage explicitely
request the redraw clip from the actor and removing the
ClutterPaintVolume argument from _clutter_actor_finish_queue_redraw().
This is done by adding a private function
clutter_actor_get_redraw_clip() which returns our old (currently
visible) paint volume and the new paint volume.
This also allows removing the check whether a full stage redraw has been
queued in clutter_actor_real_queue_redraw() and we can now just stop the
signal emission if a propagation happened at least once.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1511>
This adds 64 bit ARM support to parts of the CI pipeline, more
specifically, we now:
- Build a 64 bit ARM container image alongside the 64 bit x86 one.
- Build test mutter on 64 bit ARM
- Run tests on 64 bit ARM
- Check coverage on 64 bit ARM
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1577>
The most common case for Clutter is 2D axis-aligned actors, which
maintain these properties even after projecting to eye coordinates.
In those cases, we can use a simpler hit test by checking against
boxes.
Not only this is simpler, but this maintains an important aspect
of picking that is a requirement for Clutter: watertightness. Even
though the triangles checks do work on x86_64, they do not guarantee
watertightness. This breaks tests on ARM.
Use graphene_box_t to hit-test axis-aligned 2D actors.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1599>
The image registry must be enabled for the CI to work, as the container
image from the upstream registry is placed (as a reference, more or
less) in the local registry.
Recently, ci-templates got a bit more helpful if this happened, and will
fail up front and generate a JUnit report with a message describing the
issue.
Update to this version.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1587>
clutter_actor_paint() implements a clear preference for custom clips
over clip_to_allocation: If a custom clip is set, clip_to_allocation is
ignored.
Since the paint volume reflects what Clutter is going to paint, we
should handle it the same when putting together our paint volume: So
first handle custom clips, and if one is set, use that. Then handle
clip_to_allocation, and if that's set, use that. And finally, if both
aren't set, union our allocation with the children paint volumes to get
the building volume.
clutter_actor_paint() also doesn't check whether the custom clip is
empty: If that's the case, it will simply not paint anything. Given that
that's allowed by clutter_actor_paint(), the paint volume should also
follow here and return an empty paint volume in case the custom clip is
empty.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1592>
When a custom clip is set for an actor, this actor is not going to allow
any painting outside that clip. That includes the children, which may
also not paint outside that clip.
Now in case clip_to_allocation is set to TRUE, we already already do the
right thing and simply use the allocation as our paint volume, ignoring
the volumes of our children. The same should be done for the custom
clip, so also stop the process of building the paint volume once we see
that a custom clip is set and simply use that clip.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1592>
In case we only have a single view (or there's only one view left to
check and the actor is visible on previous views) we can take a short-
cut, saving a region allocation and some calculations.
While on it, declare float numbers in '.f' style to make them more
recognizable.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1596>
Commit 03c69ed8 ("Do not go past size hints on resize") was meant to
ensure the size hints set by the client would be honored during resize,
as going past those values could cause the window to move on resize.
However, it did so by calling ensure_size_hints_satisfied() which works
with the frame rect rather than the client rect. As a result, the
minimum size enforced would end up being larger than expected with
client-side decorations.
Use meta_window_maybe_apply_size_hints() instead which automatically
adjusts for client size.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1542
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1594>
It's the rules that guard the pipelines, deciding when they are allowed
to run or not. The 'only_default' comes from the fact that in the past
they set the only: field.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1588>
gnome-shell depends on gdm's client library at runtime, but the
new pipeline-built image no longer provides it.
Add it back, but built it from source instead of using the Fedora
package, so we don't draw in all of gdm's runtime dependencies
(which includes a full GNOME session including gnome-shell).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1590>
This allows profilers to trace the callers of whatever is spending the
most time on the GPU, and to measure render times more accurately.
Previously such information was hidden as it completed in the
background (asynchronously) after we call swap buffers.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1327>
When using CLUTTER_DEBUG_PAINT_DAMAGE_REGION, the blue swap region is
always a superset of the red redraw region. So painting both in full (since
the previous commit) just meant the red region was overdrawn and came out
purple. That doesn't provide enough visual contrast, changes the user
experience unexpectedly and reduces performance.
So just subtract the redraw region from the swap region. This way the
red redraw region is always red, not purple.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1571>
Previously when CLUTTER_DEBUG_PAINT_DAMAGE_REGION was set, that would lead
to has_buffer_age==FALSE, which would lead to use_clipped_redraw==FALSE
which would mean swap_region was always empty. And so the blue region of
CLUTTER_DEBUG_PAINT_DAMAGE_REGION was always empty, *and* fb_clip_region
was always the full view rectangle which is not useful for debugging.
Now when CLUTTER_DEBUG_PAINT_DAMAGE_REGION is set, we don't let that
affect use_clipped_redraw, which means fb_clip_region is calculated
realistically.
But that's not enough. Calculating fb_clip_region properly with
CLUTTER_DEBUG_PAINT_DAMAGE_REGION would still lead to colouring artefacts
left on screen from previous frames that don't apply to the current frame.
So to fix that we also paint_stage for the whole screen every time when
using CLUTTER_DEBUG_PAINT_DAMAGE_REGION.
So now you will only ever see red and blue shading that's applicable to
the current frame, and no artefacts from the previous frames.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1535
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1571>
It was being painted without scaling and offsetting so would only look
right at scale 1.0 and only on the view with origin (0,0). Now we include
the framebuffer scale and view origin it will be painted in the correct
location.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1571>
ci-templates had a bug where it failed to find the ready-built container
images on the upstream repository due to invalid assumptions about the
relationship between upstream repository and image registry. This
resulted in the container image to be rebuilt, wasting valuable CPU
cycles and storage space. Bump the included ci-templates template to
include the fix for this.
See https://gitlab.freedesktop.org/freedesktop/ci-templates/-/issues/22.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1583>
only/except keywords where deperecated in favor of rules.
Since we started using GNOME/mutter!1525 it introduced
a second pipeline being run for each commit.
Detached pipelines are the only way to access CI_MERGE_REQUEST_*
variables, and if we disable normal pipelines you will need to
create wip/spam MRs in order to run the tests.
This reworked rules makes it so, the normal pipeline needs manual
interaction to be started, and the detached/MR pipleines is always
run.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1578>
Since we schedule frames for each stage view seperately now, surfaces receive
frame callbacks for each stage view they are visible on.
Only emit frame callbacks for the primary stage view.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1468>
Our main use case of `is_obscured()` is frame callback emission.
Since we now support stage views running at differt speeds, we
need to know whether an actor is visible on a specific stage view
in order to schedule frame callbacks accordingly.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1468>