Changes in games between fullscreen and windowed modes may trigger
chaotic situations where the buffer and the frame size temporarily
disagree, producing rectangles with negative width/height. This is
usually followed by other updates that bring the pointer constraint
up to date.
This makes cairo panic and return an "error" empty region, which breaks
deeper down when using the region rectangles to apply the pointer
constraint.
If we hit this situation, ignore the frame rectangle, and just go with
the buffer rectangle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1655>
We didn't tear down the libinput objects in the right thread when
exiting, but did so after the input thread exited.
We also tried to destroy the libinput devices after the libinput context
was destroyed, which isn't allowed.
Fix these two issues by tearing down the libinput objects in a input
thread task that when done exits the input thread. This effectively
"flushes" the input thread tasks while destroying the libinput objects
just before the thread exits.
While it might fine to tear down libinput objects in an arbitrary (main
in this case) thread while making sure nothing pokes at it in parallel
(e.g. the input thread is gone), libinput is by definition single
threaded, and could theoretically make assumptions about this, and we
shouldn't cause any possible surprises here, so make sure to destroy it
all in the right thread.
This fixes an abort() on exit caused by an assert about invalid object
destruction in libinput.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1663>
The "seat" usually refers to the ClutterSeat (MetaSeatNative) object,
and "seat_impl" to the MetaSeatImpl object, but there were still a few
places where this wasn't adhered to so fix those.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1663>
When supported, this property allows the window system to apply a 3x3 color
correction matrix in order to transform colors from the window system's native
color space to the measured color space of a display device.
Query for this property and set the 'supports-color-transform' property in the
GetResource reply. Add support for the SetOutputCTM DBus method and plumb that
through to the server's CTM property.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1048>
Add a test case to check whether the stage views and frame clocks are
all correctly freed after working with timelines a bit and then
hotplugging and removing all monitors.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1632>
In clutter_timeline_set_actor() we currently always unset the
priv->frame_clock pointer of the old actor when a new actor gets set.
The priv->frame_clock pointer takes a reference on the ClutterFrameClock
though, so we leak ClutterFrameClocks here.
To fix it, simply rely on update_frame_clock(), which will call
set_frame_clock_internal() unconditionally to update the
priv->frame_clock pointer for us.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1632>
Currently, the NotifyPointerAxis method always assumes that the scroll
source is CLUTTER_SCROLL_SOURCE_FINGER.
This is however not always true and in some cases a remote desktop
client needs to submit a PointerAxis event with a custom axis step.
This is for example the case with high resolution mouse wheels, where
the NotifyPointerAxisDiscrete method is unsuitable.
In such cases NotifyPointerAxis needs to be called, but with the
intention that the scroll source is still a mouse wheel.
To solve this situation, don't assume the scroll source always to be
CLUTTER_SCROLL_SOURCE_FINGER.
Instead, add further flag options to NotifyPointerAxis, which allow a
remote desktop client to choose the scroll source.
This way a remote desktop client can choose what scroll source is the
most suitable one for the current scroll event.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1636>
The monitor texture is the final background image. It doesn't need to
have any alpha channel. Cross-fades (which is the process of rendering
*into* the monitor texture) still work just fine.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1665>
Because the framebuffer itself might be backed by a texture, which might
have mipmapping enabled. If so then rendering to the framebuffer will make
those mipmaps out of date.
Technically we are flagging the framebuffer's mipmaps as dirty *before*
they are, because the journal hasn't been flushed yet. But we need to do
it early because ideally the next flush will both write the offscreen
framebuffer contents and then read them for use in rendering to an onscreen
framebuffer. And the `mipmaps_dirty` flag needs to be set before the read,
so therefore we need to do it before the next journal flush.
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3146
where the offscreen framebuffer in question is meta-background's
`monitor->fbo`.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1664>
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>