Realizing a cursor will assume view related state objects are valid so
they can mark them as dirty. This assumption broke when there were a
scale changed that happened with multiple CRTCs, as we'd create view
object by view object as we realized the texture. Realizing the texture
would trigger a signal that had the handler assuming the validity of all
view objects, but if we only had gotten to the first, the second view
would not be there yet, thus we'd be doing a NULL pointer dereference.
Creating the view objects first, then handling the updating avoids this
problem by making the already done assumption valid on hotplugs.
The test case added tests exactly this series of events, and uses a
virtual monitor as a cheap trick to make the KMS CRTC based view the
first one, and an arbitrary view the second that previously had its view
object initialized too late.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3012
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3262>
The cursor surface is decided by the "current" surface; if that alone
changed (e.g. current surface was destroyed), we didn't update the
cursor, meaning it either got stuck, or got hidden if the client exited
completely.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3262>
It's hard to tell why turning on HDR mode failed without these log
messages. It could be missing support in the sink (EDID/DisplayID) or
missing support in the driver/display hardware (connector properties) or
just a failure turning it on.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3251>
When the actor gets a new "main" surface assigned, it adds the
new surface to the stack of surface actors, but forgets to remove
the old one.
This stale pointer in the array may cause invalid reads and crashes
after the assigned surface is disposed, e.g. when destroying the
MetaWindowActor tries to disconnect signals from all accounted
surface actors.
Fixes: 9a2c8b2592 ("window: Add suspend state")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3252>
Commit 3bfcb6d1 fixed the check for tiling via keybindings, but
ignored a subtle edge case when tiling with the pointer: The
monitor used for tiling is the monitor with the pointer, which
is not necessarily the one that contains the largest part of the
window.
That is, the correct monitor to check against depends on the
context where the function is called. We can either figure
it out automatically via the current window drag, or make it
a parameter.
The latter is clearer, because the callers already decide which
monitor to use for tiling anyway.
Fixes: 3bfcb6d1b9 ("window: Fix portrait orientation check for tiling")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3248>
These snippets are retrieved anew every time a window is resized. But
callers never modify them, they're effectively read-only so cache them
at the place of creation.
This is required to convince the pipeline hash that each reuse of the
same snippet really is the same snippet and so the pipeline is unchanged.
`CoglPipelineSnippetList` only does shallow comparisons and there's no
need right now to reimplement it as a deep comparison.
This eliminates the log message:
> Over 50 separate %s have been generated which is very unusual,
> so something is probably wrong!
which isn't actually a leak but more a warning about wasting time.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6958
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3224>
GInitable initialization is failable, currently, it may fail before error
traps are initialized, but error traps would be invariably deinitialized on
finalize() of the failed object. This results in an assert hit, on top of the
original failure to initialize the backend.
The libX11 error handlers are a pure client-side construct, and not a server
request, they just need XInitThreads() called to set up the library-side locks
protecting access to the global variable. This is done beforehand already at
meta_backend_x11_init(), so initialize the error traps around that time too.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3242>
Commit 9c3b130f67 changed slightly destruction order to handle use-after-free
situations, but missed a small new one introduced by the order change: The
MetaX11Display may schedule callbacks through MetaLaters, which depend on the
MetaCompositor, which is now freed before the MetaX11Display.
Since there is no winning move here, make the MetaX11Display aware of this
by avoiding to remove the callback if the MetaCompositor is already gone.
The MetaLaters infrastructure is already fully freed at this point (incl. the
data it contained), so this shouldn't be a leak.
Fixes: 9c3b130f67 ("display: Fix destruction order")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3247>
Use work area from the monitor that the window is currently on to
determine if tiling should be allowed.
Window tiling is disabled for monitors with portrait orientation, but
the work area we use to detect portrait orientation is taken from the
monitor that currently has the mouse pointer.
This works fine for edge tiling using the mouse, but this is broken when
using keybindings for window tiling because your mouse pointer could be
on a different monitor that has horizontal orientation.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3199>
While adjusting the monitor layout of my docked laptop, mutter got a
segfault while attempting to dereference the frame_info struct. This
happened on gnome-shell 44.4-1.fc38.
cogl_onscreen_peek_head_frame_info() just forwards the call to
g_queue_peek_head() which returns NULL in the event that the queue is
empty. If finish_frame_result_feedback() is expected to always be called
with a non-empty queue there's still a bug somewhere, but regardless
this API can legitimately return NULL so it should be checked for prior
to dereferencing.
Fixes: 61801a713a ("onscreen/native: Avoid freezing the frame clock on failed cursor commits")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3229>
If we are making an update that only disables CRTCs, we would not
actually post it, but just drop it then post nothing, as it wasn't ever
added to the mode set update hash table. This resulted in hotplugs where
we loose the all the connectors we had, where we want to disable all
CRTCs and enable nothing, to fail to disable said CRTCs.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3073>
This removes the implicit dependency on `display->stack_tracker`
existing and being valid in `on_stack_changed()` because
now it is the stack-tracker's responsibility to subscribe
to the "changed" signal of the stack and handle the changes.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3202>
The _NET_WM protocol, written before the birth of XInput 2.x, does have
no notion of different input devices whatsoever. Anyways, in a X11 session
it is safe to assume this refers about the Virtual Core Pointer since
every input device by default drives it (incl. touchscreens through the
"pointer emulating sequence", and styli).
This assumption falls apart in a Wayland session with non-pointer input,
since we do actually distinguish between all the distinct pointer devices
and touchpoints, and do not let them emulate mouse input.
We do need to specify a device/sequence there to drive the window
move/resize operation. The _NET_WM_MOVERESIZE message just gives us the
x/y root coordinates the resize was started from, so work from there
into guessing what is the most likely device/sequence that did trigger
the request on the client side.
Conversely, on Wayland we do not need to check for possible race
conditions in the pressed button states since we have larger guarantees
about not missing these events if we checked for the button modifier
mask beforehand, so make that race condition check specific to the
X11 sessions.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2836
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3059>
There can be events which don't not have source devices set on them, because
they are not backed by real hardware and rather generated by us, for example
IM events coming from the shell's OSK.
So don't assume all events have a source device in
update_pointer_visibility_from_event() and rather ignore those without one,
as we are only interested in events coming from "real hardware" here.
This fixes an issue where the mouse pointer would appear on devices without
any input from actual mice/touchpads on OSK key presses.
Fixes: 6aa42d6dad
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3236>
When we call get_grab_info() to get the sequence, device and coordinates for
a touch window drag, as the device we use the device from the
MetaWaylandPointer, assuming that it's set to the core pointer.
In the case where there is no pointer device present on the seat (so no
mouse nor touchpad), the wayland pointer remains disabled though, and
pointer->device is NULL.
This means touch window dragging on hardware without pointer devices
present is broken (because MetaWindowDrag assumes that there's a valid
device passed in meta_window_drag_begin()). Fix it by taking the core
pointer directly from ClutterSeat instead of going the extra detour through
MetaWaylandPointer.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3238>
If meta_eis_viewport_get_position() returned FALSE, the variable
'has_position' would be initialized. This variable represents
exactly the return value of meta_eis_viewport_get_position(),
so just assign it to the variable directly.
Spotted by Coverity.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3237>
CLUTTER_SCROLL_SOURCE_UNKNOWN only generates continuous scroll events
and no discrete scroll events.
As a result, scrolling only works in applications, that support high
resolution scroll wheels, like GTK4 applications.
GTK3 applications, on the other hand, don't support high resolution
scroll wheel events, and such scrolling does not work in these
applications.
Fix this issue by using the scroll source CLUTTER_SCROLL_SOURCE_WHEEL.
Since commit 92a90774a4 ([0]),
CLUTTER_SCROLL_SOURCE_WHEEL generates discrete events to ensure that
scrolling in legacy applications still works.
[0]: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2664
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3235>
We need to trigger a mode set when power-save changes to 'on' if it's
purely about power saving, but when they arrive as part of a hotplug
event, we'll handle all that later, in the monitors-changed handling,
that contains the new configuration.
This avoids a crash that happens due to the mode set being queued on now
disabled connectors.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2985
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3233>
We can change power save mode for two reasons: gsd-power told us to, or
we saw a hotplug event. Sometimes it's useful to be able to make the
distinction to why a power save mode changed, so add a reason to the
signal.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3233>
If the deadline timer is disabled (like on nvidia-drm or when
`MUTTER_DEBUG_KMS_THREAD_TYPE=user`), then we need to call
`meta_kms_device_set_needs_flush` on every cursor movement. But some were
getting skipped if they coincided with page flips, which resulted in some
cursor movements failing to schedule the frame clock. This resulted in
unnecessary levels of frame skips when using lower frequency input devices
which are less likely to provide another event within the same frame period.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3002
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3210>
Add a pair of calls to ensure the error trap infrastructure
survives for the MetaBackend. This will help on later commits that
largely operate on the MetaBackendX11 Display.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3230>
Keep a per-display list of error traps, so we don't mix them
together, and possibly deem unintended error traps outdated.
This means init/deinit calls are now stackable, and need to
happen evenly. In order to honor this, move the MetaX11Display
error trap destrution to finalize.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3230>
This forces not using the seat_proxy. But still allows the use of
session_proxy.
On tests, headless mode is explicitly set and it might not be available a
systemd session. To avoid test failing on this situation skip using
meta_launcher wich uses session_proxy and seat_proxy.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3093>