mirror of
https://github.com/brl/mutter.git
synced 2025-08-05 08:04:50 +00:00
wayland/subsurface: Move placement ops to the parents pending state
Unlike other subsurface state, placement operations need to get applied in order. As per spec: ``` Requests are handled in order and applied immediately to a pending state. The final pending state is copied to the active state the next time the state of the parent surface is applied. ``` Having placement operations being part of the subsurface state makes it difficult to support arbitrary orderings. Make them part of the parents surface pending state instead. Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/1691 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1768>
This commit is contained in:
@@ -468,6 +468,8 @@ meta_wayland_surface_state_set_default (MetaWaylandSurfaceState *state)
|
||||
state->has_new_viewport_src_rect = FALSE;
|
||||
state->has_new_viewport_dst_size = FALSE;
|
||||
|
||||
state->subsurface_placement_ops = NULL;
|
||||
|
||||
wl_list_init (&state->presentation_feedback_list);
|
||||
}
|
||||
|
||||
@@ -499,6 +501,13 @@ meta_wayland_surface_state_clear (MetaWaylandSurfaceState *state)
|
||||
wl_list_for_each_safe (cb, next, &state->frame_callback_list, link)
|
||||
wl_resource_destroy (cb->resource);
|
||||
|
||||
if (state->subsurface_placement_ops)
|
||||
{
|
||||
g_slist_free_full (
|
||||
state->subsurface_placement_ops,
|
||||
(GDestroyNotify) meta_wayland_subsurface_placement_op_free);
|
||||
}
|
||||
|
||||
meta_wayland_surface_state_discard_presentation_feedback (state);
|
||||
}
|
||||
|
||||
@@ -609,6 +618,21 @@ meta_wayland_surface_state_merge_into (MetaWaylandSurfaceState *from,
|
||||
to);
|
||||
}
|
||||
|
||||
if (from->subsurface_placement_ops != NULL)
|
||||
{
|
||||
if (to->subsurface_placement_ops != NULL)
|
||||
{
|
||||
to->subsurface_placement_ops =
|
||||
g_slist_concat (to->subsurface_placement_ops,
|
||||
from->subsurface_placement_ops);
|
||||
from->subsurface_placement_ops = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
to->subsurface_placement_ops = from->subsurface_placement_ops;
|
||||
}
|
||||
}
|
||||
|
||||
wl_list_insert_list (&to->presentation_feedback_list,
|
||||
&from->presentation_feedback_list);
|
||||
wl_list_init (&from->presentation_feedback_list);
|
||||
@@ -827,6 +851,43 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
if (state->subsurface_placement_ops)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = state->subsurface_placement_ops; l; l = l->next)
|
||||
{
|
||||
MetaWaylandSubsurfacePlacementOp *op = l->data;
|
||||
GNode *sibling_node;
|
||||
|
||||
if (!op->surface || !op->sibling)
|
||||
continue;
|
||||
|
||||
if (op->sibling == surface)
|
||||
sibling_node = surface->subsurface_leaf_node;
|
||||
else
|
||||
sibling_node = op->sibling->subsurface_branch_node;
|
||||
|
||||
g_node_unlink (op->surface->subsurface_branch_node);
|
||||
|
||||
switch (op->placement)
|
||||
{
|
||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
|
||||
g_node_insert_after (surface->subsurface_branch_node,
|
||||
sibling_node,
|
||||
op->surface->subsurface_branch_node);
|
||||
break;
|
||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
|
||||
g_node_insert_before (surface->subsurface_branch_node,
|
||||
sibling_node,
|
||||
op->surface->subsurface_branch_node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
meta_wayland_surface_notify_subsurface_state_changed (surface);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
/* If we have a buffer that we are not using, decrease the use count so it may
|
||||
* be released if no-one else has a use-reference to it.
|
||||
|
Reference in New Issue
Block a user