diff --git a/src/wayland/meta-wayland-subsurface.c b/src/wayland/meta-wayland-subsurface.c index 46451dcaa..156f392b4 100644 --- a/src/wayland/meta-wayland-subsurface.c +++ b/src/wayland/meta-wayland-subsurface.c @@ -397,11 +397,38 @@ wl_subsurface_place_below (struct wl_client *client, 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 permanently_unmap_subsurface (MetaWaylandSurface *surface) { MetaWaylandSubsurfacePlacementOp *op; MetaWaylandTransaction *transaction; + MetaWaylandSurface *parent; + MetaWaylandSurfaceState *pending_state; op = get_subsurface_placement_op (surface, NULL, 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_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; } diff --git a/src/wayland/meta-wayland-subsurface.h b/src/wayland/meta-wayland-subsurface.h index b4401b9ba..a4407b7d4 100644 --- a/src/wayland/meta-wayland-subsurface.h +++ b/src/wayland/meta-wayland-subsurface.h @@ -44,6 +44,9 @@ void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface, int parent_y, 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_subsurfaces_init (MetaWaylandCompositor *compositor); diff --git a/src/wayland/meta-wayland-transaction.c b/src/wayland/meta-wayland-transaction.c index 6e4943a21..6f1d3cac3 100644 --- a/src/wayland/meta-wayland-transaction.c +++ b/src/wayland/meta-wayland-transaction.c @@ -101,6 +101,25 @@ meta_wayland_transaction_apply_subsurface_position (MetaWaylandSurface 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 is_ancestor (MetaWaylandSurface *candidate, MetaWaylandSurface *reference) diff --git a/src/wayland/meta-wayland-transaction.h b/src/wayland/meta-wayland-transaction.h index 6674d2c2c..165fe7f66 100644 --- a/src/wayland/meta-wayland-transaction.h +++ b/src/wayland/meta-wayland-transaction.h @@ -20,6 +20,9 @@ #include "wayland/meta-wayland-types.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); MetaWaylandTransactionEntry *meta_wayland_transaction_ensure_entry (MetaWaylandTransaction *transaction,