This API is the one accessed from different bits of the UI thread,
make it "async" (it's basically one-way setters, so API stays the same
in the surface) and able to run in the MetaSeatImpl main context.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Simplify the handling of numlock state, so it can be entirely handled
within the input thread. Since the saving/restoring is triggered inside
each backend code, there's no need anymore for meta_backend_set_numlock().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Push it a little bit down to the MetaSeatNative. As both the UI thread
and the input thread are interested in dealing with the xkb_keymap and
it is not meant to be used in different threads, keep 2 separate copies
around.
The keyboard map will always be set from the UI thread, so the xkb_keymap
owned by the MetaSeatNative (owned by the UI thread) can be considered
canonical.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Don't let the vfuncs (meant to be called from the UI thread) deal with
xkb state itself. Instead store the current state in struct fields, which
is then fetched in vfuncs.
This makes the keymap able to be used from the UI thread, while being
maintained by the input thread. Same caveats apply than
clutter_seat_query_state(), you are asking for the most up-to-date state,
but it still may be changing under your feet.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Wrap all keyboard state updates, and all pointer/stylus/touch cursor
position with a write lock, and ::query_state() (The only entrypoint
to this state from other threads) with a read lock.
The principle is that query_state may be called from different threads
(UI so far, but maybe KMS too in the future), while the input thread
may (or may not) be updating it. This state is fetched "atomically"
(eg. x/y will be consistently old or new, if the input thread were
updating it at the same time).
There's other places deep in backends/native that read this state,
they all will run in the input thread, so they count as "other readers"
to the other thread. Those changes are already mutually exclusive with
updates, so they don't explicitly need the RW lock.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
While barriers will be added from the main thread, the native barrier
manager will sit close to the MetaSeatImpl in its own thread. Add the
necessary locking so that we can pass MetaBarrierImplNative from the
UI thread to the input thread, and ensure the MetaBarrier signals are
still emitted in the UI thread.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Depending on the backend, we want to integrate this object at different
levels. It will sit close to the MetaBackendX11/MetaSeatX11 in X11, but
it will be put deep down with MetaSeatImpl in the native backend, in a
separate thread.
Since we can't depend on a single object type, nor are able to track
ClutterSeat signals neatly, make this API something to be called
explicitly by backends.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
These changes will happen in the input event management code, so let them
be emitted via the MetaSeatImpl, as that's what we'll have neat access to.
The ClutterSeat signals are now emitted from there.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Move most of the functional bits (those meant to run on a standalone
thread) to a MetaSeatImpl object. This object is managed by the MetaSeatImpl
and not exposed outside the friend MetaSeatNative/MetaInputDeviceNative/
MetaInputSettings classes.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Banish MetaInputSettings from MetaBackend "public" API, it's now meant to
spend the rest of its days in the backend dungeons, maybe hanging
off a thread.
MetaInputMapper replaces all external uses.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Delegate on the MetaInputMapper all matching of inputs and outputs,
including configuration. Other secondary aspects, like output
aspect ratio for tablet letterbox mode, or toggling attached devices
with power saving changes, are also moved here.
This makes MetaInputSettings independent of MetaMonitorManager,
all interaction with it happens indirectly via public API entrypoints.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Rename the set_tablet_keep_aspect() vfunc into a set_tablet_aspect_ratio()
one that takes an aspect ratio double, instead of leaking monitor info
into subclasses to let them all figure out this number themselves.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
We have 2 sources (this one in MetaSeatNative, and the one in
MetaBackend) dispatching ClutterEvents to the stage. Make the
MetaSeatNative one exclusively about dispatching the libinput
queue, and leave ClutterEvents to the other.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
This will resort to SW rendering if this cursor renderer does not
own the MetaKmsCursorRenderer, so it's pretty much equivalent thus
far, except we may now implement logic to flip the kms cursor renderer
around.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
We actually have a set_send_events() vfunc that can enable or disable
devices at the libinput and X11 input driver level, so use that. A
positive side effect is that those layers will leave the device at
a consistent idle state (as opposed to going mute maybe amid user
input).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
We are aiming for a split of HW and SW cursor rendering management.
Given the HW plane is a limited resource and the amount of cursor
renderers may be >1 (due to tablets, even though we currently use an
always-software cursor renderer there), it would ideally be able to
switch between renderers.
Being MetaCursorRenderer not really a singleton, having cursor
inhibitor accounting here doesn't pan out. Make it MetaBackend API
so all cursor renderers get the same picture.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
These use now more of a "pull" model, where they receive update
notifications and the relevant input position is queried, instead
of the coordinates being passed along.
This allows to treat cursor renderers all the same independently
of the device they track. This notifying of position changes should
ideally be more backend-y than core-y, a better location will be
figured out in future commits.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Instead of letting the wayland bits maintain an always-software
cursor renderer, let the cursor renderer be managed by the backend,
and only hook to it (as we do for pointer cursor) in the wayland
bits.
ATM, make the cursor renderer still always-software, although
ideally we should allow moving the HW cursor management between
renderers.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Different devices may get standalone cursor renderers, add this API
to adapt slowly to this. The meta_backend_get_cursor_renderer() call
still exists, but shortcuts to the mouse pointer's renderer (as it
actually did before).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Use a new set in MetaInputDeviceNative, this coexists with
ClutterInputDevice coords for the time being. This API will
eventually be only accessed from the input thread.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
While multiple built-in panels isn't actually supported in any
meaningful manner, if we would ever end up with such a situation, e.g.
due to kernel bugs[0], we shouldn't crash when trying to set an
'external only' without any external monitors.
While we could handle this with more degraded functionality (e.g. don't
support the 'switch' method of monitor configuration at all), handle it
by simply not trying to switch to external-only when there are no,
according to the kernel, external monitors available. This would e.g.
still allow betwene 'mirror-all', and 'linear' switches.
The crash itself was disguised as an arbitrary X11 BadValue error, due
to mutter trying to resize the root window to 0x0, as the monitor
configuration that was applied consisted of zero logical monitors, thus
was effectively empty.
[0] https://bugzilla.redhat.com/show_bug.cgi?id=1896904
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1899260
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1607>
xkb recently gained support for user-specified keymaps, which means we
can no longer assume that the configuration data is necessarily fully
complete or correct; and the configuration language is quite a labyrinth,
so it's easy to get wrong. If setting the keymap fails, leave it in
whatever state it previously had, since that seems preferable to crashing
with a NULL pointer dereference.
Resolves: https://gitlab.gnome.org/GNOME/mutter/-/issues/1555
Signed-off-by: Simon McVittie <smcv@debian.org>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1605>
Sometimes the automatically selected primary GPU isn't suitable with no
way to make an well educated guess to do it better. To make it possible
for the user to override the automatically calculated default, make it
possible to override it using a udev rule.
E.g. to select /dev/dri/card1 as the primary GPU, add a file e.g.
/usr/lib/udev/rules.d/61-mutter-primary-gpu.rules (path my vary
depending on distribution) containing the fellowing line:
ENV{DEVNAME}=="/dev/dri/card1", TAG+="mutter-device-preferred-primary"
Reboot or manual triggering of udev rules to make it take effect may be
required.
Related: https://gitlab.gnome.org/GNOME/mutter/merge_requests/1057https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1562
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1562>
Instead of aborting with an error, display a half transparent gray
square instead of cursors and log a warning in the journal, allowing the
user to fix their system withotu having to rely on switching to a TTY.
It will be immediately obvious the cursor is silly looking, which will
be a better hint than just aborting.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1428
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1563>
Monitor tile info is possible to fetch when RANDR version 15 is exposed
by the X11 server. We had inverted the check meaning that only if older
versions were advertised would we attempt to init the tile information.
Fix this guard, thus fix monitor tiling on X11.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1524
Not calling libinput dispatch in the backend constructor defeats the
logic in post init as the device added events have not been processed
yet.
So instead of trying to guess the cursor initial visibility, simply
update it along when devices get added.
Additional benefit, we do not need to walk the all device list looking
for touchscreens anymore, we just need to check the device being added
since the current logic is to hide the cursor as soon as a touchscreen
is found.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1534
At startup, libinput dispatch is called from the MetaSeatNative
constructed callback.
That means that we may get libinput events even before the default seat
is set.
In turn, processing those events may trigger the use the default seat
while it's still not set yet, and cause a crash of gnome-shell/mutter
at startup.
A simple reproducer for this is to start gnome-shell/mutter with a
tablet connected and the stylus in proximity, the proximity event will
cause gnome-shell/mutter to crash at startup.
To avoid that issue, avoid dispatching libinput events early from the
MetaSeatNative constructed callback, those events will eventually get
processed when the seat and the backend are all setup.
https://gitlab.gnome.org/GNOME/mutter/-/issues/1501https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1534
Otherwise we might run into a use-after-free and crash on (virtual)
device removal:
Invalid read of size 8
at clutter_input_device_get_device_type (clutter-input-device.c:811)
by update_last_device (meta-backend.c:1282)
by g_main_dispatch (gmain.c:3325)
by g_main_context_dispatch (gmain.c:4016)
by g_main_context_iterate.constprop.0 (gmain.c:4092)
by g_main_loop_run (gmain.c:4290)
by meta_run_main_loop (main.c:708)
by meta_run (main.c:723)
by main (main.c:550)
Address is 32 bytes inside a block of size 504 free'd
at free (vg_replace_malloc.c:538)
by g_type_free_instance (gtype.c:1939)
by clutter_event_free (clutter-event.c:1420)
by _clutter_stage_process_queued_events (clutter-stage.c:830)
by handle_frame_clock_before_frame (clutter-stage-view.c:1064)
by clutter_frame_clock_dispatch (clutter-frame-clock.c:405)
by frame_clock_source_dispatch (clutter-frame-clock.c:456)
by g_main_dispatch (gmain.c:3325)
by g_main_context_dispatch (gmain.c:4016)
by g_main_context_iterate.constprop.0 (gmain.c:4092)
by g_main_loop_run (gmain.c:4290)
by meta_run_main_loop (main.c:708)
by meta_run (main.c:723)
Block was alloc'd at
at malloc (vg_replace_malloc.c:307)
by g_malloc (gmem.c:106)
by g_slice_alloc (gslice.c:1025)
by g_slice_alloc0 (gslice.c:1051)
by g_type_create_instance (gtype.c:1839)
by g_object_new_internal (gobject.c:1939)
by g_object_new_valist (gobject.c:2264)
by g_object_new (gobject.c:1782)
by meta_input_device_native_new_virtual (meta-input-device-native.c:1365)
by meta_virtual_input_device_native_constructed (meta-virtual-input-device-native.c:705)
by g_object_new_internal (gobject.c:1979)
by g_object_new_valist (gobject.c:2264)
Suggested-by: Carlos Garnacho <carlosg@gnome.org>
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1529
Rely on the seat stage, or other ways to fetch it. Also rely that
there is actually a single stage, so that we assign the right stage
to all events going out of the seat, in a single place.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1486
This is a bit scattered around, with the setter/getter in Clutter, and
it only being only directly honored in Wayland (it goes straight through
device properties in X11).
Make this private native API, and out of public ClutterInputDevice API.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1486
Make the upper part agnostic about the device being relative in order
to avoid applying keep-aspect. The X11 bits already are, so make it
sure it's also the case for the native backend.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1486
As it does seem from a read to libinput code, TOUCH_CANCEL events
actually do contain slot information, and are emitted per-slot.
This means we can avoid iterating over the slots ourselves, they
are still expected to be sent altogether.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1486
When malformed modes are provided and no valid mode spec is found, mutter
will eventually try to access the last element of an empty list. Warn about
this and exit properly.
https://gitlab.gnome.org/GNOME/mutter/-/issues/1481
Many tablets have a native portrait mode panel, yet come with a keyboard dock,
where the device gets docked in landscape mode. To avoid the display being
on its side when mutter starts while the tablet is docked, we need to take
the accelerometer reported orientation into account even if there is a
tablet-mode-switch which indicates that the device is NOT in tablet-mode
(because it is docked).
Add special handling for the first time the "orientation-changed"
signal gets signalled by the orientation-manager, which happens after it
has successfully claimed the accelerometer with iio-sensor-proxy.
The added special handling of the initial "orientation-changed" signal
does a number of checks:
1. panel_orientation_managed is false because of the tablet-mode-switch and not
because of other reasons.
2. The device has a native portrait mode panel (and thus likely needs rotation
to display the image the right way up when docked).
If all these checks succeed then it continues with creating a new
monitors-config based on the orientation ignoring the panel_orientation_managed
value (for the initial/first "orientation-changed" signal only).
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
The orientation reported by the orientation_manager may have changed while
panel_orientation_managed was false. So when panel_orientation_managed
changes to true we should re-check the orientation.
This fixes the orientation not being correct when e.g. taking a 360 degree
hinges 2-in-1 in clamshell mode (so landscape orientation) and then folding
it into tablet mode while holding it in portrait orientation.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
Add support for the (mostly theoretical) case of an input-device
offering tablet-mode-switch functionality being unplugged.
This makes the has_tablet_switch handling identical to the has_touchscreen
handling, leading to more consistent code.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
Detect if a tablet-mode-switch device is already present when mutter
starts by checking for this from meta_seat_native_constructed. This
mirrors how we also set has_touchscreen from meta_seat_native_constructed.
This fixes tablet-mode-switches only being recognized when they are added
at runtime.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
Unconditionally setting has_touchscreen to check_touch_mode
when a new device gets added leads to has_touchscreen becoming
false when during runtime e.g. an USB keyboard gets plugged in.
Fix this by setting has_touchscreen to TRUE when check_touch_mode
is TRUE and leaving it alone otherwise.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
A first step towards abandoning the CoglObject type system: convert
CoglFramebuffer, CoglOffscreen and CoglOnscreen into GObjects.
CoglFramebuffer is turned into an abstract GObject, while the two others
are currently final. The "winsys" and "platform" are still sprinkled
'void *' in the the non-abstract type instances however.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1496