mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 09:30:45 -05:00
wayland/subsurface: Avoid placement ops for detached subsurfaces
If a subsurface first gets reordered and afterwards detached from the parent before the parent surface got commited, we currently would end up reattaching the subsurface to its previous parent. While clients should avoid this behaviour, it's legit according to the spec. We already prevent similar cases where the subsurface is destroyed - extend that check to detaching, which includes the destroy case. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1831>
This commit is contained in:
parent
f7768874e5
commit
6e00e5e6e7
@ -355,11 +355,11 @@ is_valid_sibling (MetaWaylandSurface *surface,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
subsurface_handle_pending_surface_destroyed (struct wl_listener *listener,
|
subsurface_handle_pending_subsurface_destroyed (struct wl_listener *listener,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
MetaWaylandSubsurfacePlacementOp *op =
|
MetaWaylandSubsurfacePlacementOp *op =
|
||||||
wl_container_of (listener, op, surface_destroy_listener);
|
wl_container_of (listener, op, subsurface_destroy_listener);
|
||||||
|
|
||||||
op->surface = NULL;
|
op->surface = NULL;
|
||||||
}
|
}
|
||||||
@ -378,7 +378,7 @@ void
|
|||||||
meta_wayland_subsurface_placement_op_free (MetaWaylandSubsurfacePlacementOp *op)
|
meta_wayland_subsurface_placement_op_free (MetaWaylandSubsurfacePlacementOp *op)
|
||||||
{
|
{
|
||||||
if (op->surface)
|
if (op->surface)
|
||||||
wl_list_remove (&op->surface_destroy_listener.link);
|
wl_list_remove (&op->subsurface_destroy_listener.link);
|
||||||
if (op->sibling)
|
if (op->sibling)
|
||||||
wl_list_remove (&op->sibling_destroy_listener.link);
|
wl_list_remove (&op->sibling_destroy_listener.link);
|
||||||
g_free (op);
|
g_free (op);
|
||||||
@ -396,12 +396,12 @@ queue_subsurface_placement (MetaWaylandSurface *surface,
|
|||||||
op->placement = placement;
|
op->placement = placement;
|
||||||
op->surface = surface;
|
op->surface = surface;
|
||||||
op->sibling = sibling;
|
op->sibling = sibling;
|
||||||
op->surface_destroy_listener.notify =
|
op->subsurface_destroy_listener.notify =
|
||||||
subsurface_handle_pending_surface_destroyed;
|
subsurface_handle_pending_subsurface_destroyed;
|
||||||
op->sibling_destroy_listener.notify =
|
op->sibling_destroy_listener.notify =
|
||||||
subsurface_handle_pending_sibling_destroyed;
|
subsurface_handle_pending_sibling_destroyed;
|
||||||
wl_resource_add_destroy_listener (surface->resource,
|
wl_resource_add_destroy_listener (surface->wl_subsurface,
|
||||||
&op->surface_destroy_listener);
|
&op->subsurface_destroy_listener);
|
||||||
wl_resource_add_destroy_listener (sibling->resource,
|
wl_resource_add_destroy_listener (sibling->resource,
|
||||||
&op->sibling_destroy_listener);
|
&op->sibling_destroy_listener);
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ typedef struct
|
|||||||
MetaWaylandSubsurfacePlacement placement;
|
MetaWaylandSubsurfacePlacement placement;
|
||||||
MetaWaylandSurface *surface;
|
MetaWaylandSurface *surface;
|
||||||
MetaWaylandSurface *sibling;
|
MetaWaylandSurface *sibling;
|
||||||
struct wl_listener surface_destroy_listener;
|
struct wl_listener subsurface_destroy_listener;
|
||||||
struct wl_listener sibling_destroy_listener;
|
struct wl_listener sibling_destroy_listener;
|
||||||
} MetaWaylandSubsurfacePlacementOp;
|
} MetaWaylandSubsurfacePlacementOp;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user