At some point we crossed the streams... In a short timespan we had
1f00aba92c merged, pushing WacomDevice to a common parent object,
and dcaa45fc0c implementing device grouping for X11.
The latter did not rely on the former, and just happened to
merge/compile without issues, but would promptly trigger a crash
whenever the API would be used.
Drop all traces of the WacomDevice internal to MetaInputDeviceX11.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1183
(cherry picked from commit f0718c7d95)
With the introduction of "shallow" relayouts, we are now able to enter
allocation cycles not only at the stage but also deeper down the
hierarchy if we know an actors allocation isn't affected by its children
since the NO_LAYOUT flag is set.
Now that means when queuing relayouts it's possible that
`priv->needs_allocation` gets set to TRUE for some actors down the
hierarchy, but not for actors higher up in the hierarchy. An actor tree
where that happens could look like that:
stage -> container -> container2 (NO_LAYOUT) -> textActor
With that tree, if the "textActor" queues a relayout, "container2" will
be added to the relayout hashtable of the stage and the actors "stage"
and "container" will have `priv->needs_allocation` set to FALSE.
Now if another relayout on the stage actor is queued,
`clutter_stage_queue_actor_relayout()` currently removes all the other
hashtable entries in favour of the stage entry, (wrongly) assuming that
will allocate everything. It doesn't allocate everything because in the
example above "container" has `priv->needs_allocation` set to FALSE,
which makes clutter_actor_allocate() return early before allocating its
children, so in the end "container2" will never get a new allocation.
To fix this, stop flushing the relayout hashtable when queuing a
stage-relayout and still add new entries to the hashtable if a stage
relayout is already queued to make sure we still go through all the
previously queued "shallow" relayouts. That shouldn't hurt performance,
too, because as soon as an actor got allocated once, it doesn't need an
allocation anymore and should bail out in clutter_actor_allocate() as
long as it's absolute position didn't change.
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1173
(cherry picked from commit e74c2e42cf)
Currently we check whether a window is alive everytime it's focused.
This means that an application that doesn't respond to the check-alive
event during startup always showing the "application froze" dialog,
without the user ever trying to interact with it.
An example where this tends to to happen is with games, and for this
particular scenario, it's purely an annoyance, as I never tried to
interact with the game window in the first place, so I don't care that
it's not responding - it's loading.
To avoid these unnecessary particular "app-is-frozen" popups, remove the
alive check from the focus function, and instead move it back to the
"meta_window_activate_full()" call. To also trigger it slightly more
often, also add it to the path that triggers the window focus when a
user actively clicks on the window.
This means that we currently check whether a window is alive on:
* Any time the window is activated. This means e.g. alt-tab or
selecting the window in the overview.
* The user clicks on the window.
Note that the second only works for an already focused window on
Wayland, as on X11, we don't refocus it. This particular case isn't
changed with this commit, as we didn't call meta_window_focus() to begin
with here.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1182
(cherry picked from commit 8df3b21a51)
This fixes an issue where a non-maximized screen casted window would be
stretched to fill the whole screen cast stream, instead of just the crop
that corresponds to the current window size.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1174
(cherry picked from commit a6f94696e2)
It isn't immediately obvious that this is impossible, because there's some
"action at a distance" going on with framebuffers that have their size
set lazily, after their textures get allocated; so let's make this a
critical warning rather than crashing.
In particular, this works around a crash when gnome-shell tries to blur a
background that hasn't yet had any space allocated for it - which it seems
is really an actor layout bug, but more robustness seems good to have.
Workaround for <https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538>.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1172
Signed-off-by: Simon McVittie <smcv@debian.org>
(cherry picked from commit c389aadff9)
A texture with no pixels isn't a useful thing to have, and breaks
assumptions elsewhere. For example, CoglFramebuffer assumes that after
a texture has been allocated, it will have width and height both greater
than 0.
In particular, this works around a crash when gnome-shell tries to blur a
background that hasn't yet had any space allocated for it - which it seems
is really an actor layout bug, but more robustness seems good to have.
Workaround for <https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538>.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1172
Signed-off-by: Simon McVittie <smcv@debian.org>
(cherry picked from commit 37eda498f2)
Previously clutter timelines advanced according to `g_source_get_time`.
But that meant the spatial stepping of animations was visibly sensitive to
any irregularities in the main loop. It also represented a time older [1]
than the intended presentation time of each frame.
Now we instead use `master_clock_get_next_presentation_time`. This ensures
we get the smoothness of hardware vsync as well as being closer to the
actual presentation time.
This means, for example, backends like Xorg that move the hardware cursor
independently of repaints will have their animations more closely matching
the hardware cursor position. So the cursor appears to stick more closely
when dragging windows or on the lock screen etc.
[1] "older" = (refresh_interval - sync_delay) = ~14ms for 60Hz
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/25https://gitlab.gnome.org/GNOME/mutter/merge_requests/724
Disabling a click action after a button-press but before a
button-release is captured makes ClutterClickAction connect to
captured-event and never disconnect.
This change fixes it by making sure the captured-event is only
processed if the action is still enabled, otherwise releasing
the action (reset state) and propagating the event.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1170
(cherry picked from commit 5f5ce08ba4)
Picking now only happens on allocated actors, but the
callback in the actor-pick test is not waiting for the
stage to run an allocation cycle. Ideally, we'd wait
for this cycle, but for now, forcing an allocation works
as well.
Allocate the overlay actor in the actor-pick test.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1169
(cherry picked from commit 7f488e3e1d)
When selecting the pick regions for an actor we were not considering
whether the actor was allocated and that was causing issues where the
preferred width/height of the actor was used when deciding whether
the actor should be considered as a pick target.
Check if the actor has a valid allocation, in addition to being mapped
and being in pick mode, in clutter_actor_should_pick_paint().
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1169
(cherry picked from commit 902302a174)
Normally we bail out in `sync_actor_geometry()`. The comment there
states:
```
Normally we want freezing a window to also freeze its position; this allows
windows to atomically move and resize together, either under app control,
or because the user is resizing from the left/top. But on initial placement
we need to assign a position, since immediately after the window
is shown, the map effect will go into effect and prevent further geometry
updates.
```
The signal for the initial sync originates in `MetaWindow` though and predates
`xdg_toplevel_set_maximized`, which again calls `meta_window_force_placement`,
triggering the signal too early. As a result, Wayland clients that start up
maximized have a wrong map animation, starting in the top-left corner.
In order to fix this without changing big parts of the geometry logic and risking
regressions, force the initial sync again before mapping.
Solution suggested by Jonas Ådahl.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1164
cogl_object_[get|set]_value_object() are annotated as [get|set]-value-func
for objects and primitives, so they must be visible for any derived types
to be usable from introspection.
https://gitlab.gnome.org/GNOME/mutter/-/issues/1146
IBusInputContext/ClutterInputFocus/GtkIMContext all go for offset+len
for their ::delete-surrounding signals, with offset being a signed int
(neg. to delete towards left of selection, pos. to delete towards right
of selection) and len being an unsigned int from the offset (and
presumably, skipping the current selection).
The text-input protocols however pass in this event two unsigned integers,
one being the length of text to delete towards the left of the selection,
and another the length of text to delete towards the right of the selection.
To translate properly these semantics, positive offsets shouldn't account
for before_length, and negative offset+len shouldn't account for after_length.
The offset/length approach may of course represent deletions that are
detached from the current cursor/selection, we simply delete the whole range
from the cursor/selection positions then.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/517
The input method can assign a negative value to
clutter_input_method_delete_surrounding() to move the cursor to the left.
But Wayland protocol accepts positive values in delete_surrounding() and
GTK converts the values to the negative ones in
text_input_delete_surrounding_text_apply().
https://gitlab.gnome.org/GNOME/mutter/issues/539
GObject recommends to break references to other objects on dispose
instead of finalize, also we want to release the pressed virtual buttons
as early as possible if we know the object is getting destroyed.
So release the pressed buttons and unref our virtual
MetaInputDeviceNative when the dispose vfunc is called, which also
allows us to release the buttons immediately from javascript instead of
waiting for the garbage collector by calling run_dispose() on the
object.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1157
In commit d846fabda we moved to using the override color alpha, however
it was missed that the actor opacity is transferred to the PangoRenderer
through the default color alpha, and the reason it was used there.
We actually want to factor in both alpha values, in order to respect
both foreground color alpha and actor opacity. This is done on the
unpremultiplied color, so we just need to change the alpha value.
Fixes effects on text actors that involve actor opacity.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1158
pango_renderer_get_alpha() returns 0 to indicate that the alpha value
should be inherited from the environment, but we are passing it on
(and therefore making the text fully translucent).
Instead, make the text fully opaque as expected.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1156
This allows us to screencast any window continuously, even
without it being visible. Because it's still being painted,
clients continue to receive frame callbacks, and people
are happy again.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
Just like what's done for monitor screencasting. Unfortunately, there's
no mechanism to share fences with PipeWire clients yet, which forces
us to guarantee that a frame is completed after blitting.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
MetaScreenCastWindowStreamSrc connects to the "damaged" signal of
MetaWindowActor. This signal is not exactly tied to the paint cycle
of the stage, and a damage may take quite a while to arrive when
a client doesn't want to draw anything. For that reason, the window
screencast can start empty, waiting for a damage to arrive.
Ensure at least one frame is recorded when enabling the window stream.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1097https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
cogl_framebuffer_push_rectangle_clip() acts on the current modelview
matrix. That means the result of clipping then translating will be
different of the result of translating then clipping.
What we want for window screencasting is the former, not the latter.
Move the translation code (and associated) to after clipping.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1097https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
Fix a regression that got introduced with
c483b52d24 where we started passing the
redraw_clip to paint_stage() instead of creating a temporary view_region
for unclipped redraws: In case we detect an invalid buffer age, we fall
back to doing an unclipped redraw after we passed the first check
setting up may_use_clipped_redraw. That means we didn't reset the
redraw_clip to the view_rect, and we're now going to redraw the stage
using the original redraw clip even though we're swapping the full
framebuffer without damage.
To fix that, check for the buffer age before setting up the
fb_clip_region and the redraw_clip and set may_use_clipped_redraw to
FALSE if the buffer age is invalid, too. This ensures the redraw_clip is
always going to be correctly set to the view rect when we want to force
a full redraw.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/1128
When calculating the transform we should apply to the cursor sprite
before uploading it to the cursor plane, we must also take into
account non upright mounted LCD panels.
Otherwise the cursor ends up 90 degrees rotated on devices where the
LCD panel is mounted 90 degrees rotated in its enclosure.
This commit fixes this by calling meta_monitor_logical_to_crtc_transform
in get_common_crtc_sprite_transform_for_logical_monitors to adjust the
transform for each Monitor in the LogicalMonitor.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1123https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1153
Support for them appears to be way less common than e.g. png, which is
currently the preferred format from Firefox, Chromium, Libreoffice and others.
Adopt to that fact.
As a side effect, this works around a bug observed when copying images in
Firefox on Wayland.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1141
Cogl shares some GL functions between the GLES and the big
GL drivers. Namely, it shares _cogl_driver_gl_context_init
and _cogl_driver_gl_context_deinit between these two drivers.
The plot twist is: even though these functions are shared and
their prototypes are in cogl-util-gl-private.h, they're actually
implemented inside cogl-driver-gl.c, which is strictly only
about the big GL driver.
This is problematic when building Mutter on ARM v7, where we
need to disable OpenGL, but keep GLES enabled.
Fix this by moving the shared GL functions to a shared GL file.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1151
When resizing a window interactively, we'll set a grab operation and a
grab window, among other things. If we're resizing (including setting
initial size, i.e. mapping) another window, that didn't change position,
don't use the gravity of the grab operation when resizing our own
window.
This fixes an issue with jumpy popup position when moving a previously
mapped gtk popover.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/999
The transactional KMS API has been modelled after atomic KMS. Atomic KMS
currently doesn't support forwarding cursor hotspot metadata, thus it
was left out of the transactional KMS API having the user set the simply
create a plane assigment with the cursor sprite assigned to a cursor
plane using regular coordinates.
This, however, proved to be inadequate for virtual machines using
"seamless mouse mode" where they rely on the cursor position to
correspond to the actual cursor position of the virtual machine, not the
cursor plane. In effect, this caused cursor positions to look "shifted".
Fix this by adding back the hotspot metadata, right now as a optional
field to the plane assignment. In the legacy KMS implementation, this is
translated into drmModeSetCursor2() just as before, while still falling
back to drmModeSetCursor() with the plane coordinates, if either there
was no hotspot set, or if drmModeSetCursor2() failed.
Eventually, the atomic KMS API will learn about hotspots, but when
adding our own atomic KMS backend to the transacitonal KMS API, we must
until then still fall back to legacy KMS for virtual machines.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1136
When calculating the resource scale of a clone source, we might end up
in situations where we fail to do so, even though we're in a paint. A
real world example when this may happen if this happens:
* A client creates a toplevel window
* A client creates a modal dialog for said toplevel window
* Said client commits a buffer to the modal before the toplevel
If GNOME Shell is in overview mode, the window group is hidden, and the
toplevel window actor is hidden. When the clone tries to paint, it fails
to calculate the resource scale, as the parent of the parent (window
group) is not currently mapped. It would have succeeded if only the
clone source was unmapped, as it deals with the unmapped actor painting
by setting intermediate state while painting, but this does not work
when the *parent* of the source is unmapped as well.
Fix this by inheriting the unmapped clone paint even when calculating
the resource scale.
This also adds a test case that mimics the sequence of events otherwise
triggered by a client. We can't add a Wayland client to test this, where
we actually crash is in the offscreen redirect effect used by the window
dimming feature in GNOME Shell.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/808https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1147
For HiDPI pointer cursors backed by Wayland surfaces, the hotspot must
be placed using integers on the logical pixel grid. In practice what
this means is that if the client loads a cursor sprite with the buffer
scale 2, and it's hotspot is not dividable by 2, it will be rounded
down to an integer that can. E.g. a wl_surface with buffer scale 2 and a
cursor image with hotspot coordinate (7, 7) will have the coordinate
(3.5, 3.5) in surface coordinate space, and will in practice be rounded
down to (3, 3) as the hotspot position in wl_pointer only takes
integers.
To not potentially shift by 1 pixel on HiDPI monitors when switching
between wl_surface backend cursor sprites and built-in ones, make the
built in one emulate the restrictions put up by the Wayland protocol.
This also initializes the theme scale of the xcursor sprite instances to
1, as they may not have been set prior to being used, it'll only happen
in response to "prepare-at" signals being emitted prior to rendering.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1092https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1107
We checked that the content size was appropriately painted in the stage,
but didn't take into account that the size of the sampled texture
region, meaning that when stage views were scaled, we'd think that we
would draw a texture scaled, as e.g. a 200x200 sized texture with buffer
scale 2 would have the size 100x100. When stage views were not scaled,
we'd apply a geometry scale meaning it'd end up as 200x200 anyway, thus
pass the check, but when stage views are scaled, it'd still be painted
as a 100x100 shaped texture on the stage, thus failing the
are-we-unscaled test.
Fix this by comparing the transformed paint size with the sampled size,
instead of the paint size again, when checking whether we are being
painted scaled or not. For example, when stage views are scaled, our
200x200 buffer with buffer scale 2, thus content size 100x100 will
transform to a 200x200 paint command, thus passing the test. For
non-scaled stage views, our 200x200 buffer with buffer scale 2 thus
content size 100x100 will also transform into a 200x200 paint command,
and will also pass the check, as the texture sample region is still
200x200.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/804https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1124