Some effects such as the BrightnessContrastEffect try to skip rendering
by returning early with a FALSE return value in pre_paint() in cases
where the effect would not change the rendering. This stopped working
when effects were ported to paint nodes.
In the case of OffscreenEffects, like BrightnessContrastEffect,
pre_paint() is responsible for setting up the offscreen buffer which is
then used in paint_node(). However if pre_paint() fails, this buffer is
not created and attempting to use it will result in several error
messages and broken rendering.
Instead of trying to call paint_node() of the effect if pre_paint()
failed, just draw the actor.
Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1576
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1658>
Unfortunately there's situations where we can't fully rely on only
crossing events here. One such situation is pointer visibility changes
due to touch interaction, or e.g. after closing the lid.
In these situations the pointer position stays the same, picks the
same actor, yet we want to see the right surface as the pointer focus
again in the wayland side.
This used to happen on the first motion event after the pointer
visibility change before commit ad3f2b0b86, use motion events again
for picking so we don't break these usecases.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1657>
These events may be emitted for touchpoints (in which case they contain
an event sequence). Ignore those as they are not relevant for pointer
picking, and shouldn't influence its focus.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1657>
When using alt-tab to switch between windows, on a key handler we
undo the compositor grab, which triggers a repick, which generates
crossing events, which are handled in place, and trigger these
reentrancy checks.
On one hand, we do intend these crossings to take effect in place,
rather than being queued (possibly after a number of already queued
events). On the other hand, we now outright discourage generating
events from random places (and hope to make it just not possible,
eventually) thus we can afford not to protect against reentrancy
caused by API misuse.
So just drop these checks, and let these crossing events be
properly handled.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1657>
This signal may be left dangling when disconnecting a device, and be executed
later on if the device is connected again, and mapped to other output. Make it
sure the signal handler is disconnected when unplugging the device.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1657>
Just because of implementation details, this is only relevant to Wayland,
and is done via ::effects-completed handlers there. Ideally, Clutter should
notice by itself about effects starting, finishing, and affecting picking.
Doing this in generic code seems slightly cleaner in the interim.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1654>
This is the very same code than meta_wayland_pointer_repick(),
made part of Clutter, so triggering repicks on the same pointer
coordinates is made easy.
The intention is to remove meta_wayland_pointer_repick() in favor
of this call.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1654>
In the wayland code we are in synchronization with the events that
the ClutterStage is managing at the moment. Asking the ClutterSeat for
the pointer position gets ahead of the current events, and may result
in imprecise coordinates sent in wl_pointer.enter.
To be in consistence with the motion events that might be already
queued, we should ask the stage for the last known coordinates.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1654>
Updating the state before emitting the CLUTTER_LEAVE event allows its
handlers to query the pointer actor, and avoid getting the same actor
again. Conceptually, this makes picking more "atomic", and the events a
notification of the change.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1654>
To clear a pointer constraint, the Wayland backend passes a NULL
constraint to the native input backend.
The new async API however tries to reference/un-reference the given
object to use it while running in a separate task, which leads to a
warning from GLib trying to g_object_ref()/g_object_unref() a non
GObject pointer.
To avoid that issue, simply set the data only if the given constraints
pointer is not NULL.
Suggested-by: Carlos Garnacho <carlosg@gnome.org>
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1587
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1652>
I messed up and released 40.alpha at the same time as 3.38.2, when it's
supposed to be in January. In order to re-align with the schedule, change
the upcoming version to 40.alpha2 so we don't have to skip a release and
will be back on track in time of 40.beta.
Turns out GObject implicitly notifies all properties by default as soon
as a property setter is called, no matter if the property actually
changed or not. One can opt-out of this behavior by setting the
G_PARAM_EXPLICIT_NOTIFY flag.
So since almost all our properties get notified explicitely (well,
except ClutterActors deprecated show-on-set-parent property), set this
flag for all properties of ClutterActor and ClutterStage now. This
significantly reduces the number of notify:: signals emitted on
ClutterActors, because in gnome-shell javascript we usually set GObject
properties directly, not by going through the extra setter method.
More cleanups can be done in the future, since this flag is suitable for
almost every property in Clutter and even Mutter.
This fixes a crash where we'd hit a newly introduced assertion in
on_device_actor_reactive_changed() of ClutterStage because
notify::reactive got emitted multiple times.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1651>
Due to a few reasons currently the updating of input devices after stage
relayouts isn't working right now. Since we now have a list of pointer
devices in ClutterStage, we can simply use that list and can avoid
asking the input thread. Also we no longer need to check whether the
devices are pointer devices, since our list only consists of pointer
devices.
So switch to ClutterStages private list of pointer devices, which also
includes the core pointer (as opposed to the list returned by
clutter_seat_peek_devices()). This fixes picking after relayouts.
Note that this doesn't catch every possible change that might need a
repick, actors might also need a repick after transformation changes or
in case their custom clip has been changed.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1634>
find_focusable_ancestor() may pick an ancestor window which is not
mapped or hidden, and setting focus on that window will fail.
Be a tad more selective when looking for a focusable ancestor, to reduce
the chance of meta_window_focus() not focusing the happy chosen one.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1643>
The function focus_default_window() optionally takes a MetaWindow
argument denoting a window that should not be focused.
That function calls focus_ancestor_or_top_window() which in turn
calls meta_window_focus() to pass focus to another window.
However meta_window_focus() gives no guarantee that the given window
will end up being the one focused, and can fail in various and creative
ways.
If that fails, we could possibly end up with the focus window being the
one to avoid, while the caller assumes focus was changed, going as far
as asserting that fact like meta_window_unmanage() does.
As a result, mutter may abort simply because meta_window_focus() failed
to set focus on the expected window.
To avoid that issue, check that the focus did not end up on the window
that we explicitly did not want, and if that's the case, simply fallback
to the default focus window.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/862
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1643>
If texture allocation failed for a sliced 2D texture, the alloc()
function would free the slices immediately, but not clear the pointer to
the slices array. When the code attempting to allocate the texture then
freed the texture object, the cleanup functions tried to free the slices
array again, since it wasn't NULL.
Fix this by clearing the slices array after freeing it.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1580
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1648>
As planned and prepared with the last commits, let ClutterStage take
care of tracking input devices and their respective actors. This means
we now can remove the old infrastructure for this from
ClutterInputDevice.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1633>
We're moving keeping track of input devices and their associated actors
out of ClutterInputDevice, this commit basically adds replacements for
clutter_input_device_update() and clutter_input_device_set_actor() to
clutter-main and shuffles the internals of those functions around a bit
for clarity.
clutter_stage_update_device() is made available in clutter-mutter.h
because we need to update the actor of input devices not only from
ClutterStage (when repicking after relayout), but also from
MetaWaylandPointer (inside meta_wayland_pointer_repick()).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1633>
With the introduction of the input thread, we want to avoid modifying
ClutterInputDevices from the main thread, since they're owned and
updated by the thread.
There's one part of ClutterInputDevice that's still modified from the
main thread though, that is device-actors of pointer devices, and we're
going to move that state-tracking into ClutterStage instead.
So start that by adding the infrastructure to ClutterStage to keep track
of those things. It consists of two hashtables which associate devices
and touch sequences with actors, those hashtables get updated using
clutter_stage_update_device_entry() and
clutter_stage_remove_device_entry(), they can be queried by calling
clutter_stage_get_device_actor(), which will replace
clutter_input_device_get_actor().
clutter_stage_get_device_coords() is added and made available in
clutter-mutter.h because we need to get the coordinates when repicking
in meta_wayland_pointer_repick().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1633>
The n_steps variable corresponds to the number of *pairs* of
texture lookups that the blur shader does. For example, when
n_steps = 1, the for-loop reads 1 pixel before and 1 pixel
after the current one.
Our blur shader is heavily inspired in WebRender's blur shader,
the biggest difference being that we calculate the gaussian
samples in the fragment shader itself, and not in the vertex
shader. (This could be an improvement in performance for the
future though!)
WebRender's blur shader calculates n_steps differently than what
we currently do, though. It calculates n_step in such a way that
at least 2 steps are performed for evey non-zero sigma value.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1646>
The shader already operates on floating point sigma, and
there's just no reason for us to force it to be an unsigned
integer. It's still important that sigma must be positive
though.
Make sigma a float, and make sure it's a positive number.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1646>
Yet another way to reduce the instruction count of the fragment
shader. Passing a pair of floats once is virtually free, compared
to computing horizontal and vertical on each fragment run.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1646>
New entries indirectly added to `pending_queue_redraw` during the loop
would make our iterator invalid and cause `g_hash_table_iter_next` to
fail without having visited all elements. That was seen as assertion
failures but also likely resulted in incomplete paint clips.
Now we steal the iterator's entry before such corruption can happen,
free it manually, and reset the iterator to the beginning on every
iteration. This is actually safe and efficient because we're removing each
entry we visit. So no time is wasted in resuming from the (new) beginning
of the hash table.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1557
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1615>
Add a new pair of APIs corresponding to CoglFramebuffer's draw_rectangles()
and draw_textured_rectangles(). They're generally more performance compared
to adding multiple single-rect operations. These variants are heavily used
by GNOME Shell's CSS implementation.
The op array is built to match cogl_framebuffer_draw_textured_rectangles()
always, which means it's a series of 8 floats composed (x1 y1 x2 y2) and
(s1 t1 s2 t2). To avoid adding new struct fields to ClutterPaintOperation,
which is a performance and memory sensitive structure, simply divide the
array length by 8 (which is guaranteed to be correct).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1637>
Power saving changes in laptop panels enable/disable the attached
touchscreen input device, this is an asynchronous operation that
may be happening while the device is disappearing.
In fact, closing the lid is such perfect storm where both things
happen around the same time.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1644>