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>
Given X11 nature, the pointer "leaves" the stage anytime it wanders into
a client window, or any other areas that are not deemed part of the
stage input region.
Yet we want to stay correct in those situations, e.g. have the clutter
side reasonably in sync, picking and highlighting to work properly, etc.
In order to achieve that, emulate motion events on XI_RawMotion. These
are as much throttled as our pointer tracking for a11y, in order to avoid
too many XIQueryPointer sync calls. This emulation only kicks in anytime
that X11 notifies us that we are not "on" the stage.
This replaces some sync_pointer() calls in GNOME Shell code that are
there just to compensate for this trait of X11, e.g. in the message tray
code.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1659>
Ensure we issue a motion event for the current pointer position,
as there might be situations where compositor modals get X grabs
from other clients stacked on top, or missed events in between
otherwise.
Ensure the Clutter state is still up-to-date afterwards here. This
replaces some sync_pointer() calls done in GNOME Shell code, always
done after modality changes.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1659>
Do these Wayland operations (that apply on both native and nested backends)
in the MetaCompositorServer subclass. We want to add more backend specific
behavior here in the future.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1659>
In the case that DnD is performed and succeeds, we want to release
the grab early, and let the transfer IPC happen in the back. For
that to happen without a hitch, drag source and offer must be left
related to each other after undoing the grab, even though the default
ungrabbing code does that automatically (indirectly, by unsetting the
drag focus).
In these cases, we used to manually unset the current source, so
this decoupling was skipped. Notably, one missed case is X11 DnD,
so we might end up with the situation there that DnD did succeed,
transfer is ongoing, but the source and offer are already decoupled,
this confused the machinery and missed the finishing XdndFinished
to be emitted to the X11 drag source.
The prior commits prepared for this source/offer decoupling being
a manual operation, this commit avoids doing this automatically
when ungrabbing.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1720>
This object is just being detached, with no code unref'ing it. Do
this whenever the XDnD selection goes unowned, usually a good
indication that the drag source no longer is one.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1720>
g_set_error_literal() asserts that the provided message is not NULL.
If it is NULL, the function is entirely no-op.
This resulted in a NULL dereference of the GError, which remained
NULL in this case, when trying to print a warning in
clutter_stage_cogl_redraw_view().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1715>
PipeWire recently introduced busy buffers, which actually fixes the last remaining
issue that blocked us from downgrading these cogl_framebuffer_finish() calls into
cogl_framebuffer_flush() ones.
Switch to cogl_framebuffer_flush() in all three stream sources.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1701>
When a transfer request is done to the MetaSelectionSourceRemote source,
it's translated to a SelectionTransfer signal, which the remote desktop
server is supposed to respond to with SelectionWrite.
A timeout (set to 15 seconds) is added to handle too long timeouts,
which cancels the transfer request.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1552>
Nothing is hooked up, it only does basic sanity checking i.e. whether
the clipboard was enabled when interacting with it. No actual clipboard
integration is hooked up yet.
This also syncs org.gnome.Mutter.RemoteDesktop.xml from
gnome-remote-desktop.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1552>
The original implementation of ::touch-mode tested for keyboard
presence to know whether the OSK and other touch-only features were
enabled.
However that didn't pan out, every webcam, card reader and kitchen
sink like to live a second life as EV_KEY devices. This made the
detection of actual external keyboards a much harder task than it
sounds, and was thus removed in commit f8e2234ce5.
Try a different approach here, and test for pointer devices, it
doesn't matter if internal or external devices, the rationales:
- It is significantly easier to get this right, there's virtually
no devices with abs/rel axes that don't try to be a real input
device of some sorts.
- It's not as good as testing for keyboard presence, but it's the
next best thing. These usually come in pairs, except in weird
setups.
- It is better than not having anything for a number of situations:
- Non-convertible laptops with a touchscreen will get touch-mode
disabled due to touchpad presence (plus keyboard). There's
been complains about OSK triggering with those.
- Same for desktop machines with USB touchscreens, the mouse
(and presumably keyboard) attached would make touch-mode
get in the middle.
- Convertible laptops with a broken tablet-mode switch get a
chance to work on tablet modes that do disable input devices
(e.g. detachable keyboards, or via firmware)
- Kiosk machines, tablets, and other devices that have a
touchscreen but will not regularly have a mouse/keyboard
will get the touch-mode enabled.
All in all, this seems to cover more situations the way we expect it,
there's only one situation that the OSK would show where it might
not be desirable, and one that might not show when it better should:
- Tablets and kiosk machines that get one keyboard plugged, but not a
mouse, will still show the OSK, despite being able to type right
away.
- Convertible laptops with broken/unreliable tablet-mode switch (e.g.
ignored by the kernel) rely entirely on the device/firmware
characteristics to work. If after folding into tablet mode the
touchpad remains active, touch-mode will not turn on.
Fixing the tablet-mode switch on these devices should be preferred,
as that'll also make libinput magically disable the touchpad.
The latter can be worked around with the a11y toggle. The former is
merely inconvenient, and nothing prevents the user from plugging a mouse
in addition.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1710>
Technically this is still wrong if the source actor or dnd actor are
transformed in other ways. However geometry scale is the by far most
common case and we currently lack convenience API in Clutter to
easily compute the right values.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1683>
When recording the screen and real time encoding it using a gstreamer
pipeline, that pipeline can stall when the encoder is too slow. Log a
debug message using the new SCREEN_CAST debug topic in that case so we
know when framedrops are happening.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1709>
Since commit c255031b6d, we allow some modifier+scroll events to
pass through to Clutter to enable gnome-shell to handle them. That
action shouldn't trigger a modifier-only action at the same time, so
reset the corresponding tracking just like we do for modifier+click.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1695>
Since commit c255031b6d we pass scroll-events through to
the compositor if the window_grab_modifiers are pressed;
in order to allow gnome-shell to check for those events,
expose the struct member as a MetaDisplay property.
Also take the opportunity to pick a more generic name, now
that the modifier is no longer used exclusively for mouse
clicks (unless we maintain the notion of scroll events as
button 4 and 5 "clicks").
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1695>
The other end of the PipeWire stream can set the buffer data type to a
bitmask of supported buffer types. We should respect this, and not
attempt to allocate a DMA buffer if it isn't asked for.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1697>
Instead of getters, pass the width, height and stride around when
relevant. This also removes the redudant "stream_size" and
"stream_height" variables from the src struct, as they are already part
of the video format.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1697>
Mutter freezes Xwayland commits when resizing windows, and thaw them in
the window actors' after_paint() for X11.
Yet, after_paint() could be never called, as when a new window is mapped
while the overview is active in gnome-shell.
As a result, the content of the X11 window will remain invisible to the
overview.
Add a new window actor API to tell whether commits can be frozen. For
Wayland window actors, this always return FALSE, whereas for X11 window
actors, it checks whether the Clutter actor is mapped.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1678>
When (un)maximizing, (un)fullscreening, the move/resize action is
flagged with 'ACTION_MOVE' and 'ACTION_RESIZE' , while e.g.
'appears-focus' does not.
When a client misbehaved and didn't immediately reply to a configure
request with a commit with the corresponding ack_configure, the
following commit would trigger a oddly timed move, making the window
appear to move back to a previous position.
Avoid this issue by only carrying over the target window position if the
configuration actually contained a new position.
We cannot only rely on the flags however, as e.g. a new position should
be respected during interactive resize, even though only 'ACTION_RESIZE'
is passed in such scenarios.
Do the same for the size, except if the window state dictates that the
size is fixed to a certain size, e.g. being fullscreen or maximized.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1445>
Mutter needs to fetch the X11 Window ID from the onscreen and did that
by using an X11 specific API on the CoglOnscreen, where the X11 type was
"expanded" (Window -> uint32_t). Change this by introducing an interface
called CoglX11Onscreen, implemented by both the Xlib and GLX onscreen
implementations, that keeps the right type (Window), while avoiding X11
specific API for CoglOnscreen.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
Instead of calling "init_onscreen()" on two different separate vtables
from the allocate() funtion, just have the CoglOnscreen sub types
themself implement allocate() and initialize in there.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
Thins means that e.g. MetaOnscreenNative now inherits CoglOnscreenEgl,
which inherits CoglOnscreen which inherits CoglFramebuffer, all being
the same GObject instance.
This makes it necessary to the one creating the onscreen to know what it
wants to create. For the X11 backend, the type of renderer (Xlib EGL or
GLX) determines the type, and for the native backend, it's currently
always MetaOnscreenNative.
The "winsys" vfunc entries related to onscreens hasn't been moved yet,
that will come later.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
To get meta-renderer-native.c down to a bit more managable size, and to
isolate "onscreen" functionality from other (at least partly), move out
the things related to CoglOnscreen to meta-onscreen-native.[ch].
A couple of structs are moved to a new shared header file, as
abstracting those types (e.g. (primary, secondary) render devices) will
be dealt with later.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
The mutter naming convention for types and their instance variables is:
Type name:
[Namespace][BaseName][SubType]
Instance name:
[base_name]_[sub_type]
This means that e.g. CoglOnscreenGLX is renamed CoglOnscreenGlx, and
glx_onscreen is renamed onscreen_glx. This is in preparation for
GObjectification.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
Makes sure that monitor specs which may be read from EDID data do not
contain characters that are invalid in XML. Makes it possible to restore
monitor configs of monitor models with characters such as '&' in them.
To make this change not break any tests, the sample monitor configs need
to be adjusted as well. Apostrophes don't strictly have to be escaped in
XML text elements. However, we now do escape the elements in
`<monitorspec>` specifically.
Closes: <https://gitlab.gnome.org/GNOME/mutter/-/issues/1011>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1685>
Previously the wl_resource and MetaWaylandGtkSurface corresponding to
any client gtk_surface have been kept around until the exit of the
client due to the client side destroy method not signaling the
destruction to the server. Ideally the protocol would have specified a
destroy request marked as destructor to handle this automatically,
however this is no longer possible due to the destroy method being
implicitly generated in the absence of an explicit request in the
protocol. Adding a destroy request marked as destructor now would
generate a new destroy method that unconditionally would send the
request to the server, which would break clients running on servers not
supporting that request.
So instead of modifying the destroy request add a new "release"
destructor, that indicates to the server that it can release the
resource. This can be optionally be used by clients depending on the
server protocol version.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1307>
The MetaWaylandSurface corresponding to a MetaWaylandGtkSurface can be
destroyed before the MetaWaylandGtkSurface is destroyed. In its destroy
function MetaWaylandSurface however was unsetting the destructor of the
correspnding resource along with the gtk_surface1 interface
implementation. This was done to prevent further gtk_surface1 requests
on a NULLed MetaWaylandSurface, if it has been destroyed before the
MetaWaylandGtkSurface.
It would be enough to just unset the resource implementation, while
keeping the destructor to fix this leak. However the following commit
will rely on the implementation being available after the
MetaWaylandSurface has been destroyed. So instead introduce NULL checks
for all functions that can be called on the gtk_surface1 interface and
do not unset the implementation.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1307>
If the monitor configuration changed, even though the streamed monitor
didn't change, we'd still fail to continue streaming, as we failed to
update the stage watchers, meaning we wouldn't be notified about when
the stage views were painted.
Fix this by reattaching the stage watches, i.e. update the painted
signalling listeners to listen to the right views, when monitor changes
happens.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1691>
Make the API used more shared and better named.
meta_monitor_manager_on_hotplug() was renamed
meta_monitor_manager_reconfigure(), and meta_monitor_manager_reload()
was introduced to combine reading the current state and reconfiguring.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1689>
It was named "backend_native" and "backend" which is easily confused with
MetaBackendNative and MetaBackend which tends to have those names.
Prepare for introducing the usage of a MetaBackendNative and MetaBackend
pointers here by cleaning up the naming.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1689>
Fullscreen X11 windows that attempt to change the resolution on Wayland
use a surface viewport to achieve this without affecting the resolution
of the display. This however also means that pointer events will be
delivered in the display coordinates while the code handling the window
frame is not aware of any such viewport scaling. So a right click
outside of the area corresponding to the new resolution will not be
considered to be on the client area. And since the only area that is
ignored when determining whether to perform the right click action, such
as opening the context menu, is the client area, this will result in the
action being performed, despite happening on the (scaled) client area.
While it would be possible to scale the event coordinates so that
get_control() correctly determines the frame element the cursor is on,
viewport scaling only affects fullscreen windows. Since fullscreen
windows have no frame, we can always assume that if the window gets
delivered an event for a fullscreen window, it is on the client area
without doing any additional calculations.
Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1592
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1661>
We remove pending pings when unmanaging a window, but currently
don't prevent new pings to be scheduled after that.
The previous commit fixed a code path where this did indeed happen,
but as the result of gnome-shell trying to attach a Clutter actor
to a non-existent window actor is pretty bad, also guard can_ping()
against being called for an unmanaging window.
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2467
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1676>
This seems to have been the default in the past, but was (accidentally?) modified
by 8adab0275.
For GNOME 40, we'll be returning to our root with horizontal workspaces, so instead
of overriding it in GNOME Shell side, change the default back to what it once was.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1684>
We'll have two persistent client connections alive for the whole test,
one X11 client, and one Wayland client. So in order to be able to set up
the async waiter, do so after setting up the X11 client, as after that
we know we'll have a MetaX11Display ready to use.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1681>
One for the public channel, and one for the private maintainance
channel. Use the public one for test clients, otherwise tests become
flaky, and the private one for MetaX11Display.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1681>
This adds a MetaKmsImplDevice backend using atomic drmMode* API in constrast to
non-atomic legacy drmMode* API used in MetaKmsImplDeviceSimple.
This has various behavioral differences worth noting, compared to the
simple backend:
* We can only commit once per CRTC per page flip.
This means that we can only update the cursor plane once. If a primary
plane composition missed a dead line, we cannot commit only a cursor
update that would be presented earlier.
* Partial success is not possible with the atomic backend.
Cursor planes may fail with the simple backend. This is not the case
with the atomic backend. This will instead later be handled using API
specific to the atomic backend, that will effectively translate into
TEST_ONLY commits.
For testing and debugging purposes, the environment variable
MUTTER_DEBUG_ENABLE_ATOMIC_KMS can be set to either 1 or 0 to
force-enable or force-disable atomic mode setting. Setting it to some
other value will cause mutter to abort().
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/548
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
In order to reliably manage the reference count of the user data passed
to page flip listeners - being the stage view - make the ownership of
this data travel through the different objects that take responsibility
of the next step.
Initially this is the MetaKmsPageFlipListener that belongs to a
MetaKmsUpdate.
When a page flip is successfully queued, the ownership is transferred to
a MetaKmsPageFlipClosure that is part of a MetaKmsPageFlipData. In the
simple impl device, the MetaKmsPageFlipData is passed to
drmModePageFlip(), then returned back via the DRM event. In the future
atomic impl device, the MetaKmsPageFlipData is stored in a table, then
retrieved when DRM event are handled.
When the DRM events are handled, the page flip listener's interface
callbacks are invoked, and after that, the user data is freed using the
passed GDestroyNotify function, in the main context, the same as where
the interface callbacks were called.
When a page flip fails, the ownership is also transferred to a
MetaKmsPageFlipClosure that is part of a MetaKmsPageFlipData. This page
flip data will be passed to the main context via a callback, where it
will discard the page flip, and free the user data using the provided
GDestroyNotify.
Note that this adds back a page flip listener type flag for telling the
KMS implementation whether to actively discard a page flip via the
interface, or just free the user data. Avoiding discarding via the
interface is needed for the direct scanout case, where we immediately
need to know the result in order to fall back to the composite pipeline
if the direct scanout failed. We do in fact also need active discard via
the interface paths, e.g. in the simple impl device when we're
asynchronously retrying a page flip, so replace the ad-hoc discard paths
in meta-renderer-native.c and replace them by not asking for no-discard
page flip error handling.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Suspending might have changed the CRTC configuration, turning some off,
some on, etc. We need to update our internal representation of this
state, so that we know how to reconfigure upon resuming, e.g. what CRTCs
to turn off again.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Destroying an onscreen destroyes the gbm_surface, the gbm_bo's, and the
fb_id's. Doing this (drmModeRmFB() of the fb_id specifically), may on
some hw implicitly disable the CRTC of the plane that framebuffer was
assigned to. This would cause following atomic commit that attempts to
disable the CRTC to fail as disabling an already disabled CRTC is not
allowed.
It'd also mean we'd always disable the plane before having finished next
mode set, leaving it monitor content potentially empty when not really
necessary.
Solve this by keeping the CoglOnscreens (thus the gbm_surface, gbm_bo
and fb_id) alive until the following global mode set has completed, i.e.
the new state has been fully committed and applied.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This makes "power save" (i.e. when you make a monitor go into power save
mode, or make it come out of power save mode), a per device action when
turning on power saving (power save being set to 'off'), and implicitly
handled when turning off power saving (power save being set to 'on')
when doing a mode set.
This is needed as with atomic mode setting, the configuration of DPMS
(Display Power Management Signaling), is replaced by directly turning on
or off CRTCs, and via the CRTC drm properties. Thus in order to handle
both with a common API, make that API high level enough for both cases
being covered.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Before we received new gamma updates via D-Bus and posted the update to
KMS directly. This won't be possible with atomic KMS, since one can only
update the state of a CRTC once per cycle.
Thus, to handle this, when configured by D-Bus, only cache the value,
and mark it as invalid. The next frame, the native renderer will pick
up the newly cached gamma value and configure the CRTCs accordingly.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
We cannot switch DPMS state to 'on' first, then mode set later, when
using atomic KMS. So when we're turning it on, just let the eventual
mode set handle DPMS too.
When switching DPMS to 'off', do it directly, synchronously, both by
setting the DPMS state and switching off CRTCs.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Before each frame is maybe redrawn, push any new cursor KMS state to the
pending update. It'll then either be posted during the next page flip,
or when the same frame finishes, in case nothing was redrawn.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This makes it possible to post a symbolic page flip and frame callback,
meant to be used by immediate symbolic page flip reply when emulating
cursor plane changes using legacy drmMode* functions.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
In constrast to notify_presented(), notify_ready() also returns the
state machine to the idle state, but without providing new frame
information, as no frame was actually presented.
This will happen for example with the simple KMS impl backend will do a
cursor movement, which will trigger a symbolic "page flip" reply in
order to emulate atomic KMS behavior. When this happen, we should just
try to reschedule again.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Don't mode set each CRTC in separate KMS updates, as reconfiguring one
CRTC might cause other CRTCs to be implicitly reset thus as well,
causing KMS return EBUSY if using atomic modesetting.
Prepare for this by compositing each CRTC first including adding steps
to the KMS update, but wait until all views has rendered at least once
before posting the initial update. After this each CRTC is posted
separately.
Using EGLStreams instead of normal page flipping seems to fail when
doing this though, so handle that the old way for the EGLStream case,
i.e. eglSwapBuffers() -> mode set with dumb buffer -> eglStream
"acquire" (resulting in page flip under the hood).
For this we also introduce a new error code so that we don't use client
buffers when doing mode sets, which could accidentally configure the
CRTC in a way that is incompatible with the primary plane buffers.
Do the same also when we're in power save mode, to only have one special
case path for this scenario in the regular swap-buffer path.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Instead of setting the frame result in the most generic layer, have the
backends do it themselves. This is necessary to communicate that a
swap-buffer call didn't really succeed completely to present the swapped
buffer, e.g. errors from KMS.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This argument is intended to be used by clutter to be able to
communicate with the onscreen backend, that happens to be the native
backend. It will be used to pass a ClutterFrame pointer, where the
result of page flips, mode sets etc can be communicated whenever it is
available.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
ClutterFrame aims to carry information valid during dispatching a frame.
A frame may or may not include redrawing, but will always end with a
result.
A asynchronous page flip, for example, will result in a
CLUTTER_FRAME_RESULT_PENDING_PRESENTED, while a frame that only
dispatched events etc will result in CLUTTER_FRAME_RESULT_IDLE. Instead
of this being implicit, make the ClutterStageWindow implementation
handle this itself.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
The way drm events are handled depends on whether we're using atomic or
not. Lets move the handling to the implementation, so that later the
atomic backend can handle the event they it need to.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
If we reassign e.g. a cursor plane twice before it's updated, we need to
make sure the 'fb-unchanged' flag is correctly handled, so that if we
changed the fb first, then updated the assignment again only changing
the position, the new assignment should not be flagged with
fb-unchanged.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
When we e.g. try to post an direct client buffer scanout update, it
might arbitrarily fail; when this happen we still will want to post the
rest of the update when we try again after having composited the primary
plane. To do this, add a way to preserve the metadata of an update if it
failed, only dropping the failed plane assignments. This involves
unlocking a previously locked MetaKmsUpdate, so that e.g. a new primary
plane can be assigned.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Sealing is a one way operation, but in the next commit, the "seal" will
be broken, so to avoid missusing the "seal" terminology, rename related
methods and variables to use the term "lock" instead. E.g.
meta_update_is_sealed() is now meta_update_is_locked().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
If a modeset is pending, it's likely that the cursor update will not
work; thus, wait with updating the cursor so that it's applied together
with the mode set update.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Something might want to affect the next update that is going to be
posted, but without posting it immediately. For example, changing the
cursor might need to wait for mode setting. Make it possible to get
feedback from posting the update, in order to gracefully handle any
errors.
Note, the API for notifiying about results take out the result listener
from the update, and notifies them in an open coded for loop. The reason
for this is that in the next commit we'll sometimes reuse updates, and
we only want notify about the results once.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Page flipping shouldn't necessarily be an actively requested action, but
happen implicitly depending on the given state. Thus, change the "page
flip" update into adding listeners for page flip feedback instead.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This will later make it possible to pass cursor plane assignments,
together with a complete update including the primary plane, but not
failing the whole update if just processing the cursor plane failed.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
If posting an update resulted in an immediate error, don't communicate
this failure using the page flip feedback callbacks, but directly as a
return value.
This makes it possible for the direct client buffer scanout path not to
pass around flags triggering this behavior, meaning we can handle such
direct scanouts better.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Instead of a "post all pending updates", pass an update specific to a
single device. This gets rid of the awkward "combine feedback" function,
and makes it possible to queue updates to a multiple devices without
always posting them together.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Custom page flips are meant to allow using e.g. EGLStream API to
indirectly trigger page flip queueing, when the KMS API cannot be used
directly. This is really something that is specific to a device, so
instead of making part of the page flip API, make it a configuration of
the update itself.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
Eventually the type of impl device will depend on the driver details, so
get that information before constructing the impl device. This commit
doesn't introduce any new usage of the details, it just prepares for
the future.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>