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>
Creates a GSource which will call the specified dispatch callback when
all dma-buf file descriptors for the buffer have become readable.
v2:
* Hold a reference to the buffer in the source, to prevent the buffer
from getting destroyed before the source.
v3:
* Do not use check callback, handle everything in dispatch callback.
(Dor Askayo)
v4: (Georges Basile Stavracas Neto)
* Define and use MetaWaylandDmaBufSource & MetaWaylandDmaBufSourceDispatch
types.
* Fix meta_wayland_dma_buf_source_dispatch &
meta_wayland_dma_buf_source_funcs formatting.
* Use gpointer instead of void*.
* Rename meta_wayland_dma_buf_get_source to
meta_wayland_dma_buf_create_source. (Carlos Garnacho)
v5:
* Explicitly handle NULL return value. (Jonas Ådahl)
v6:
* Fix style issue per check-style.py.
v7:
* Fix code style harder. (Jonas Ådahl)
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
And call it from meta_wayland_buffer_realize. This makes dma-buf fds
available for EGL image type buffers as well.
v2:
* Move buffer->dma_buf.dma_buf assignment value to next line.
(Jonas Ådahl)
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
Currently, we will notify the display about a new window being created
during the constructed phase of the GObject. During this time,
property-change notifications are frozen by GObject, so we'll emit a few
::notify signals only after the window-created signal, although
the actual property change happened before that.
This caused confusion in gnome-shell code where a notify::skip-taskbar =
true emission was seen when the property already was true inside a
window-created handler before.
In order to fix that that, we notify the window creation
post-construction
of the GObject on GInitable.init vfunc
Details
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6119#note_1598983
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6119
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2703>
A client may provide a positioner that places the window outside of its
parent. This isn't allowed, according to spec, so we hide the window and
log a warning. This, however, leads these affected clients with an
incorrect view of what is mapped or not, meaning it becomes harder to
recover.
Fix this by sending xdg_popup.done when we hide the popup due to an
invalid position. Don't error out the client, let the bug slide, as
that's a less jarring experience for existing applications that
reproduce this than being disconnected, which practically feels like a
crash.
Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/2408
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2645>
This reverts commit eac227a203.
Currently, Flatpak applications can bypass the X11 permission setting
and access the X server through abstract sockets because X11 authentication
is not enforced for the current user ID.
Fix this by always requiring X11 authentication for Xwayland. This also
means applications without XAUTHORITY set to the file with Mutter's
Xwayland credentials cannot connect to X, including apps launched from
VT or SSH.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2633>
Back in 2014 sending pressed keys to Wayland clients caused issues,
because at least Xwayland didn't handle that gracefully, causing issues
like ghost-pressed keys. A way it was reproduced was quickly alt-tab:ing
to and from a Firefox window, which would cause the File menu bar
incorrectly appearing.
While this was reported to the Xwayland component back then, it was,
probably by mistake, assumed to be an issue in mutter, and mutter
stopped sending pressed key events on enter.
The following year, Xwayland was eventually fixed, but the work around
in mutter has been kept around until it was again noticed as an
inconsistency between compositor implementations.
Lets remove the work around, and follow the spec, again.
This reverts commit c39f18c2d4.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2457
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2657>
We'd set the capabilities to 'none', meaning all previously enabled
device classes would be disabled. That means we shouldn't re-disable
them directly after.
This ensures '..disable()' is only called once for every '..enable()'.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2657>
In fcfe90aa, multiple for loops were replaced with
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE.
However, this substitution was not side-effect free, and introduced a
null-pointer dereference risk as shown in the example below:
Old:
for (n = g_node_first_child (surface->subsurface_branch_node);
n;
n = g_node_next_sibling (n))
{
if (G_NODE_IS_LEAF (n))
continue;
meta_wayland_surface_update_outputs_recursively (n->data);
}
n is checked for NULL during each loop in the condition expression.
Therefore, when `G_NODE_IS_LEAF (n)` is called, `n` is guaranteed not to
be NULL. Note also that g_node_first_child is also NULL-safe since it
performs a NULL check internally.
New:
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
meta_wayland_surface_update_outputs_recursively (subsurface_surface);
=
for (GNode *G_PASTE(__n, __LINE__) = meta_get_first_subsurface_node ((surface)); \
(subsurface = (G_PASTE (__n, __LINE__) ? G_PASTE (__n, __LINE__)->data : NULL)); \
G_PASTE (__n, __LINE__) = meta_get_next_subsurface_sibling (G_PASTE (__n, __LINE__)))
In the new logic `subsurface` is still checked for NULL in the loop
condition. However, in the new loop init:
...
meta_get_first_subsurface_node (MetaWaylandSurface *surface)
...
n = g_node_first_child (surface->subsurface_branch_node);
if (!G_NODE_IS_LEAF (n))
...
The above implementation performs a `G_NODE_IS_LEAF` call, which
performs a dereference on `n`, without first checking for NULLs.
This NULL dereference triggers the following gnome-shell crash:
Core was generated by `/usr/bin/gnome-shell'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 meta_get_first_subsurface_node (surface=0x55d589623450) at ../src/wayland/meta-wayland-surface.h:399
#1 pointer_can_grab_surface (pointer=0x7f6dc4012700, surface=0x55d589623450) at ../src/wayland/meta-wayland-pointer.c:1306
#2 0x00007f6ddb94d509 in meta_wayland_pointer_can_grab_surface (pointer=<optimized out>, surface=surface@entry=0x55d589623450, serial=serial@entry=996) at ../src/wayland/meta-wayland-pointer.c:1321
#3 0x00007f6ddb950d05 in meta_wayland_seat_get_grab_info (seat=seat@entry=0x55d586c24f20, surface=0x55d589623450, serial=996, require_pressed=require_pressed@entry=0, x=x@entry=0x0, y=y@entry=0x0)
at ../src/wayland/meta-wayland-seat.c:467
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2655>
Fullscreen Wayland toplevel surfaces don't need to respect the
configured size in which case it should be shown centered on the monitor
with a black background. The black background becomes part of the window
geometry.
The surface container is responsible for correctly culling the surfaces
and making sure the surface actors are removed from the actor tree to
avoid destroying them.
The window actor culling implementation assumes all surfaces to be direct
children of said actor. The introduction of the surface_container actor
broke that assumption. This implements the culling interface in
MetaWindowActorWayland which is aware of the actor surface_container and
fullscreen state.
v2: Fix forwarding culling to surface even if there is a background.
v2: Don't alter passed geometry.
v2: Update window geometry code documentation to reflect these changes.
v2: Only use constrained rect if we're acked fullscreen.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2338>
This is helpful to know what current state a window actually have, in
contrast to the state in MetaWindow (e.g. MetaWindow::fullscreen) which
is the intended state, be it current or not yet so.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2338>
First make sure we call 'move_resize()' in all cases where the size or
position can change, then move the updating of the buffer rect to the
same place as we update the frame rect. This means keeping track of
surface size changes, in addition to geometry changes, and calling
finish_move_resize() whenever any of those changes, in addition to
acknowledged configurations.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2338>
When a window configuration is constructed for a Wayland surface it
contains a position, size and a scale. The scale is the geometry scale
for the configuration, i.e. before the size is sent the passed dimension
is divided with the passed scale.
When moving between monitors with different scales, if we use the
existing geometry scale, this means we will send a configure event with
incorrect dimensions. Fix this by calculating the scale used in the
configuration given the rect we're configuring with as this will mean
the correct size will be sent to the client.
v2: Removed the fullscreen condition. Don't know why it was added to
begin with.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2338>
There were some magic conditions that decided when
meta_window_constrain() was to be called or not. Reasoning about and
changing these conditions were complicated, and in practice the caller
knows when constraining should be done. Lets change things by adding a
'constrain' flag to the move-resize flags that makes this clearer. This
way we can, if needed, have better control of when a window is
constrained or not without leaking that logic into the generic
to-constrain-or-not expression.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2338>
We'll never scan out, which is why ADDFB2 is required otherwise, and we
won't enable the DMA buffer extension if
'EGL_EXT_image_dma_buf_import_modifiers' is missing, so send modifiers
in this case.
This also happens to avoid crashing when the GPU is null, since we'd
otherwise attempt to dereference it.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2578>
This is what the protocol says we should do, and even though normally
an out of focus client should not have any reason to create IM requests,
there is a bit of a grey area around focus changes, as both the client
losing focus and the client gaining focus may respectively try to
disable/enable in an undetermined order.
Anyways, since in that situation the client losing focus is not aware
of the requests being ignored, the serial should always be incremented
in order not to break accounting of .done/.commit for that specific
client.
Fixes the IM focus being possibly "lost" after changing focus between
clients, if the race condition turned the odds in that direction.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2585>
Same applies to MetaOutput. The reason for this is to make it possible
to more reliably know when there was EDID telling us about these
details. This will be used for colord integration.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2141>
In the timespan between an activation token being created and the
token being used by the activated application, the surface that started
the activation request may end up destroyed/disposed.
In that case, the token would be left with a stale surface pointer,
maybe causing crashes later on. Set up a destroy notification listener
so that we do know to unset the token surface if that situation arises,
this will result in Mutter not considering the token activatable, thus
maybe issuing the "Application needs attention" notification if the
activated surface did not immediately get focus. In any case this is
better than a compositor crash.
A typical situation where this may happen is "Open With..." dialogs,
since those don't live long after launching the application.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2390
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2592>