wayland/subsurface: Drop unapplied subsurface state on unmap

To prevent it from getting spuriously applied if a wl_subsurface is
later created again for the same wl_surface.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3364>
This commit is contained in:
Michel Dänzer 2023-11-02 19:02:03 +01:00 committed by Marge Bot
parent cdfc8cf967
commit 35d92e0fac
4 changed files with 70 additions and 0 deletions

View File

@ -397,11 +397,38 @@ wl_subsurface_place_below (struct wl_client *client,
META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW); META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW);
} }
void
meta_wayland_subsurface_drop_placement_ops (MetaWaylandSurfaceState *state,
MetaWaylandSurface *surface)
{
GSList **list = &state->subsurface_placement_ops;
GSList *link = *list;
while (link)
{
MetaWaylandSubsurfacePlacementOp *op = link->data;
if (op->surface == surface)
{
g_free (link->data);
*list = g_slist_delete_link (*list, link);
}
else
{
list = &link->next;
}
link = *list;
}
}
static void static void
permanently_unmap_subsurface (MetaWaylandSurface *surface) permanently_unmap_subsurface (MetaWaylandSurface *surface)
{ {
MetaWaylandSubsurfacePlacementOp *op; MetaWaylandSubsurfacePlacementOp *op;
MetaWaylandTransaction *transaction; MetaWaylandTransaction *transaction;
MetaWaylandSurface *parent;
MetaWaylandSurfaceState *pending_state;
op = get_subsurface_placement_op (surface, NULL, op = get_subsurface_placement_op (surface, NULL,
META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW); META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW);
@ -412,6 +439,24 @@ permanently_unmap_subsurface (MetaWaylandSurface *surface)
meta_wayland_transaction_add_subsurface_position (transaction, surface, 0, 0); meta_wayland_transaction_add_subsurface_position (transaction, surface, 0, 0);
meta_wayland_transaction_commit (transaction); meta_wayland_transaction_commit (transaction);
if (surface->sub.transaction)
meta_wayland_transaction_drop_subsurface_state (surface->sub.transaction,
surface);
parent = surface->protocol_state.parent;
pending_state = meta_wayland_surface_get_pending_state (parent);
if (pending_state && pending_state->subsurface_placement_ops)
meta_wayland_subsurface_drop_placement_ops (pending_state, surface);
while (parent)
{
if (parent->sub.transaction)
meta_wayland_transaction_drop_subsurface_state (parent->sub.transaction,
surface);
parent = parent->protocol_state.parent;
}
surface->protocol_state.parent = NULL; surface->protocol_state.parent = NULL;
} }

View File

@ -44,6 +44,9 @@ void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
int parent_y, int parent_y,
MtkRectangle *out_geometry); MtkRectangle *out_geometry);
void meta_wayland_subsurface_drop_placement_ops (MetaWaylandSurfaceState *state,
MetaWaylandSurface *surface);
void meta_wayland_subsurface_parent_destroyed (MetaWaylandSurface *surface); void meta_wayland_subsurface_parent_destroyed (MetaWaylandSurface *surface);
void meta_wayland_subsurfaces_init (MetaWaylandCompositor *compositor); void meta_wayland_subsurfaces_init (MetaWaylandCompositor *compositor);

View File

@ -101,6 +101,25 @@ meta_wayland_transaction_apply_subsurface_position (MetaWaylandSurface
surface->sub.y = entry->y; surface->sub.y = entry->y;
} }
void
meta_wayland_transaction_drop_subsurface_state (MetaWaylandTransaction *transaction,
MetaWaylandSurface *surface)
{
MetaWaylandSurface *parent = surface->protocol_state.parent;
MetaWaylandTransactionEntry *entry;
entry = meta_wayland_transaction_get_entry (transaction, surface);
if (entry)
entry->has_sub_pos = FALSE;
if (!parent)
return;
entry = meta_wayland_transaction_get_entry (transaction, parent);
if (entry && entry->state && entry->state->subsurface_placement_ops)
meta_wayland_subsurface_drop_placement_ops (entry->state, surface);
}
static gboolean static gboolean
is_ancestor (MetaWaylandSurface *candidate, is_ancestor (MetaWaylandSurface *candidate,
MetaWaylandSurface *reference) MetaWaylandSurface *reference)

View File

@ -20,6 +20,9 @@
#include "wayland/meta-wayland-types.h" #include "wayland/meta-wayland-types.h"
#include "wayland/meta-wayland-subsurface.h" #include "wayland/meta-wayland-subsurface.h"
void meta_wayland_transaction_drop_subsurface_state (MetaWaylandTransaction *transaction,
MetaWaylandSurface *surface);
void meta_wayland_transaction_commit (MetaWaylandTransaction *transaction); void meta_wayland_transaction_commit (MetaWaylandTransaction *transaction);
MetaWaylandTransactionEntry *meta_wayland_transaction_ensure_entry (MetaWaylandTransaction *transaction, MetaWaylandTransactionEntry *meta_wayland_transaction_ensure_entry (MetaWaylandTransaction *transaction,