ClutterStage is the one and only subclass of ClutterGroup, but
it overrides basically everything specific to ClutterGroup to
mimic a ClutterActor. What a waste!
Subclass ClutterActor directly and remove all the now useless
vfunc overrides from ClutterStage. Adapt CallyStage to subclass
CallyActor as well.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1332
It is deprecated in favor of the 'z-position' property, and
the implementation itself redirects to the z-position, so
just drop it and replace all get|set_depth calls to their
z-position counterparts.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1332
We were setting the pipeline colour to all white (1.0, 1.0, 1.0, 1.0)
and so the default layer combine function multiplied each pixel
(R, G, B, A) by all ones. Obviously multiplying by one four times per
pixel is a waste of effort so we remove the colour setting *and* set
the layer combine function to a trivial shader that will ignore whatever
the current pipeline colour is set to. So now we do **zero** multiplies
per pixel.
On an i7-7700 at UHD 3840x2160 this results in 5% faster render times
and 10% lower power usage (says intel_gpu_top). The benefit is probably
much higher for virtual machines though, as they're no longer being
asked to do CPU-based math on every pixel of a window.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1331
The previous commit removed checks for intermediate focus states which
would make tests randomly fail, because of their time dependence. What
can be tested however is that if there is no other window available that
would accept the focus, that the focus remains at 'none', after the
focused window has been closed. This newly introduced test checks the
focus directly after closing the window (and syncing) and after the time
it would have taken for the queue to finish. The first check has a
similar timing issue as the removed focus checks in the other tests, but
the test will never accidentally fail, because regardless of whether the
queue has finished or not, the focus is always expected to be 'none'.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1329
While c3d13203 ensured that the test-client has actually closed the
window before testing for the focus change, it also made another timing
related issue with the tests more likely to happen. Serveral tests
assert that the focus is set to 'none' after the focussed window has
been closed when the window below does not accept focus. This however
can never be reliably tested, because closing the window triggers
timeout based iteration of a queue of default focus candidate windows.
This starts after the window has been closed and might finish before the
clients have finished synchronizing. This issue is more likely to
trigger the shorter the queue is and the more test clients there are
that could delay the synchronization.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1329
This avoids some issues which could happen on some setups[0] due to
meta-native-renderer.c:dummy_power_save_page_flip →
meta_onscreen_native_swap_drm_fb implicitly turning of the primary
plane (by destroying the KMS framebuffer assigned to it):
* drmModeObjectSetProperty could return an "Invalid argument" error
between setting a non-empty cursor with drmModeSetCursor(2) and
enabling the primary plane again:
Failed to DPMS: Failed to set connector 69 property 2: Invalid argument
(This was harmless other than the error message, as we always re-set
a mode on the CRTC after setting the DPMS property to on, which
enables the primary plane and implicitly sets the DRM property to on)
* drmModeSetCursor(2) could return an "Invalid argument" error between
setting the DPMS property to on and enabling the primary plane again:
Failed to set hardware cursor (drmModeSetCursor failed: Invalid argument), using OpenGL from now on
[0] E.g. with the amdgpu DC display code.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1240
I noticed my system would fall back to the slow unclipped (and
uncullable) paint path whenever a window touched the left edge of
the screen. Turns out that was a red herring. Just that
`use_clipped_redraw` was uninitialized so clipping/culling was used
randomly.
So the compiler failed to notice `use_clipped_redraw` was uninitialized.
Weirdly, as soon as you fix that it starts complaining that `buffer_age`
might be uninitialized, which appears to be wrong. So we initialize that
too, to shut up the compiler warnings/errors.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1323
In commit 4c1fde9d MetaCullable related code was moved out of
MetaShapedTexture into MetaSurfaceActor. While generally desirable,
this removed drawing optimizations in MetaShapedTexture for partial
redraws. The common case for fully obscured actors was still supposed
to work, but it was now discovered that it actually did not.
This commit revert parts of 4c1fde9d: it reintroduces clipping
to MetaShapedTexture but leaves all culling and actor related logic
in MetaSurfaceActor.
Thanks to Daniel van Vugt for uncovering the issue.
Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/850
Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1295https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1326
When trying to find a default focus window, the code iterates through a
queue of candidates with a timeout between each candidate. If the window
the current timeout is waiting for gets destroyed, this process just
stops instead of trying the next window in the queue.
This issue was made more likely to be triggered with the previous change
to the closed-transient-no-input-parents-queued-default-focus-destroyed
test due to the introduction of a wait, which can introduce a
delay between the two destroy commands.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1325
Some tests were not waiting for the test client to actually issue
destroy commands before checking their effect on the window focus.
Similarly when mutter is supposed to change the focus based on a delay
by sending a WM_TAKE_FOCUS to the client, this also could fail without
synchronization with the client before checking the result.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1325
The ClutterBindConstraint will change the preferred size an actor
reports so it returns the same size as the source actor in some cases.
This behavior was introduced recently with 4f8e518d.
This can lead to infinite loops in case the source actor is a parent of
the actor the BindConstraint is attached to, that's because calling
get_preferred_size() on the source will recursively call
get_preferred_size() on the actor again.
So to avoid those loops, check if the source is a parent of the actor
we're attached to and don't update the preferred size in that case.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1282
For ClutterClones we need to apply a scale to the texture of the clone
to ensure the painted texture of the source actor actually fits the
allocation of the clone. We're doing this using the transformation
matrix instead of using the scale_x/scale_y properties of ClutterActor
to allow users to scale ClutterClones using that API independently.
Now it's quite a bad idea to get the allocation boxes for calculating
that scale using clutter_actor_get_allocation_box(), since that method
will internally do an immediate relayout of the stage in case the actor
isn't allocated. Another side effect of that approach is that it makes
it impossible to invalidate the transform (which will be needed when we
start caching those matrices) properly.
So since we eventually allocate both the source actor and the clone
ourselves anyway, we can simply use the allocation box inside
clutter_clone_allocate() (which is definitely updated and valid at that
point) to calculate the scale factor.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1181
It seems wrong to use the scale factor of the X axis on the Z axis and
it looks like this has been accidentally changed in commit 570fa3f044.
So use a factor of 1.0 instead to not scale the Z axis at all because
the layout machinery only works in X and Y coordinates.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1181
There are cases where a layout manager used by an actor also wants to
return a custom size when the actor has no children, for example in case
the layout manager requests a fixed size. This is currently impossible
because we only query the layout manager when calculating the preferred
size if the actor has children.
So fix that and also use the layout managers size negotiation functions
in case the actor has no children.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1322
_cogl_shader_set_source_with_boilerplate and _cogl_shader_compile_real
have enough GL assumptions that it makes sense to push them into the
backend. Taken together their only callers are under driver/gl, so.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194
This had been an entirely-too-GL-aware collection of renderer queries,
mostly to work around driver bugs and handle software drivers
intelligently. The driver workarounds have been removed (fix your
driver, and if you can't because it's closed-source, fix that first),
and we now delegate the am-i-software-or-not logic to the backend, so
this can all go
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194
We delegate the answer through CoglDriverVtable::is_hardware_accelerated
since this is properly a property of the renderer, and not something the
cogl core should know about. The answer given for the nop driver is
admittedly arbitrary, yes it's infinitely fast but no there's not any
"hardware" making it so.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194
The size of the buffer the texture will be written to by
paint_to_buffer() is determined based on
meta_screen_cast_area_stream_src_get_specs() which uses roundf() to
calculate the width and height after scaling. Because the size of the
texture to be written to that buffer is calculated using ceilf(), it
might exceed the allocated buffer when using fractional scaling.
In 3.36 paint_to_buffer() is used from capture_view() which also uses
roundf() to allocate its buffer. Here this leads to a memory corruption
resulting in a crash when taking screenshots of an area.
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2842https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1320
Event delivery with grabbing popups stay essentially the same within
the grabbing client, we still must honor the implicit grab as long as
there is one.
This is however not the case, the popup_grab_focus() function ignores
the button state. The popup_grab_button() function will already indirectly
re-sync the focus surface after the last button is released, so checking
for button state in popup_grab_focus() is sufficient to make the implicit
grab honored with popup grabs involved.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1275https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1270
When a touch sequence was rejected, we'd update the event timestamps of
incoming touch events to help with implementing grabs. This was done by
sending a ClientMessage with a counter, and comparing the counter to
decide whether we're seing a replayed event or not.
This had the unforseen consequence that we would potentially end up
destroying all actors including the stage, since, when mutter receives a
ClientMessage event, it would assume that it's a WM_PROTOCOLS event, and
handle it as such. The problem with this approach is that it would
ignore fact that there might be other ClientMessage types sent to it,
for example the touch synchronization one. What could happen is that the
touch count value would match up with the value of the WM_DELETE_WINDOW
atom, clutter would treat this as WM_PROTOCOLS:WM_DELETE_WINDOW, which
it'd translate to clutter_actor_destroy(stage).
Destroying the stage in such a way is not expected, and caused wierd
crashes in different places depending on what was going on.
This commit make sure we only treat WM_PROTOCOLS client messages as
WM_PROTOCOLS client messages effectively avoiding the issue.
This fixes crashes such as:
#0 meta_window_get_buffer_rect (window=0x0, rect=rect@entry=0x7ffd7fc62e40) at core/window.c:4396
#1 0x00007f1e2634837f in get_top_visible_window_actor (compositor=0x297d700, compositor=0x297d700) at compositor/compositor.c:1059
#2 meta_compositor_sync_stack (compositor=0x297d700, stack=<optimized out>, stack@entry=0x26e3140) at compositor/compositor.c:1176
#3 0x00007f1e263757ac in meta_stack_tracker_sync_stack (tracker=0x297dbc0) at core/stack-tracker.c:871
#4 0x00007f1e26375899 in stack_tracker_sync_stack_later (data=<optimized out>) at core/stack-tracker.c:881
#5 0x00007f1e26376914 in run_repaint_laters (laters_list=0x7f1e2663b7d8 <laters+24>) at core/util.c:809
#6 run_all_repaint_laters (data=<optimized out>) at core/util.c:826
#7 0x00007f1e26b18325 in _clutter_run_repaint_functions (flags=flags@entry=CLUTTER_REPAINT_FLAGS_PRE_PAINT) at clutter-main.c:3448
#8 0x00007f1e26b18fc5 in master_clock_update_stages (master_clock=0x32d6a80, stages=0x4e5a740) at clutter-master-clock-default.c:437
#9 clutter_clock_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at clutter-master-clock-default.c:567
#10 0x00007f1e27e48049 in g_main_dispatch (context=0x225b8d0) at gmain.c:3175
#11 g_main_context_dispatch (context=context@entry=0x225b8d0) at gmain.c:3828
#12 0x00007f1e27e483a8 in g_main_context_iterate (context=0x225b8d0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3901
#13 0x00007f1e27e4867a in g_main_loop_run (loop=0x24e29f0) at gmain.c:4097
#14 0x00007f1e2636a3dc in meta_run () at core/main.c:666
#15 0x000000000040219c in main (argc=1, argv=0x7ffd7fc63238) at ../src/main.c:534
and
#0 0x00007f93943c1f25 in raise () at /usr/lib/libc.so.6
#1 0x00007f93943ab897 in abort () at /usr/lib/libc.so.6
#2 0x00007f9393e1e062 in g_assertion_message (domain=<optimized out>, file=<optimized out>, line=<optimized out>, func=0x7f93933e6860 <__func__.116322> "meta_x11_get_stage_window",
#3 0x00007f9393e4ab1d in g_assertion_message_expr ()
#4 0x00007f939338ecd7 in meta_x11_get_stage_window (stage=<optimized out>) at ../mutter/src/backends/x11/meta-stage-x11.c:923
#5 0x00007f939339e599 in meta_backend_x11_cm_translate_device_event (x11=<optimized out>, device_event=0x55bc8bcfd6b0) at ../mutter/src/backends/x11/cm/meta-backend-x11-cm.c:381
#6 0x00007f939339f2e2 in meta_backend_x11_translate_device_event (device_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:179
#7 0x00007f939339f2e2 in translate_device_event (device_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:208
#8 0x00007f939339f2e2 in maybe_spoof_event_as_stage_event (input_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:284
#9 0x00007f939339f2e2 in handle_input_event (event=0x7fff62d60490, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:309
#10 0x00007f939339f2e2 in handle_host_xevent (event=0x7fff62d60490, backend=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:413
#11 0x00007f939339f2e2 in x_event_source_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at ../mutter/src/backends/x11/meta-backend-x11.c:467
#12 0x00007f9393e6c39e in g_main_dispatch (context=0x55bc89dd03e0) at ../glib/glib/gmain.c:3179
#13 0x00007f9393e6c39e in g_main_context_dispatch (context=context@entry=0x55bc89dd03e0) at ../glib/glib/gmain.c:3844
#14 0x00007f9393e6e1b1 in g_main_context_iterate (context=0x55bc89dd03e0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/glib/gmain.c:3917
#15 0x00007f9393e6f0c3 in g_main_loop_run (loop=0x55bc8a042640) at ../glib/glib/gmain.c:4111
#16 0x00007f9393369a0c in meta_run () at ../mutter/src/core/main.c:676
#17 0x000055bc880f2426 in main (argc=<optimized out>, argv=<optimized out>) at ../gnome-shell/src/main.c:552
Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/338
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/951https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1317
The modifier state of the input device is supposed to be set to the
newest state, while the modifier state detail of the event is set to the
last state before the event (so not including the changes triggered by
the event).
So since the modifier state of the event is the last state anyway, the
state of the ClutterInputDevice is supposed to be set by the backend and
not by the stage while queuing the event, so stop setting the state
here.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1275
Make the clutter_input_device_get_actor() API public and remove
clutter_input_device_get_pointer_actor() in favour of the new function.
This allows also getting the "pointer" actor for a given touch sequence,
not only for real pointer input devices like mice.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1275
Switch from clutter_seat_list_devices() to the new peek_devices() method
of ClutterSeat in cases where we're only looping through the returned
list without manipulating it. This way we don't have to unnecessarily
copy around the list of devices.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1275
Add a method to ClutterSeat that allows peeking the list of input
devices and allow looping through devices a bit faster. The API left is
private so we can make use of peeking the GList internally, but don't
have to expose any details to the outside, which means we'd have to
eventually stick with a GList forever to avoid breaking API.
Since we now have the peek_devices() API internally, we can implement
ClutterSeats public list_devices() API using g_list_copy() on the list
returned by peek_devices().
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1275
While it's strongly discouraged, it is possible to queue a new relayout
of an actor in the middle of an allocation cycle, we warn about it but
don't forbid it.
With the introduction of the "shallow relayout" API, our handling of
those relayouts silently changed: Before introducing "shallow
relayouts", we'd handle them on the next stage update, but with the
priv->pending_relayouts hashtable and the
priv->pending_relayouts_version counter, we now do them immediately
during the same allocation cycle (the counter is increased by 1 when
queuing the relayout and we switch to a new GHashTableIter after
finishing the current relayout, which means we'll now do the newly
queued relayout).
This change in behavior was probably not intended and wasn't mentioned
in the commit message of 5257c6ecc2, so
switch back to the old behavior, which is more robust in preventing
allocation-loops. To do this, use a GSList instead of GHashTable for the
pending_relayouts list, and simply steal that list before doing the
relayouts in _clutter_stage_maybe_relayout().
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1267
As explained in the last commits, we'll let gnome-shell take care of
this since freezing and thawing needs to be decoupled from the effect
starting and ending.
So stop freezing the MetaWindowActor when starting the effect and
thawing the actor when ending the effect.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1250
As explained in the last commit, gnome-shell needs to be able to thaw
window actor updates during its size-change effect is active.
So make meta_window_actor_freeze() and meta_window_actor_thaw() public
API, which will allow the shell to freeze and thaw actor updates itself.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1250