This means objects have an owner, where the chain eventually always
leads to a MetaContext. This also means that all objects can find their
way to other object instances via the chain, instead of scattered global
singletons.
This is a squashed commit originally containing the following:
cursor-tracker: Don't get backend from singleton
idle-manager: Don't get backend from singleton
input-device: Pass pointer to backend during construction
The backend is needed during construction to get the wacom database.
input-mapper: Pass backend when constructing
monitor: Don't get backend from singleton
monitor-manager: Get backend directly from monitor manager
remote: Get backend from manager class
For the remote desktop and screen cast implementations, replace getting
the backend from singletons with getting it via the manager classes.
launcher: Pass backend during construction
device-pool: Pass backend during construction
Instead of passing the (maybe null) launcher, pass the backend, and get
the launcher from there. That way we always have a way to some known
context from the device pool.
drm-buffer/gbm: Get backend via device pool
cursor-renderer: Get backend directly from renderer
input-device: Get backend getter
input-settings: Add backend construct property and getter
input-settings/x11: Don't get backend from singleton
renderer: Get backend from renderer itself
seat-impl: Add backend getter
seat/native: Get backend from instance struct
stage-impl: Get backend from stage impl itself
x11/xkb-a11y: Don't get backend from singleton
backend/x11/nested: Don't get Wayland compositor from singleton
crtc: Add backend property
Adding a link to the GPU isn't enough; the virtual CRTCs of virtual
monitors doesn't have one.
cursor-tracker: Don't get display from singleton
remote: Don't get display from singleton
seat: Don't get display from singleton
backend/x11: Don't get display from singleton
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2718>
While already cleaning up API, if this should ever be more non-static
than a constant, it's better if its a function on the monitor manager
instance than something static.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2718>
Since the Wacom panel rewrite, the "output" setting is handled as
a kind of tri-state for display-integrated tablets:
- If the setting is unset, the device is automatically mapped
to an output
- If the setting is set and not empty, the device is mapped to
the output defined by the EDID data
- If the setting is ['', '', ''], the device is mapped to the
span of all displays, like opaque tablets do.
This distinction for the unset setting fell through the cracks,
so both "Automatic" and "All displays" options were handled as
the former.
Add this distinction, so that display-integrated tablets can
be used like opaque tablets of sorts with no limitations.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2767>
These are the ones attached to a display, thus they are the ones that may need
help from this heuristic. Non-integrated tablets (e.g. Intuos) will default to
the span of all monitors.
Fixes mapping of opaque tablets if a display-integrated tablet of the same
brand is also plugged in.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2767>
This might happen when the workspace is not switched and
focus_default_window is called or when 'workspace on primary display
only' is enabled, a secondary display exists and the workspace is
switched.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2747>
There's 2 users of this, meta_display_sync_wayland_input_focus() which
does already perform these checks on its own, and MetaCursorTracker's
update_displayed_cursor() to determine whether it should go with the
Wayland client's cursor.
This second check should also consider the existing ClutterGrabs, so
make meta_display_windows_are_interactable() handle them for both
callers.
Fixes the cursor shown over windows while e.g. there are menus opened.
Close: https://gitlab.gnome.org/GNOME/mutter/-/issues/2553
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2754>
This code path is important for "empty" commits to ensure we schedule
frame callbacks even if previous commits didn't cause stage redraws.
There is, however, no reason to schedule updates on all stage views
instead of only those the actor is on.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2671>
Avoid some allocations, save some CPU cycles and make the code easier
to read.
Behaviourwise the only expected change is that now, if there are mapped
clones, we unconditionally choose the view with the highest refresh
rate the actor (or one of its clones) is on and don't check the
obscurred region any more.
Thus in some cases a client may receive a higher rate of frame callbacks
when obscured on a faster view while a clone is present on a slower
one. The assumption is that cases like this are relatively rare and
that the reduction of code complexity, the reduction of allocations in
`meta_surface_actor_is_obscured_on_stage_view()` whenever the actor is
not fully obscured and has clones on other views, as well as generally
fewer lookups and less code in most common cases, compensate for that.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2671>
We only support feedback-actors, such as DnD-icons, in the compositing
path at the moment.
The approach is similar to how we handle certain shell elements.
Implementations need to ensure no references to the object keep
around longer that necessary.
Arguably this should be replaced by a more robust and implicit actor
hierachy detection in the direct scanout code at some point.
Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/2470
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2677>
The fields of 'priv->video_format.max_framerate' are all of type
uint32_t. Multiplying by G_USEC_PER_SEC can overflow, and equally,
dividing a large numerical type by uint32_t can err too.
Since the variable holding the result is int64_t, cast all uint32_t
fields to int64_t before doing any maths on it.
Spotted while trying to investigating an issue with framerates on
HDMI screencasts.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2762>
Add a helper function that ensures any queued virtual input events have
been flushed from the input thread. This works by posting a task to the
input thread, which will itself queue another callback back to the main
thread. Once the main thread callback is invoked, the flush call is
unblocked and the function returns. Upon this, any previously emitted
virtual input event should have already passed through the input thread
back into the main thread, however not necessarily fully processed.
For making sure it has been processed, one also have to make sure the
stage has been updated, e.g. via `meta_wait_for_paint()`.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2727>
After the commit "wayland/subsurface: Implement
meta_wayland_surface_get_window()" subsurfaces are supported. Adjust
some comments and fix a warning that could occur when closing a window.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2717>
The intention here was to check if the subsurface belongs to a window.
Thus it didn't behave as expected for subsurfaces belonging to non-toplevel
windows.
After the previous commit we can use `get_window()` to check for what we
actually want here.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2717>
Subsurfaces are special regarding windows as they don't have a window,
but usually have an ancestor which does. All current users of
`get_window()` are either used for known surface roles, such as xdg-*
ones, or, as is the case for pointer constrains, would actually want to
get the ancestors window.
Thus implement `get_window()` to allow pointer constrains to work.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2223
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2717>
The meta_prop_get_motif_hints() function was only used in the
old MetaUI frames code. The remaining code in mutter accesses
directly the MetaPropValue when loading properties for a window,
and does not use this API call.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2741>
Since we use XCB in the Mutter side, but Xlib in the frames client,
we cannot share the same struct definition since both libraries
will expect different type lengths (respectively, 32-bit ints vs.
longs).
Revert the changes that made both executables share the same
struct, since not both of them can get it right (and retrieve
correctly the struct with the contained flags) in reading the
Motif WM hints.
This reverts commit 2fb3c5a4f5.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2741>
Adding the 'default-decoration' CSS class to MetaFrameHeader after
it is set as the headerbar makes it not account for the minimum size
correctly sometimes. This is a bit racy though - if the window opens
very quickly, it works as expected.
Adding the CSS class before the widget is used guarantees it'll
always report the correct size though, so do that.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2753>
Add this CSS class both to the header bar itself, since it is what
actually contains the window controls, and to MetaFrameHeader too,
since it's what's directly attached to the window.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2740>
Previous commit added support for setting the GTK4 theme setting
according to the color scheme setting. That's cool. What it didn't
add, though, was initializing the GTK4 theme setting to the proper
value. That means if the desktop starts at dark style, you'd still
get a light titlebar.
Fix that by updating the GTK4 theme setting on init as well.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2740>
These are now referenced on the frames client side (in order to
track deletable state from the client window) and the mutter side
(pretty much everything else, like figuring out if a window wants
WM decorations).
It makes sense to make this a separate header, so that we don't
need to doubly define these flags/structs.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2735>
We use this for tracking the deletable state of the client window,
but forgot to check that the MWM_HINT_FUNCTIONS hint is set in
hints.flags before checking hints.functions.
This resulted in windows that do not specify this flag (and thus
should go with the defaults) in being mistakenly removed the close
button, as the functions flags would be typically 0 in that case.
Fixes issues with Chromium and Electron applications missing the
close button, since Chromium does this on X11.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2735>
Recalculating window features is a busy thing on the Mutter side, the
different properties being (re)set will overwrite the current state
and cause some side work. Between that is the rewriting of the
_MUTTER_NEEDS_FRAME property on the window being recalculated, which
throws the frames client off, by thinking the window does actually
require a new frame.
It is not sufficient to trust that PropertyNewValue means the property
or the value are new, also double check that the window did not have
in fact a frame, and avoid the busy work if it did.
Besides the busywork that can be easily avoided, this also fixes the
window close button state being stuck if the window changed its
deletable state, since the frame being respawn managed to miss the
property change.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2735>
meta_screen_cast_window_stream_src_set_cursor_metadata() relies
entirely on meta_screen_cast_window_transform_cursor_position()
to return the correct relative cursor position.
However, this function actually does not return the expected
values, since it does not apply the resource scale to the
transformed position.
Actually apply the cursor scale when calculating the cursor
position.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2737>
meta_screen_cast_stream_src_set_cursor_sprite_metadata() receives
the cursor sprite, position, and scale, and with that it downloads
the cursor sprite by drawing it into a separate framebuffer, then
calls cogl_framebuffer_read_pixels() in it - this is the offscren
path that is very common when using screen capturing applications
such as OBS Studio.
There's a sneaky issue in this code path though: the 'scale' value
is a float. The cursor size is then determined by multiplying the
sprite width and height - two integer variables - by scale, and
this relies on standard float-to-int conversions. This is problematic
as sometimes the rounded values disagree with what is expected by
cogl_framebuffer_read_pixels(). If the packing of either the cursor
width or height is off by one, glReadPixels() will try to write into
off bounds, which crashes.
This can be reproduced by enabling fractional scaling, setting a 150%
zoom level, on a 4K screen, and opening any commit with an image diff
in gitlab.gnome.org, all while screencasting. When hovering the new
image, the cursor sprite will be such that it triggers this code path,
and reproduces this issue.
Fix this by always ceiling the cursor sprite sizes.
Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/2542
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2736>
The uninitialized fields in this event causes use of uninitialised
data as seen in valgrind:
==71864== Syscall param writev(vector[0]) points to uninitialised byte(s)
==71864== at 0x5026EBD: __writev (writev.c:26)
==71864== by 0x5026EBD: writev (writev.c:24)
==71864== by 0x6482A3B: UnknownInlinedFun (xcb_conn.c:296)
==71864== by 0x6482A3B: _xcb_conn_wait.part.0 (xcb_conn.c:551)
==71864== by 0x6482BAF: UnknownInlinedFun (xcb_out.c:469)
==71864== by 0x6482BAF: _xcb_out_send (xcb_out.c:470)
==71864== by 0x6483DD7: UnknownInlinedFun (xcb_out.c:416)
==71864== by 0x6483DD7: xcb_writev (xcb_out.c:409)
==71864== by 0x53B79B4: _XSend (xcb_io.c:587)
==71864== by 0x53BBF38: _XReply (xcb_io.c:679)
==71864== by 0x53AFFC9: XQueryTree (QuTree.c:47)
==71864== by 0x4982A5F: query_xserver_stack (stack-tracker.c:508)
==71864== by 0x4EA1F5F: g_closure_invoke (gclosure.c:832)
==71864== by 0x4ECFD45: signal_emit_unlocked_R.isra.0 (gsignal.c:3796)
==71864== by 0x4EC0129: g_signal_emit_valist (gsignal.c:3549)
==71864== by 0x4EC03B2: g_signal_emit (gsignal.c:3606)
==71864== Address 0x287d5900 is 32 bytes inside a block of size 16,384 alloc'd
==71864== at 0x4849444: calloc (vg_replace_malloc.c:1340)
==71864== by 0x53A5FE8: XOpenDisplay (OpenDis.c:240)
==71864== by 0x6100E3C: _gdk_x11_display_open (gdkdisplay-x11.c:1565)
==71864== by 0x60CF675: gdk_display_manager_open_display (gdkdisplaymanager.c:462)
==71864== by 0x49D59F1: open_gdk_display (meta-x11-display.c:1041)
==71864== by 0x49D5D64: meta_x11_display_new (meta-x11-display.c:1156)
==71864== by 0x49564AD: meta_display_init_x11_finish (display.c:743)
==71864== by 0x495679D: on_x11_initialized (display.c:818)
==71864== by 0x4D67558: g_task_return_now (gtask.c:1232)
==71864== by 0x4D67782: UnknownInlinedFun (gtask.c:1301)
==71864== by 0x4D67782: g_task_return (gtask.c:1258)
==71864== by 0x495663C: on_xserver_started (display.c:788)
==71864== by 0x4D67558: g_task_return_now (gtask.c:1232)
==71864== Uninitialised value was created by a stack allocation
==71864== at 0x49D4A59: take_manager_selection (meta-x11-display.c:640)
==71864==
To fix this, fully initialize the event struct before sending it.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2535
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2724>
Since the frames are now rendered by a separate process, we no longer
can guarantee at this point that all updates were handled. Engaging
in a new synchronous resize operation will again freeze the actor,
so sometimes we are left with a not-quite-current buffer for the
frame+window surface.
In order to ensure that the right changes made it onscreen, delay
this next synchronous resize step until the moment the surface was
repainted. This avoids those glitches, while still ensuing the
resize operation ends up in sync with the pointer.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
Let the frames client render its own shadow. In order to do that,
avoid double painting a shadow on the compositor side, and extend
the mask area of the frame, so it does unveil the (so far)
hidden frames-client-side shadows.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
There's two meanings of "frame" there! Since SSD frames are now
rendered by an external client, and there are no actual mechanism
that ensures the frame did already get painted when the client did
respond to its NET_WM_FRAME_SYNC_REQUEST request, there may be
artifacts when resizing windows.
In order to get always the best visual result, we should actually
synchronize rendering with both the client window and the window
frame window.
This commit adds these mechanisms, so a sync alarm update is
expected on both windows until further resizes are allowed, this
ensures window and frame stay in sync, even after moving rendering
elsewhere.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
It will become necessary to track properties and changes from frame windows,
and it will be more convenient to have this managed by the common property
tracking mechanisms.
Add this source_xwindow parameter so property handler functions can check
whether the property belonged to the client Window or the frame Window.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
Store the alarms in a different hashtable, and look up the MetaSyncCounter
right away. It so far avoids the MetaWindow middle man, but will also be
simpler when each window can possibly have more than one active alarms.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
Replace the in-process implementation of frames with the external
frames client.
When a client window is created and managed by Mutter, Mutter will
determine whether it is a window that requires decorations and
hint the creation of a frame for it by setting the _MUTTER_NEEDS_FRAME
property on the client window.
After the frames client created a window that has the _MUTTER_FRAME_FOR
property, Mutter will proceed to reparent the client window on the
frame window, and show them as a single unit.
Rendering and event handling on the frame window will be performed by
the external client, Mutter is still responsible for everything else,
namely resizing client and frame window in synchronization, and
managing updates on the MetaWindowActor.
In order to let the frame be managed by the external client, Mutter
needs to change the way some properties are forwarded to the client
and/or frame windows. Some properties are necessary to keep propagating
to the client window only, some others need to happen on the frame
window now, and some others needs to be propagated on both so they
are synchronized about the behavior.
Also, some events that were previously totally unexpected in frame
windows are now susceptible to happen, so must be allowed now.
MetaFrame in src/core/frame.c now acts as the wrapper of foreign
windows created by the frames client, from the Mutter side. Location,
size, and lifetime are still largely in control of Mutter, some
details like visible/invisible borders are obtained from the client
instead (through the _MUTTER_FRAME_EXTENTS and _GTK_FRAME_EXTENTS
properties, respectively).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
This small X11 client takes care of creating frames for client
windows, Mutter will use this client to delegate window frame
rendering and event handling.
The MetaWindowTracker object will keep track of windows created
from other clients, and will await for _MUTTER_NEEDS_FRAME property
updates on those (coming from Mutter), indicating the need for a
frame window.
This process is resilient to restarts of the frames client, existing
windows will be queried during start, and the existence of relevant
properties checked. Mutter will be able to just hide/show
SSD-decorated windows while the frames client restarts.
The frames are created through GTK4 widgets, the MetaWindowContent
widget acts as a replacement prop for the actual client window,
and the MetaFrameHeader wraps GtkHeaderBar so that windows can be
overshrunk, but otherwise a MetaFrame is a 100% true GTK4 GtkWindow.
After a frame window is created for a client window, the
_MUTTER_FRAME_FOR property will be set on the frame window,
indicating to mutter the correspondence between both Windows.
Additionally, the pixel sizes of the visible left/right/top/bottom
borders of the frame will be set through the _MUTTER_FRAME_EXTENTS
property, set on the frame window.
In order to make the frame window behave as the frame for the
client window, a number of properties will be tracked from the
client window to update the relevant frame behavior (window title,
resizability, availability of actions...), and also some forwarding
of events happening in the frame will be forwarded to the client
window (mainly, WM_DELETE_WINDOW when the close button is clicked).
Other than that, the frames are pretty much CSD GTK4 windows, so
window drags and resizes, and window context menus are forwarded for
the WM to handle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
This check dates all the way back to commit ac2aa5337d. At the time, the
window switcher was an actual X window, that could generate crossing events
if popped up under the pointer. Checking for this kind of crossing events
made sense back at the time in order not to break focus-follows-mouse as
it's been behaving for long.
But now, this UI is all Clutter widgetry, which in the worst case (X11
sessions, of course) it will update the stage window shape to make these
parts clickable. This happens in other places of code that do already
check for ignoring crossing events.
Underneath, this looked up for a Mutter-local GdkWindow of type
GDK_WINDOW_TEMP, only the main MetaFrames window matches those characteristics
nowadays, notably no window switcher popups. Since the remaining window is
never unmapped (until perhaps shutdown), the paths were functionally dead.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
If the window is not managed, it's weird that it asks for _NET_FRAME_EXTENTS,
it's even weirder that mutter replies with a frame border that would only
apply if the window were managed. Stop doing the latter, and drop the
MetaUI call that calculates borders from the theme settings.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
Put the helper to use, in order to lift MetaWindow itself from this
accounting. As a bonus, the data itself now moved to the MetaWindowX11
private struct, since this may only happen with X11 windows (or its
Xwayland subclass).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
This helper struct takes care of the handling of requests and alarms
in order to satisfy NET_WM_SYNC_REQUEST. It will be necessary to
decouple rendering of windows and frames in future commits, so each
window may need its own synchronization and accounting.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
This may result in a view of the stack in MetaStackManager that does not correspond
to reality, since the window is already being unmanaged, there is no point either in
notifying the stack manager about it.
This slight divergence with reality in the MetaStackManager may produce a non-accurate
view if querying its state has to go through the predicted branches. Later synchronization
with the X11 stack may even this out, but the result really depends on when it is asked.
Fixes some intermittent failures in the stacking/closed-transient-only-take-focus-parents
unit test.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
The meta_window_show() method internally relies on window->mapped being
up-to-date, or attempting to focus it may fail since the window is not
mapped yet, resulting on the window being mapped, but not focused as
it would be expected.
This is moot so far, since windows with frames are created sort-of
synchronously and showing them will result in the focus attempt happening
when the window is already mapped, but things will break when this
becomes an asynchronous step.
Ensure to synchronize client state before showing, so any attempts to
focus the window are able to succeed despite the initial state when
calling meta_window_update_visibility().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
The test does simply "wait" which apparently is not enough to ensure the
client window did resize to the expected dimensions. Use "wait_reconfigure"
and assert that the size after resize is the expected, before going further
at testing its behavior after maximize/unmaximize; it might end up with the
unexpected size after the whole operation.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
Move the use count from a separate MetaWaylandBufferRef struct to the
MetaWaylandBuffer class, and remove the former.
The buffer use count is now incremented already in
meta_wayland_surface_commit, since the Wayland protocol defines the
buffer to be in use by the compositor at that point. If the buffer
attachment ends up being dropped again before it is applied to the
surface state (e.g. because another buffer is committed to a
synchronized sub-surface before the parent surface is committed),
the use count is now decremented, and a buffer release event is sent if
the use count drops to 0.
Buffer release events were previously incorrectly not sent under these
circumstances. Test case: Run the weston-subsurfaces demo with the -r1
and/or -t1 command line parameter. Resize the window. Before this
change, weston-subsurfaces would freeze or abort after a few resize
operations, because mutter failed to send release events and the
client ran out of usable buffers.
v2:
* Handle NULL priv->buffer_ref in
meta_wayland_cursor_surface_apply_state.
v3:
* Remove MetaWaylandBufferRef altogether, move the use count tracking
to MetaWaylandBuffer itself. Much simpler, and doesn't run into
lifetime issues when mutter shuts down.
v4:
* Warn if use count isn't 0 in meta_wayland_buffer_finalize.
* Keep pending_buffer_resource_destroyed for attached but not yet
committed buffers. If the client attaches a buffer and then destroys
it before commit, we ignore the buffer attachement, same as before
this MR.
v5:
* Rebase on top of new commit which splits up surface->texture.
* MetaWaylandSurfaceState::buffer can only be non-NULL if
::newly_attached is TRUE, simplify accordingly.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
Until all dma-buf file descriptors for all buffers in the transaction
are readable, which corresponds to when the client drawing to the
buffers has finished.
This fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1162 if the
GPU & drivers support high priority contexts which can preempt lower
priority contexts.
v2:
* Also remove dma-buf fds from transaction and try applying it from
pending_buffer_resource_destroyed. Avoids freeze due to leaving a
GSource based on a closed fd attached if a client destroys a wl_buffer
which is part of a transaction which was committed but not applied
yet. (Robert Mader)
* Tweak transaction cleanup logic in wl_surface_destructor.
v3:
* Adapt to meta_wayland_dma_buf_get_source.
v4:
* Adapt to new commits using transactions for (sub-)surface destruction,
drop code to remove destroyed surfaces from pending transactions.
v5:
* Use g_clear_pointer in meta_wayland_transaction_destroy.
(Georges Basile Stavracas Neto)
* Add spaces between type casts and values. (Carlos Garnacho)
* Use (gpointer *) instead of (void**). (Carlos Garnacho)
* Use gpointer instead of void * in
meta_wayland_transaction_dma_buf_dispatch.
v6:
* Use g_hash_table_remove in meta_wayland_transaction_dma_buf_dispatch.
(Carlos Garnacho)
v7: (Jonas Ådahl)
* Move include of glib-unix.h below that of meta-wayland-transaction.h.
* Split up g_hash_table_iter_next call to multiple lines in
meta_wayland_transaction_commit.
* Call g_source_destroy as well as g_source_unref when freeing a
committed but not yet applied transaction (during mutter shutdown).
v8:
* Drop dma_buf_source_destroy, can use g_source_destroy directly.
(Jonas Ådahl)
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
From xdg_surface_constructor_get_popup / xdg_popup_reposition (called
during Wayland protocol processing) to finish_popup_setup /
meta_wayland_xdg_popup_apply_state (called when the popup state is
applied).
This makes sure that the parent window frame rectangle is up to date in
meta_wayland_xdg_positioner_to_placement.
v2:
* Use meta_wayland_surface_state_new () in
meta_wayland_transaction_add_xdg_popup_reposition.
v3:
* Move xdg_popup_repositioned handling to
meta_wayland_xdg_popup_apply_state.
v4:
* Do not steal pending->xdg_positioner in
meta_wayland_xdg_popup_apply_state, fixes leaking the corresponding
memory.
* Drop MetaWaylandSurfaceState::xdg_popup_repositioned, just use
::xdg_positioner.
v5:
* Reformat meta_wayland_xdg_positioner_to_placement calls to stay within
80 columns. (Jonas Ådahl)
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
This makes sure that finish_popup_setup is called after any previous
transactions for the parent surface have been applied, so the parent
window geometry is up to date.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
Preparation for potentially calling meta_wayland_transaction_apply some
time after surface commit, in which case doing it in the former would be
too late: The client may legally destroy the attached wl_buffer
immediately after commit, in which case meta_wayland_buffer_attach would
spuriously fail and disconnect the client (or possibly even crash mutter
due to NULL error).
Requires splitting up the surface texture between protocol and output
state, and propagating from the former to the latter via
MetaWaylandSurfaceState.
v2: (Jonas Ådahl)
* Move meta_wayland_surface_get_texture call to separate line.
* Use g_autoptr for GError.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
And keep track of the hierarchy separately for the Wayland protocol and
for output. Protocol state is updated immediately as protocol requests
are processed, output state only when the corresponding transaction is
applied (which may be deferred until the next commit of the parent
surface).
v2:
* Directly add placement ops to a transaction, instead of going via
pending_state.
* Use transaction entry for the sub-surface instead of that for its
parent surface.
v3:
* Use transaction entry for the parent surface again, to ensure proper
ordering of placement ops, and call
meta_wayland_surface_notify_subsurface_state_changed only once per
parent surface.
* Drop all use of wl_resource_add_destroy_listener, transactions are
keeping surfaces alive as long as needed.
v4:
* Rebase on https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2501
* Drop ClutterActor code from meta_wayland_surface_apply_placement_ops.
(Robert Mader)
v5:
* Rename MetaWaylandSubSurfaceState to MetaWaylandSurfaceSubState, since
the next commit adds not sub-surface specific state to it.
v6:
* Move include of meta-wayland-subsurface.h from
meta-wayland-transaction.c to .h, since the latter references
MetaWaylandSubsurfacePlacementOp.
v7:
* Drop superfluous !entry check from meta_wayland_transaction_apply.
v8:
* Rename output/protocol fields to output/protocol_state. (Jonas Ådahl)
v9:
* Use meta_wayland_surface_state_new in
meta_wayland_transaction_add_placement_op.
v10:
* Fix a few style issues per check-style.py.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
Destroy Wayland protocol related state immediately when the Wayland
resource is destroyed, but keep the rest alive by any transaction which
references the surface.
This makes it easier and cleaner to deal with a surface getting
destroyed while it's still referenced by transactions.
v2:
* No more need to keep references for surfaces in the entries hash
table.
v3:
* Do not use surface->sub.transaction in wl_surface_destructor, just
destroy it.
v4:
* No need for wl_surface_destructor to use its own transaction.
v5:
* Use g_steal_pointer & (more) g_clear_pointer in wl_surface_destructor.
v6:
* Leave SURFACE_DESTROY signal emission in wl_surface_destructor.
v7:
* Use finalize instead of dispose callback.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
This keeps all surfaces referenced by a transaction alive until the
transaction is destroyed, and makes sure transactions are applied in
the same order as they were committed with respect to all surfaces
they reference.
v2:
* Guard against NULL entry in meta_wayland_transaction_apply.
v3:
* Keep single entries hash table.
v4:
* Unref the surface in the meta_wayland_transaction_merge_into while
loop only if the "to" transaction didn't already have an entry for it,
to prevent premature finalization of the surface (likely followed by a
crash).
v5:
* Unref the surface (implicitly via g_hash_table_iter_remove) in the
meta_wayland_transaction_merge_into while loop even if the "to"
transaction already had an entry for it, or we leak a reference.
* Use g_clear_object & g_steal_pointer to not leave behind a dangling
from->state pointer in meta_wayland_transaction_entry_merge_into.
v6:
* Add curly braces around
meta_wayland_transaction_add_placement_surfaces calls. (Jonas Ådahl)
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
Instead of cached_state.
surface_commit for a synchronized sub-surface either commits the
transaction or merges it into the parent surface's transaction (if
the parent is a synchronized sub-surface itself).
This should fix or at least improve the behaviour of nested synchronized
sub-surfaces.
Also change wl_subsurface_set_desync:
* Commit sub-surface transactions separately. This may allow some of
them to be applied earlier in some cases.
* Commit transaction only for descendant sub-surfaces which become
newly de-synchronized themselves.
v2:
* Drop unused function prototypes
v3:
* Use g_clear_pointer for surface->sub.transaction.
v4:
* Use g_steal_pointer instead of g_clear_pointer. (Sebastian Wick, Jonas
Ådahl)
v5: (Carlos Garnacho)
* Add spaces between type casts and values.
* Use (gpointer *) instead of (void**).
v6: (Jonas Ådahl)
* Use g_clear_object in meta_wayland_transaction_entry_merge_into.
* Use meta_wayland_transaction_entry_free in
meta_wayland_transaction_merge_into.
* Fix alignment of meta_wayland_transaction_merge_pending_state
parameters.
* Remove unused meta_wayland_transaction_add_state declaration.
v7:
* Use meta_wayland_surface_state_new in
meta_wayland_transaction_merge_pending_state.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
A transaction contains the committed state for a surface, plus any
cached state for synchronized subsurfaces.
v2:
* Handle sub-surface positions separately from surface states.
v3:
* Sync child states only for surfaces with state in the transaction.
v4: (Jonas Ådahl)
* Drop unnecessary g_object_new call from wl_subsurface_set_desync. (me)
* Fix indentation & formatting in meta_wayland_surface_commit.
* Add meta_wayland_surface_state_new helper function.
* Fix alignment of meta_wayland_transaction_apply_subsurface_position
parameters.
* Add curly braces around meta_wayland_transaction_sync_child_states
call in meta_wayland_transaction_apply.
v5:
* Make meta_wayland_surface_state_new an inline function.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
If multiple transactions have entries for the same surface, they are
applied in the same order as they were committed. Otherwise, they can
be applied in any order.
This is preparation for following changes, transactions are still
applied as soon as they're committed.
v2:
* Move GQueue for transactions to MetaWaylandCompositor (Jonas Ådahl)
v3
* Say "entry for" instead of "state for", since there can be transaction
entries with no state (for surfaces which are getting destroyed).
v4:
* Use a hash table to keep track of all candidate transactions which
might be newly ready to be applied.
* Use clearer function / variable names.
v5:
* Use custom single-linked list instead of hash table for candidate
transactions, ordered by the transaction commit sequence number, so
that they're attempted to be applied in the same order as they were
committed.
* Rename transaction->queue to transaction->committed_queue, and
simplify its handling.
v6: (Carlos Garnacho)
* Add spaces between type casts and values.
* Use (gpointer *) instead of (void**).
v7: (Jonas Ådahl)
* Use G_MAXSIZE instead of ULONG_MAX.
* Fix indentation of meta_wayland_transaction_apply &
meta_wayland_transaction_maybe_apply_one parameters.
* Refactor find_next_transaction_for_surface & ensure_next_candidate
helper functions out of meta_wayland_transaction_apply.
* Refactor has_unapplied_dependencies helper function out of
meta_wayland_transaction_maybe_apply_one.
* Make while (TRUE) loop in meta_wayland_transaction_maybe_apply
consistent with general usage.
* Drop unused value local from meta_wayland_transaction_commit.
* Store pointer to compositor object in transactions, instead of
pointer to the queue of committed transactions.
* Drop tautological g_assert from meta_wayland_transaction_apply. (me)
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
v2:
* Use single hash table with struct which will contain all kinds of
state handled by a transaction.
v3:
* Add meta_wayland_transaction_destroy.
v4 (Georges Basile Stavracas Neto)
* Fix struct _MetaWaylandTransaction(Entry) formatting.
* Explicitly test against NULL.
* Use gpointer insteadof void * for
meta_wayland_transaction_entry_destroy.
v5: (Robert Mader)
* Use for loop in is_ancestor.
* Include meta-wayland-transaction.h first in
meta-wayland-transaction.c.
v6:
* Use g_autofree & g_clear_object.
v7: (Jonas Ådahl)
* Rename meta_wayland_transaction_entry_destroy to
meta_wayland_transaction_entry_free.
* Drop g_autofree use from meta_wayland_transaction_entry_free again.
* Make meta_wayland_transaction_entry_free take a
MetaWaylandTransactionEntry pointer.
* Rename meta_wayland_transaction_destroy to
meta_wayland_transaction_free.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
Need to deal with surface->resource == NULL and
surface->pending_state == NULL in some places.
v2:
* Avoid expanding conditions to multiple lines.
(Georges Basile Stavracas Neto)
v3:
* Use a single bailout condition in meta_wayland_client_owns_window as
well.
v4:
* Remove spare empty line in meta_wayland_surface_apply_state.
(Robert Mader)
* Add wl_resource_post_error calls in xdg-shell request handlers.
(Robert Mader)
* Drop checks in functions which can only be called if there's a valid
resource.
* Drop more checks which are unnecessary due to leaving the
SURFACE_DESTROY signal emission in wl_surface_destructor later.
v5:
* Move resource = surface->resource assignments to if (!resource) tests.
(Jonas Ådahl)
v6:
* Fix style issue per check-style.py.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>