This commit assumes that cursor surfaces work in a "mailbox" fashion. If
they are painted multiple times before a successful flip, all commits
but the last get discarded, and the last commit gets presented after the
flip succeeds. This is more or less how it works in the atomic backend,
and also more or less how it works in other backends, with the exception
that the cursor painting might fail without any way of knowing. This
assumption is still better than unconditionally discarding all cursor
surface feedbacks as if the cursor painting always fails.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
Regarding the sequence = 0 fallback: in some cases (moving a cursor
plane on atomic amdgpu) we get sequence = 0 in the page flip callback.
This seems like an amdgpu bug, so work around it by assuming a sequence
delta of 1 (it is equal to 1 because of the sequence != 0 check above).
Sequence can also legitimately be 0 if we're lucky during the 32-bit
overflow, in which case assuming a delta of 1 will give more or less
reasonable values on this and next presentation, after which it'll be
back to normal.
Sequence is also 0 on mode set fallback and when running nested, in
which case assuming a delta of 1 every frame is the best we can do.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
The presentation-time protocol allows surfaces to get accurate
timestamps of when their contents were shown on screen.
This commit implements a stub version of the protocol which correctly
discards all presentation feedback objects (as if the surface contents
are never shown on screen). Subsequent commits will implement sending
the presented events to surfaces shown on screen.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
This concerns only the cases when the presentation timestamp is received
directly from the device (from KMS or from GLX). In the majority of
cases this timestamp is already MONOTONIC. When it isn't, after this
commit, the current value of the MONOTONIC clock is sampled instead.
The alternative is to store the clock id alongside the timestamp, with
possible values of MONOTONIC, REALTIME (from KMS) and GETTIMEOFDAY (from
GLX; this might be the same as REALTIME, I'm not sure), and then
"convert" the timestamp to MONOTONIC when needed. An example of such a
conversion was done in compositor.c (removed in this commit). It would
also be needed for the presentation-time Wayland protocol. However, it
seems that the vast majority of up-to-date systems are using MONOTONIC
anyway, making this effort not justified.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
KMS and GLX device timestamps have microsecond precision, and whenever
we sample the time ourselves it's not the real presentation time anyway,
so nanosecond precision for that case is unnecessary.
The presentation timestamp in ClutterFrameInfo is in microseconds, too,
so this commit makes them have the same precision.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
A flag indicating whether the presentation timestamp was provided by
the display hardware (rather than sampled in user space).
It will be used for the presentation-time Wayland protocol.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
A flag indicating whether the presentation timestamp was provided by the
display hardware (rather than sampled in user space).
It will be used for the presentation-time Wayland protocol.
This is definitely the case for page_flip_handler(), and I'm assuming
this is also the case for the two instances in the GLX code.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
The old calculation was introduced to improve the precision
with commit c16a5ec1cf.
Here, I call the calculation as "revision 2", and the
calculation even older as "revision 1", and the new
calculation introduced with this commit as "reivion 3".
Revision 2 has two problems:
1. The calculation is mixed with fixed-point numbers and
floating-point numbers.
To overcome the precision loss of fixed-point numbers division,
it first "calculates refresh rate in milliHz first for extra
precision", but this requires converting the value back to Hz.
An extra calculation has performance and precision costs.
It is also hard to understand for programmers.
2. The calculation has a bias.
In the process, it does:
refresh += (drm_mode->vtotal / 2);
It prevents the value from being rounded to a smaller value in
a fixed-point integer arithmetics, but it only adds a small
bias (0.0005) and consumes some fraction bits for
floating point arithmetic.
Revision 3, introduced with this commit always uses
double-precision floating-point values for true precision and
to ease understanding of this code. It also removes the bias.
Another change is that it now has two internal values, numerator
and denominator. Revision 1 also calculated those two values
first, and later performed a division with them, which minimizes
the precision loss caused by divisions. This method has risks of
overflowing the two values and revision 1 caused problems due to
that, but revision 3 won't thanks to double-precision. Therefore,
revision 3 will theoretically have the result identical with
the calculation with infinite-precision.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1737>
Handle the case of a TOUCH_BEGIN event during window dragging separately
instead of treating it like a TOUCH_UPDATE event: Simply return TRUE to
make Clutter stop event propagation if it's the pointer emulating
sequence and let Clutter propagate the event if it isn't.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/427>
Window dragging should be cancelled when the touch sequences we're using
are no longer available. Also listen to TOUCH_CANCEL events if the
window is grabbed and cancel the grab op when a TOUCH_CANCEL event
happens.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/427>
This removes the responsibility of tracking these from the backend to
the base object. The backends are instead responsible for calling the
function to update the values.
For the native backend, it's important that this happens on the correct
thread, so each time either of these states may change, post a idle
callback on the main thread that sets the, at the time of queuing said
callback, up to date state. This means that things on the main thread
will always be able to get a "new enough but not too new" state when
listening on the 'notify::' signals and getting the property value
after.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1739>
Make sure to reset all the state that was set for an interactive grab op
back to the defaults after a grab op has ended.
Especially important here is setting grab_frame_action back to FALSE,
since this will constrain window-titlebars to the panel. We set this to
TRUE on some grabs, for example when resizing, but not when moving
windows. Since this remained being set to TRUE, it would also constrain
non-grab window movements, like calling MetaWindow.move_frame(), which
is used by gnome-shells OSK. By resetting it back to FALSE after a grab,
the OSK can now always move non-maximized windows to the position it
wants.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1736>
The cache had the size 9, which was "big enough" in the past, but when
more ways pipelines could be constructed, the size was not enough. The
need to increase the cache size was hard to spot though, since adding
pipeline flag didn't give any hints about the cache being directly tied
to these flag values.
So, when enough flag bits were set when attempting to retrieve and put a
pipeline in the cache, it'd instead overwrite some arbitrary stack
memory, which would sooner or later result in a memory corruption
induced crash. Valgrind could not detect this particular memory
corruption, as it messed up stack memory, not e.g. freed heap memory, so
it instead got confused and thought plain stack values were unreadable.
Fix these two issues by making the cache size the combination of all
pipeline flags + 1, so that we can safely put any flag combination in
the cache.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1747>
If `meta_xwayland_start_xserver()` returned via an error path, some of
the socket FDs were leaked.
Fix that, and add `steal_fd()` calls to make it clearer that FDs passed
to `g_subprocess_launcher_take_fd()` are transferred to it. There were
no bugs with how `GSubprocessLauncher` was being used.
Spotted while working on
https://gitlab.gnome.org/GNOME/glib/-/issues/2332.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1738>
Each next and current scanout buffer has a reference on them making sure
they stay alive. When dumb buffers were used on the secondary GPU state,
this didn't happen, leading to crashes due to unref:ing one time too
many, with backtraces such as
0) g_type_check_instance_is_fundamentally_a ()
1) g_object_unref ()
2) secondary_gpu_release_dumb ()
3) import_shared_framebuffer ()
4) update_secondary_gpu_state_post_swap_buffers ()
5) meta_onscreen_native_swap_buffers_with_damage ()
6) cogl_onscreen_swap_buffers_with_damage ()
7) swap_framebuffer ()
8) clutter_stage_cogl_redraw_view_primary ()
9) clutter_stage_cogl_redraw_view ()
10) _clutter_stage_window_redraw_view ()
11) handle_frame_clock_frame ()
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1746>
gnome-shell has this hack where it sets the environment variable
"NO_AT_BRIDGE" to "1" before calling meta_init() and then unsets it
after meta_init() returns.
This variable being set to "1" will then cause the ATK bridge in
at-spi2-gtk to fail to load, which GTK then ignores. This is on purpose,
since accessibility is supposed to be done done by GNOME Shell via
Clutter, not via GTK.
The problem is that, now, by default, setting "NO_AT_BRIDGE" to
"1" during meta_init() only has the desired effect on an X11 session,
where we always connect to the X11 server on startup (i.e. during
meta_init()). With Xwayland on-demand, we do not attempt to create the
GDK display during meta_init(), thus this hack falls apart.
Since there are no real altenatives to this hack, just move it to
mutter, which have a better idea when GDK displays are created or not.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1744>
Commit afa43154 tried to make sure the focus was properly changed when
calling focus_default_window() by checking the focused window just after
trying to set the focus.
However, the X11 “Inter-Client Communication Conventions Manual” version
2.0 (ICCCM 2 for short) states that some X11 client may want to use a so
called “globally active input” model in which case the client expects
keyboard input and set input focus even when it's not one of its own
window.
To comply with this, when dealing with such clients, mutter will not
change the focus and send a WM_TAKE_FOCUS message instead.
That mechanism will defeat the logic introduced by commit afa43154
because the focused window is not changed in this case. As a result, the
input focus will fallback to the no-focus window.
To avoid this, only check that the focus change occurred for windows
using a synchronous focus model.
v2: Split specific test for "globally active input" model (Florian).
v3: Remove the check for window->unmanaging which is useless (Jonas).
Fixes: afa43154 - "core: Make sure focus_default_window() worked"
Close: https://gitlab.gnome.org/GNOME/mutter/-/issues/1620
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1716>
X11 clients can use different models of input handling, of which some
may not result focus being set synchronously.
For such clients, meta_focus_window() will not change the focus itself
but rely on the client itself to set the input focus on the desired
window.
Add a new MetaWindow API to check when dealing with such a window.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1716>
Without these devices, things that depend on the existance of input
device classes won't know about the existance of e.g. pointer devices,
if the only pointer device is from a virtual one.
This requires handling situations where e.g. a device doesn't have a
device node thus can't be matched against a udev device.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1688>
Libinput will queue a few initial events when a seat is assigned to the
udev backend; a result of it probing udev adding detected devices. For
us to see these events, we need to dispatch libinput before going idle,
as nothing will show up on the libinput file descriptor until something
else (e.g. keyboard event or mouse movement) wakes us up.
Do this by adding a prepare() function to the libinput GSource, that
checks whether there are any events in the queue already, and return
TRUE if so is the case, causing us to dispatch before going fully idle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1688>
The API for NotifyKeyboardKeycode() does not mention what type of
keycode is expected to be submitted.
So, clarify in the API that the keycode to submit is expected to be an
evdev keycode.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1732>
Currently, when a remote desktop user submits a keycode, it will be
interpreted differently, when using the x11 session, instead of a
wayland session.
In a wayland session, submitting a keycode will have the expected
result (as if the key was pressed locally).
In a x11 session, this is not the case. Instead of getting the expected
key, some other key will be pressed (or sometimes even none).
The reason for this is that the native backend interprets the keycode
as evdev keycode and the x11 backend interprets the keycode as xkb
keycode.
To ensure that both backends produce the same behaviour when submitting
a keycode, fix the x11 backend to always interpret the keycode as evdev
keycode, instead of a xkb keycode.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1732>
GObject signals pass the emitting GObject as the first argument to
signal handler callbacks. When refactoring the grab-op-begin/end signals
to remove MetaScreen with commit 1d5e37050d,
the "screen" argument was replaced with a "display" argument instead of
being removed completely. This made us call the signal handlers with two
identical MetaDisplay arguments, which is very confusing and actually
wasn't handled in a grab-op-begin handler in gnome-shell.
So fix this by not adding the MetaDisplay as an argument to those
signals, GObject will take care of that for us.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1734>
We're going to round the workspace backgrounds in the new overview for
gnome-shell 40.
So far corner-rounding was only possible for StWidgets because the
rounded clipping was done using cairo drawing. We now need rounded
clipping for ClutterActors too because backgrounds are drawn using
ClutterActors (or more specifically a ClutterContent). To implement
that, first a ClutterOffscreenEffect subclass together with a fragment
shader from GSK (see gskSetOutputColor() [1] in the GSK GL renderer
code) was investigated, and while that was generic and worked quite
well, it was extremely slow for the case of drawing wallpapers because
of all the FBOs that had to be allocated.
This is the new, more performant approach: Use the same fragment shader,
but perform the rounded clipping right in MetaBackgroundContent while
we're painting the wallpaper. This has almost no performance impact,
with the downside of not being a generic solution.
To allow for rounded clipping not only at the edges of the wallpaper,
but using any given bounding rectangle, the API exposes not only the
radius, but also a bounding rect.
[1] https://gitlab.gnome.org/GNOME/gtk/-/blob/master/gsk/resources/glsl/preamble.fs.glsl
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1717>
Currently, the documentation for NotifyPointerAxis() just mentions that
a smooth scroll event is emitted.
However, this is not entirely correct. For each NotifyPointerAxis(),
mutter emits an emulated discrete scrolling event based on the
submitted accumulated smooth scrolling deltas.
Additionally, it doesn't mention how the motion deltas need to be
interpreted.
So, document the NotifyPointerAxis() notification better by mentioning
the emulation of discrete scroll events, how these discrete scroll
events are calculated and how the motion deltas need to be interpreted.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1727>
When a remote desktop user emits a virtual smooth scrolling event, a
smooth scroll event, that is not emulated, is emitted and on occasion
a discrete scroll event, that is emulated, is emitted.
As base for the discrete scrolling event, the smooth scrolling steps
are accumulated.
When the accumulated smooth scrolling steps surpass the
DISCRETE_SCROLL_STEP, the discrete scrolling event is emitted.
Currently, mutter uses for DISCRETE_SCROLL_STEP the value 10, which is
a terrible value to work with, especially for high resolution mouse
wheels.
When a triple resolution mouse wheel is used, each scrolling step will
have the value 3 1/3.
Three of such events won't however surpass the DISCRETE_SCROLL_STEP.
To fix this situation, add DBL_EPSILON to the calculation step, when
checking for the discrete scroll event to ensure that 3 smooth scroll
events, with each having the value 3 1/3, emit a discrete scrolling
event.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1727>
MetaVirtualInputDeviceX11 currently doesn't handle smooth scroll events
at all.
So, if a user of the remote desktop API uses smooth scroll events, then
only the wayland backend handles these events.
The user of the remote desktop API however, might not know which
backend is being used and actually the user should not even have to
care about it.
Actual smooth events cannot be emulated in the X11 events.
What can be done however is accumulating smooth events and then when
the accumulated steps surpass the DISCRETE_SCROLL_STEP value, emit a
discrete scroll event.
So, do exactly that, to make smooth scroll events work when the remote
desktop API is used with the x11 backend.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1727>