mirror of
https://github.com/brl/mutter.git
synced 2025-02-11 02:44:09 +00:00
wayland/surface: Use transactions for all sub-surface hierarchy changes
And keep track of the hierarchy separately for the Wayland protocol and for output. Protocol state is updated immediately as protocol requests are processed, output state only when the corresponding transaction is applied (which may be deferred until the next commit of the parent surface). v2: * Directly add placement ops to a transaction, instead of going via pending_state. * Use transaction entry for the sub-surface instead of that for its parent surface. v3: * Use transaction entry for the parent surface again, to ensure proper ordering of placement ops, and call meta_wayland_surface_notify_subsurface_state_changed only once per parent surface. * Drop all use of wl_resource_add_destroy_listener, transactions are keeping surfaces alive as long as needed. v4: * Rebase on https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2501 * Drop ClutterActor code from meta_wayland_surface_apply_placement_ops. (Robert Mader) v5: * Rename MetaWaylandSubSurfaceState to MetaWaylandSurfaceSubState, since the next commit adds not sub-surface specific state to it. v6: * Move include of meta-wayland-subsurface.h from meta-wayland-transaction.c to .h, since the latter references MetaWaylandSubsurfacePlacementOp. v7: * Drop superfluous !entry check from meta_wayland_transaction_apply. v8: * Rename output/protocol fields to output/protocol_state. (Jonas Ådahl) v9: * Use meta_wayland_surface_state_new in meta_wayland_transaction_add_placement_op. v10: * Fix a few style issues per check-style.py. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
This commit is contained in:
parent
4eef08c5c3
commit
80c6b7d82b
@ -197,7 +197,7 @@ meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor)
|
|||||||
meta_window_actor_get_surface (actor);
|
meta_window_actor_get_surface (actor);
|
||||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (
|
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (
|
||||||
META_SURFACE_ACTOR_WAYLAND (surface_actor));
|
META_SURFACE_ACTOR_WAYLAND (surface_actor));
|
||||||
GNode *root_node = surface->subsurface_branch_node;
|
GNode *root_node = surface->output_state.subsurface_branch_node;
|
||||||
g_autoptr (GList) surface_actors = NULL;
|
g_autoptr (GList) surface_actors = NULL;
|
||||||
g_autoptr (GList) children = NULL;
|
g_autoptr (GList) children = NULL;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
@ -273,7 +273,8 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor
|
|||||||
|
|
||||||
meta_shaped_texture_ensure_size_valid (stex);
|
meta_shaped_texture_ensure_size_valid (stex);
|
||||||
|
|
||||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (&surface->output_state,
|
||||||
|
subsurface_surface)
|
||||||
{
|
{
|
||||||
MetaWaylandActorSurface *actor_surface;
|
MetaWaylandActorSurface *actor_surface;
|
||||||
|
|
||||||
@ -417,7 +418,8 @@ meta_wayland_actor_surface_reset_actor (MetaWaylandActorSurface *actor_surface)
|
|||||||
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (actor_surface));
|
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (actor_surface));
|
||||||
MetaWaylandSurface *subsurface_surface;
|
MetaWaylandSurface *subsurface_surface;
|
||||||
|
|
||||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (&surface->output_state,
|
||||||
|
subsurface_surface)
|
||||||
{
|
{
|
||||||
MetaWaylandActorSurface *actor_surface;
|
MetaWaylandActorSurface *actor_surface;
|
||||||
|
|
||||||
|
@ -1369,7 +1369,8 @@ pointer_can_grab_surface (MetaWaylandPointer *pointer,
|
|||||||
if (pointer->focus_surface == surface)
|
if (pointer->focus_surface == surface)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface)
|
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (&surface->output_state,
|
||||||
|
subsurface)
|
||||||
{
|
{
|
||||||
if (pointer_can_grab_surface (pointer, subsurface))
|
if (pointer_can_grab_surface (pointer, subsurface))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -59,7 +59,8 @@ meta_wayland_shell_surface_calculate_geometry (MetaWaylandShellSurface *shell_su
|
|||||||
.height = meta_wayland_surface_get_height (surface),
|
.height = meta_wayland_surface_get_height (surface),
|
||||||
};
|
};
|
||||||
|
|
||||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (&surface->output_state,
|
||||||
|
subsurface_surface)
|
||||||
{
|
{
|
||||||
MetaWaylandSubsurface *subsurface;
|
MetaWaylandSubsurface *subsurface;
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ transform_subsurface_position (MetaWaylandSurface *surface,
|
|||||||
*x += surface->sub.x;
|
*x += surface->sub.x;
|
||||||
*y += surface->sub.y;
|
*y += surface->sub.y;
|
||||||
|
|
||||||
surface = surface->sub.parent;
|
surface = surface->output_state.parent;
|
||||||
}
|
}
|
||||||
while (surface);
|
while (surface);
|
||||||
}
|
}
|
||||||
@ -60,8 +60,8 @@ should_show (MetaWaylandSurface *surface)
|
|||||||
{
|
{
|
||||||
if (!surface->buffer_ref->buffer)
|
if (!surface->buffer_ref->buffer)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
else if (surface->sub.parent)
|
else if (surface->output_state.parent)
|
||||||
return should_show (surface->sub.parent);
|
return should_show (surface->output_state.parent);
|
||||||
else
|
else
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -96,14 +96,15 @@ static gboolean
|
|||||||
is_child (MetaWaylandSurface *surface,
|
is_child (MetaWaylandSurface *surface,
|
||||||
MetaWaylandSurface *sibling)
|
MetaWaylandSurface *sibling)
|
||||||
{
|
{
|
||||||
return surface->sub.parent == sibling;
|
return surface->protocol_state.parent == sibling;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_sibling (MetaWaylandSurface *surface,
|
is_sibling (MetaWaylandSurface *surface,
|
||||||
MetaWaylandSurface *sibling)
|
MetaWaylandSurface *sibling)
|
||||||
{
|
{
|
||||||
return surface != sibling && surface->sub.parent == sibling->sub.parent;
|
return surface != sibling &&
|
||||||
|
surface->protocol_state.parent == sibling->protocol_state.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -128,7 +129,8 @@ meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
|||||||
if (surface->buffer_ref->buffer)
|
if (surface->buffer_ref->buffer)
|
||||||
meta_rectangle_union (out_geometry, &geometry, out_geometry);
|
meta_rectangle_union (out_geometry, &geometry, out_geometry);
|
||||||
|
|
||||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (&surface->output_state,
|
||||||
|
subsurface_surface)
|
||||||
{
|
{
|
||||||
MetaWaylandSubsurface *subsurface;
|
MetaWaylandSubsurface *subsurface;
|
||||||
|
|
||||||
@ -158,7 +160,7 @@ meta_wayland_subsurface_get_toplevel (MetaWaylandSurfaceRole *surface_role)
|
|||||||
{
|
{
|
||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
MetaWaylandSurface *parent = surface->sub.parent;
|
MetaWaylandSurface *parent = surface->output_state.parent;
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
return meta_wayland_surface_get_toplevel (parent);
|
return meta_wayland_surface_get_toplevel (parent);
|
||||||
@ -176,7 +178,7 @@ meta_wayland_subsurface_is_synchronized (MetaWaylandSurfaceRole *surface_role)
|
|||||||
if (surface->sub.synchronous)
|
if (surface->sub.synchronous)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
parent = surface->sub.parent;
|
parent = surface->protocol_state.parent;
|
||||||
if (parent)
|
if (parent)
|
||||||
return meta_wayland_surface_is_synchronized (parent);
|
return meta_wayland_surface_is_synchronized (parent);
|
||||||
|
|
||||||
@ -188,7 +190,7 @@ meta_wayland_subsurface_notify_subsurface_state_changed (MetaWaylandSurfaceRole
|
|||||||
{
|
{
|
||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
MetaWaylandSurface *parent = surface->sub.parent;
|
MetaWaylandSurface *parent = surface->output_state.parent;
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
return meta_wayland_surface_notify_subsurface_state_changed (parent);
|
return meta_wayland_surface_notify_subsurface_state_changed (parent);
|
||||||
@ -201,13 +203,14 @@ meta_wayland_subsurface_get_geometry_scale (MetaWaylandActorSurface *actor_surfa
|
|||||||
META_WAYLAND_SURFACE_ROLE (actor_surface);
|
META_WAYLAND_SURFACE_ROLE (actor_surface);
|
||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
MetaWaylandSurface *parent = surface->sub.parent;
|
MetaWaylandSurface *parent = surface->output_state.parent;
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
{
|
{
|
||||||
MetaWaylandActorSurface *parent_actor;
|
MetaWaylandActorSurface *parent_actor;
|
||||||
|
|
||||||
parent_actor = META_WAYLAND_ACTOR_SURFACE (surface->sub.parent->role);
|
parent_actor =
|
||||||
|
META_WAYLAND_ACTOR_SURFACE (surface->output_state.parent->role);
|
||||||
return meta_wayland_actor_surface_get_geometry_scale (parent_actor);
|
return meta_wayland_actor_surface_get_geometry_scale (parent_actor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -259,23 +262,6 @@ meta_wayland_subsurface_class_init (MetaWaylandSubsurfaceClass *klass)
|
|||||||
meta_wayland_subsurface_sync_actor_state;
|
meta_wayland_subsurface_sync_actor_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
wl_subsurface_destructor (struct wl_resource *resource)
|
|
||||||
{
|
|
||||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
|
||||||
|
|
||||||
g_node_unlink (surface->subsurface_branch_node);
|
|
||||||
|
|
||||||
if (surface->sub.parent)
|
|
||||||
{
|
|
||||||
meta_wayland_surface_notify_subsurface_state_changed (surface->sub.parent);
|
|
||||||
wl_list_remove (&surface->sub.parent_destroy_listener.link);
|
|
||||||
surface->sub.parent = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface->wl_subsurface = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wl_subsurface_destroy (struct wl_client *client,
|
wl_subsurface_destroy (struct wl_client *client,
|
||||||
struct wl_resource *resource)
|
struct wl_resource *resource)
|
||||||
@ -307,61 +293,57 @@ is_valid_sibling (MetaWaylandSurface *surface,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
subsurface_handle_pending_subsurface_destroyed (struct wl_listener *listener,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
MetaWaylandSubsurfacePlacementOp *op =
|
|
||||||
wl_container_of (listener, op, subsurface_destroy_listener);
|
|
||||||
|
|
||||||
op->surface = NULL;
|
|
||||||
wl_list_remove (&op->subsurface_destroy_listener.link);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
subsurface_handle_pending_sibling_destroyed (struct wl_listener *listener,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
MetaWaylandSubsurfacePlacementOp *op =
|
|
||||||
wl_container_of (listener, op, sibling_destroy_listener);
|
|
||||||
|
|
||||||
op->sibling = NULL;
|
|
||||||
wl_list_remove (&op->sibling_destroy_listener.link);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_wayland_subsurface_placement_op_free (MetaWaylandSubsurfacePlacementOp *op)
|
|
||||||
{
|
|
||||||
if (op->surface)
|
|
||||||
wl_list_remove (&op->subsurface_destroy_listener.link);
|
|
||||||
if (op->sibling)
|
|
||||||
wl_list_remove (&op->sibling_destroy_listener.link);
|
|
||||||
g_free (op);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
queue_subsurface_placement (MetaWaylandSurface *surface,
|
queue_subsurface_placement (MetaWaylandSurface *surface,
|
||||||
MetaWaylandSurface *sibling,
|
MetaWaylandSurface *sibling,
|
||||||
MetaWaylandSubsurfacePlacement placement)
|
MetaWaylandSubsurfacePlacement placement)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *parent = surface->sub.parent;
|
MetaWaylandSurface *parent = surface->protocol_state.parent;
|
||||||
|
gboolean have_synced_parent;
|
||||||
|
MetaWaylandTransaction *transaction;
|
||||||
MetaWaylandSubsurfacePlacementOp *op =
|
MetaWaylandSubsurfacePlacementOp *op =
|
||||||
g_new0 (MetaWaylandSubsurfacePlacementOp, 1);
|
g_new0 (MetaWaylandSubsurfacePlacementOp, 1);
|
||||||
|
GNode *sibling_node;
|
||||||
|
|
||||||
|
have_synced_parent = sibling && meta_wayland_surface_is_synchronized (parent);
|
||||||
|
if (have_synced_parent)
|
||||||
|
transaction = meta_wayland_surface_ensure_transaction (parent);
|
||||||
|
else
|
||||||
|
transaction = meta_wayland_transaction_new (surface->compositor);
|
||||||
|
|
||||||
op->placement = placement;
|
op->placement = placement;
|
||||||
op->surface = surface;
|
|
||||||
op->sibling = sibling;
|
op->sibling = sibling;
|
||||||
op->subsurface_destroy_listener.notify =
|
op->surface = surface;
|
||||||
subsurface_handle_pending_subsurface_destroyed;
|
|
||||||
op->sibling_destroy_listener.notify =
|
|
||||||
subsurface_handle_pending_sibling_destroyed;
|
|
||||||
wl_resource_add_destroy_listener (surface->wl_subsurface,
|
|
||||||
&op->subsurface_destroy_listener);
|
|
||||||
wl_resource_add_destroy_listener (sibling->resource,
|
|
||||||
&op->sibling_destroy_listener);
|
|
||||||
|
|
||||||
parent->pending_state->subsurface_placement_ops =
|
g_node_unlink (surface->protocol_state.subsurface_branch_node);
|
||||||
g_slist_append (parent->pending_state->subsurface_placement_ops, op);
|
|
||||||
|
if (!sibling)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (sibling == parent)
|
||||||
|
sibling_node = parent->protocol_state.subsurface_leaf_node;
|
||||||
|
else
|
||||||
|
sibling_node = sibling->protocol_state.subsurface_branch_node;
|
||||||
|
|
||||||
|
switch (placement)
|
||||||
|
{
|
||||||
|
case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
|
||||||
|
g_node_insert_after (parent->protocol_state.subsurface_branch_node,
|
||||||
|
sibling_node,
|
||||||
|
surface->protocol_state.subsurface_branch_node);
|
||||||
|
break;
|
||||||
|
case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
|
||||||
|
g_node_insert_before (parent->protocol_state.subsurface_branch_node,
|
||||||
|
sibling_node,
|
||||||
|
surface->protocol_state.subsurface_branch_node);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
meta_wayland_transaction_add_placement_op (transaction, parent, op);
|
||||||
|
|
||||||
|
if (!have_synced_parent)
|
||||||
|
meta_wayland_transaction_commit (transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -408,6 +390,25 @@ wl_subsurface_place_below (struct wl_client *client,
|
|||||||
META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW);
|
META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wl_subsurface_destructor (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (surface->protocol_state.parent)
|
||||||
|
{
|
||||||
|
queue_subsurface_placement (surface, NULL,
|
||||||
|
META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW);
|
||||||
|
surface->protocol_state.parent = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_node_unlink (surface->protocol_state.subsurface_branch_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
surface->wl_subsurface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wl_subsurface_set_sync (struct wl_client *client,
|
wl_subsurface_set_sync (struct wl_client *client,
|
||||||
struct wl_resource *resource)
|
struct wl_resource *resource)
|
||||||
@ -428,7 +429,8 @@ meta_wayland_subsurface_parent_desynced (MetaWaylandSurface *surface)
|
|||||||
if (surface->sub.transaction)
|
if (surface->sub.transaction)
|
||||||
meta_wayland_transaction_commit (g_steal_pointer (&surface->sub.transaction));
|
meta_wayland_transaction_commit (g_steal_pointer (&surface->sub.transaction));
|
||||||
|
|
||||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (&surface->protocol_state,
|
||||||
|
subsurface_surface)
|
||||||
meta_wayland_subsurface_parent_desynced (subsurface_surface);
|
meta_wayland_subsurface_parent_desynced (subsurface_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,17 +465,12 @@ wl_subcompositor_destroy (struct wl_client *client,
|
|||||||
wl_resource_destroy (resource);
|
wl_resource_destroy (resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
surface_handle_parent_surface_destroyed (struct wl_listener *listener,
|
meta_wayland_subsurface_parent_destroyed (MetaWaylandSurface *surface)
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = wl_container_of (listener,
|
queue_subsurface_placement (surface, NULL,
|
||||||
surface,
|
META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW);
|
||||||
sub.parent_destroy_listener);
|
surface->protocol_state.parent = NULL;
|
||||||
|
|
||||||
g_node_unlink (surface->subsurface_branch_node);
|
|
||||||
surface->sub.parent = NULL;
|
|
||||||
wl_list_remove (&surface->sub.parent_destroy_listener.link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -482,8 +479,8 @@ is_same_or_ancestor (MetaWaylandSurface *surface,
|
|||||||
{
|
{
|
||||||
if (surface == other_surface)
|
if (surface == other_surface)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (other_surface->sub.parent)
|
if (other_surface->protocol_state.parent)
|
||||||
return is_same_or_ancestor (surface, other_surface->sub.parent);
|
return is_same_or_ancestor (surface, other_surface->protocol_state.parent);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,6 +493,7 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
|||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||||
MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource);
|
MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource);
|
||||||
|
MetaWaylandSurface *reference;
|
||||||
MetaWindow *toplevel_window;
|
MetaWindow *toplevel_window;
|
||||||
|
|
||||||
if (surface->wl_subsurface)
|
if (surface->wl_subsurface)
|
||||||
@ -542,16 +540,12 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
|||||||
wl_subsurface_destructor);
|
wl_subsurface_destructor);
|
||||||
|
|
||||||
surface->sub.synchronous = TRUE;
|
surface->sub.synchronous = TRUE;
|
||||||
surface->sub.parent = parent;
|
surface->protocol_state.parent = parent;
|
||||||
surface->sub.parent_destroy_listener.notify =
|
|
||||||
surface_handle_parent_surface_destroyed;
|
|
||||||
wl_resource_add_destroy_listener (parent->resource,
|
|
||||||
&surface->sub.parent_destroy_listener);
|
|
||||||
|
|
||||||
g_node_append (parent->subsurface_branch_node,
|
reference =
|
||||||
surface->subsurface_branch_node);
|
g_node_last_child (parent->protocol_state.subsurface_branch_node)->data;
|
||||||
|
queue_subsurface_placement (surface, reference,
|
||||||
meta_wayland_surface_notify_subsurface_state_changed (parent);
|
META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_subcompositor_interface meta_wayland_subcompositor_interface = {
|
static const struct wl_subcompositor_interface meta_wayland_subcompositor_interface = {
|
||||||
|
@ -40,8 +40,6 @@ typedef struct
|
|||||||
MetaWaylandSubsurfacePlacement placement;
|
MetaWaylandSubsurfacePlacement placement;
|
||||||
MetaWaylandSurface *surface;
|
MetaWaylandSurface *surface;
|
||||||
MetaWaylandSurface *sibling;
|
MetaWaylandSurface *sibling;
|
||||||
struct wl_listener subsurface_destroy_listener;
|
|
||||||
struct wl_listener sibling_destroy_listener;
|
|
||||||
} MetaWaylandSubsurfacePlacementOp;
|
} MetaWaylandSubsurfacePlacementOp;
|
||||||
|
|
||||||
void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
||||||
@ -49,7 +47,7 @@ void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
|||||||
int parent_y,
|
int parent_y,
|
||||||
MetaRectangle *out_geometry);
|
MetaRectangle *out_geometry);
|
||||||
|
|
||||||
void meta_wayland_subsurface_placement_op_free (MetaWaylandSubsurfacePlacementOp *op);
|
void meta_wayland_subsurface_parent_destroyed (MetaWaylandSurface *surface);
|
||||||
|
|
||||||
void meta_wayland_subsurfaces_init (MetaWaylandCompositor *compositor);
|
void meta_wayland_subsurfaces_init (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
|
@ -526,11 +526,7 @@ meta_wayland_surface_state_clear (MetaWaylandSurfaceState *state)
|
|||||||
wl_resource_destroy (cb->resource);
|
wl_resource_destroy (cb->resource);
|
||||||
|
|
||||||
if (state->subsurface_placement_ops)
|
if (state->subsurface_placement_ops)
|
||||||
{
|
g_slist_free_full (state->subsurface_placement_ops, g_free);
|
||||||
g_slist_free_full (
|
|
||||||
state->subsurface_placement_ops,
|
|
||||||
(GDestroyNotify) meta_wayland_subsurface_placement_op_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_wayland_surface_state_discard_presentation_feedback (state);
|
meta_wayland_surface_state_discard_presentation_feedback (state);
|
||||||
}
|
}
|
||||||
@ -714,6 +710,49 @@ meta_wayland_surface_discard_presentation_feedback (MetaWaylandSurface *surface)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_surface_apply_placement_ops (MetaWaylandSurface *parent,
|
||||||
|
MetaWaylandSurfaceState *state)
|
||||||
|
{
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
for (l = state->subsurface_placement_ops; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaWaylandSubsurfacePlacementOp *op = l->data;
|
||||||
|
MetaWaylandSurface *surface = op->surface;
|
||||||
|
GNode *sibling_node;
|
||||||
|
|
||||||
|
g_node_unlink (surface->output_state.subsurface_branch_node);
|
||||||
|
|
||||||
|
if (!op->sibling)
|
||||||
|
{
|
||||||
|
surface->output_state.parent = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface->output_state.parent = parent;
|
||||||
|
|
||||||
|
if (op->sibling == parent)
|
||||||
|
sibling_node = parent->output_state.subsurface_leaf_node;
|
||||||
|
else
|
||||||
|
sibling_node = op->sibling->output_state.subsurface_branch_node;
|
||||||
|
|
||||||
|
switch (op->placement)
|
||||||
|
{
|
||||||
|
case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
|
||||||
|
g_node_insert_after (parent->output_state.subsurface_branch_node,
|
||||||
|
sibling_node,
|
||||||
|
surface->output_state.subsurface_branch_node);
|
||||||
|
break;
|
||||||
|
case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
|
||||||
|
g_node_insert_before (parent->output_state.subsurface_branch_node,
|
||||||
|
sibling_node,
|
||||||
|
surface->output_state.subsurface_branch_node);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
||||||
MetaWaylandSurfaceState *state)
|
MetaWaylandSurfaceState *state)
|
||||||
@ -908,41 +947,7 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state->subsurface_placement_ops)
|
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);
|
meta_wayland_surface_notify_subsurface_state_changed (surface);
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
/* If we have a buffer that we are not using, decrease the use count so it may
|
/* If we have a buffer that we are not using, decrease the use count so it may
|
||||||
@ -1012,7 +1017,8 @@ meta_wayland_surface_commit (MetaWaylandSurface *surface)
|
|||||||
|
|
||||||
meta_wayland_transaction_merge_pending_state (transaction, surface);
|
meta_wayland_transaction_merge_pending_state (transaction, surface);
|
||||||
|
|
||||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (&surface->protocol_state,
|
||||||
|
subsurface_surface)
|
||||||
{
|
{
|
||||||
if (!subsurface_surface->sub.transaction)
|
if (!subsurface_surface->sub.transaction)
|
||||||
continue;
|
continue;
|
||||||
@ -1501,7 +1507,7 @@ meta_wayland_surface_finalize (GObject *object)
|
|||||||
|
|
||||||
meta_wayland_surface_discard_presentation_feedback (surface);
|
meta_wayland_surface_discard_presentation_feedback (surface);
|
||||||
|
|
||||||
g_clear_pointer (&surface->subsurface_branch_node, g_node_destroy);
|
g_clear_pointer (&surface->output_state.subsurface_branch_node, g_node_destroy);
|
||||||
|
|
||||||
g_hash_table_destroy (surface->shortcut_inhibited_seats);
|
g_hash_table_destroy (surface->shortcut_inhibited_seats);
|
||||||
|
|
||||||
@ -1512,6 +1518,7 @@ static void
|
|||||||
wl_surface_destructor (struct wl_resource *resource)
|
wl_surface_destructor (struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||||
|
MetaWaylandSurface *subsurface_surface;
|
||||||
|
|
||||||
g_signal_emit (surface, surface_signals[SURFACE_DESTROY], 0);
|
g_signal_emit (surface, surface_signals[SURFACE_DESTROY], 0);
|
||||||
|
|
||||||
@ -1521,7 +1528,12 @@ wl_surface_destructor (struct wl_resource *resource)
|
|||||||
if (surface->resource)
|
if (surface->resource)
|
||||||
wl_resource_set_user_data (g_steal_pointer (&surface->resource), NULL);
|
wl_resource_set_user_data (g_steal_pointer (&surface->resource), NULL);
|
||||||
|
|
||||||
|
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (&surface->protocol_state,
|
||||||
|
subsurface_surface)
|
||||||
|
meta_wayland_subsurface_parent_destroyed (subsurface_surface);
|
||||||
|
|
||||||
g_clear_pointer (&surface->wl_subsurface, wl_resource_destroy);
|
g_clear_pointer (&surface->wl_subsurface, wl_resource_destroy);
|
||||||
|
g_clear_pointer (&surface->protocol_state.subsurface_branch_node, g_node_destroy);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Any transactions referencing this surface will keep it alive until they get
|
* Any transactions referencing this surface will keep it alive until they get
|
||||||
@ -1758,9 +1770,13 @@ meta_wayland_surface_init (MetaWaylandSurface *surface)
|
|||||||
|
|
||||||
surface->buffer_ref = meta_wayland_buffer_ref_new ();
|
surface->buffer_ref = meta_wayland_buffer_ref_new ();
|
||||||
|
|
||||||
surface->subsurface_branch_node = g_node_new (surface);
|
surface->output_state.subsurface_branch_node = g_node_new (surface);
|
||||||
surface->subsurface_leaf_node =
|
surface->output_state.subsurface_leaf_node =
|
||||||
g_node_prepend_data (surface->subsurface_branch_node, surface);
|
g_node_prepend_data (surface->output_state.subsurface_branch_node, surface);
|
||||||
|
|
||||||
|
surface->protocol_state.subsurface_branch_node = g_node_new (surface);
|
||||||
|
surface->protocol_state.subsurface_leaf_node =
|
||||||
|
g_node_prepend_data (surface->protocol_state.subsurface_branch_node, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -166,8 +166,6 @@ struct _MetaWaylandSurface
|
|||||||
cairo_region_t *opaque_region;
|
cairo_region_t *opaque_region;
|
||||||
int scale;
|
int scale;
|
||||||
int32_t offset_x, offset_y;
|
int32_t offset_x, offset_y;
|
||||||
GNode *subsurface_branch_node;
|
|
||||||
GNode *subsurface_leaf_node;
|
|
||||||
GHashTable *outputs;
|
GHashTable *outputs;
|
||||||
MetaMonitorTransform buffer_transform;
|
MetaMonitorTransform buffer_transform;
|
||||||
|
|
||||||
@ -192,14 +190,17 @@ struct _MetaWaylandSurface
|
|||||||
/* All the pending state that wl_surface.commit will apply. */
|
/* All the pending state that wl_surface.commit will apply. */
|
||||||
MetaWaylandSurfaceState *pending_state;
|
MetaWaylandSurfaceState *pending_state;
|
||||||
|
|
||||||
|
struct MetaWaylandSurfaceSubState {
|
||||||
|
MetaWaylandSurface *parent;
|
||||||
|
GNode *subsurface_branch_node;
|
||||||
|
GNode *subsurface_leaf_node;
|
||||||
|
} output_state, protocol_state;
|
||||||
|
|
||||||
/* Extension resources. */
|
/* Extension resources. */
|
||||||
struct wl_resource *wl_subsurface;
|
struct wl_resource *wl_subsurface;
|
||||||
|
|
||||||
/* wl_subsurface stuff. */
|
/* wl_subsurface stuff. */
|
||||||
struct {
|
struct {
|
||||||
MetaWaylandSurface *parent;
|
|
||||||
struct wl_listener parent_destroy_listener;
|
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
@ -274,6 +275,9 @@ void meta_wayland_surface_state_reset (MetaWaylandSurfaceState *s
|
|||||||
void meta_wayland_surface_state_merge_into (MetaWaylandSurfaceState *from,
|
void meta_wayland_surface_state_merge_into (MetaWaylandSurfaceState *from,
|
||||||
MetaWaylandSurfaceState *to);
|
MetaWaylandSurfaceState *to);
|
||||||
|
|
||||||
|
void meta_wayland_surface_apply_placement_ops (MetaWaylandSurface *surface,
|
||||||
|
MetaWaylandSurfaceState *state);
|
||||||
|
|
||||||
void meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
void meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
||||||
MetaWaylandSurfaceState *state);
|
MetaWaylandSurfaceState *state);
|
||||||
|
|
||||||
@ -415,11 +419,11 @@ meta_get_next_subsurface_sibling (GNode *n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline GNode *
|
static inline GNode *
|
||||||
meta_get_first_subsurface_node (MetaWaylandSurface *surface)
|
meta_get_first_subsurface_node (struct MetaWaylandSurfaceSubState *sub)
|
||||||
{
|
{
|
||||||
GNode *n;
|
GNode *n;
|
||||||
|
|
||||||
n = g_node_first_child (surface->subsurface_branch_node);
|
n = g_node_first_child (sub->subsurface_branch_node);
|
||||||
if (!n)
|
if (!n)
|
||||||
return NULL;
|
return NULL;
|
||||||
else if (!G_NODE_IS_LEAF (n))
|
else if (!G_NODE_IS_LEAF (n))
|
||||||
@ -428,9 +432,11 @@ meta_get_first_subsurface_node (MetaWaylandSurface *surface)
|
|||||||
return meta_get_next_subsurface_sibling (n);
|
return meta_get_next_subsurface_sibling (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define META_WAYLAND_SURFACE_FOREACH_SUBSURFACE(surface, subsurface) \
|
#define META_WAYLAND_SURFACE_FOREACH_SUBSURFACE(state, subsurface) \
|
||||||
for (GNode *G_PASTE(__n, __LINE__) = meta_get_first_subsurface_node ((surface)); \
|
for (GNode *G_PASTE(__n, __LINE__) = meta_get_first_subsurface_node (state), \
|
||||||
|
*G_PASTE(__next, __LINE__) = meta_get_next_subsurface_sibling (G_PASTE (__n, __LINE__)); \
|
||||||
(subsurface = (G_PASTE (__n, __LINE__) ? G_PASTE (__n, __LINE__)->data : NULL)); \
|
(subsurface = (G_PASTE (__n, __LINE__) ? G_PASTE (__n, __LINE__)->data : NULL)); \
|
||||||
G_PASTE (__n, __LINE__) = meta_get_next_subsurface_sibling (G_PASTE (__n, __LINE__)))
|
G_PASTE (__n, __LINE__) = G_PASTE (__next, __LINE__), \
|
||||||
|
G_PASTE (__next, __LINE__) = meta_get_next_subsurface_sibling (G_PASTE (__n, __LINE__)))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -899,7 +899,8 @@ tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
|
|||||||
if (tool->focus_surface == surface)
|
if (tool->focus_surface == surface)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface)
|
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (&surface->output_state,
|
||||||
|
subsurface)
|
||||||
{
|
{
|
||||||
if (tablet_tool_can_grab_surface (tool, subsurface))
|
if (tablet_tool_can_grab_surface (tool, subsurface))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "wayland/meta-wayland-transaction.h"
|
#include "wayland/meta-wayland-transaction.h"
|
||||||
|
|
||||||
#include "wayland/meta-wayland.h"
|
#include "wayland/meta-wayland.h"
|
||||||
#include "wayland/meta-wayland-subsurface.h"
|
|
||||||
|
|
||||||
#define META_WAYLAND_TRANSACTION_NONE ((void *)(uintptr_t) G_MAXSIZE)
|
#define META_WAYLAND_TRANSACTION_NONE ((void *)(uintptr_t) G_MAXSIZE)
|
||||||
|
|
||||||
@ -67,7 +66,7 @@ meta_wayland_transaction_sync_child_states (MetaWaylandSurface *surface)
|
|||||||
{
|
{
|
||||||
MetaWaylandSurface *subsurface_surface;
|
MetaWaylandSurface *subsurface_surface;
|
||||||
|
|
||||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (&surface->output_state, subsurface_surface)
|
||||||
{
|
{
|
||||||
MetaWaylandSubsurface *subsurface;
|
MetaWaylandSubsurface *subsurface;
|
||||||
MetaWaylandActorSurface *actor_surface;
|
MetaWaylandActorSurface *actor_surface;
|
||||||
@ -95,7 +94,9 @@ is_ancestor (MetaWaylandSurface *candidate,
|
|||||||
{
|
{
|
||||||
MetaWaylandSurface *ancestor;
|
MetaWaylandSurface *ancestor;
|
||||||
|
|
||||||
for (ancestor = reference->sub.parent; ancestor; ancestor = ancestor->sub.parent)
|
for (ancestor = reference->output_state.parent;
|
||||||
|
ancestor;
|
||||||
|
ancestor = ancestor->output_state.parent)
|
||||||
{
|
{
|
||||||
if (ancestor == candidate)
|
if (ancestor == candidate)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -112,7 +113,7 @@ meta_wayland_transaction_compare (const void *key1,
|
|||||||
MetaWaylandSurface *surface2 = *(MetaWaylandSurface **) key2;
|
MetaWaylandSurface *surface2 = *(MetaWaylandSurface **) key2;
|
||||||
|
|
||||||
/* Order of siblings doesn't matter */
|
/* Order of siblings doesn't matter */
|
||||||
if (surface1->sub.parent == surface2->sub.parent)
|
if (surface1->output_state.parent == surface2->output_state.parent)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Ancestor surfaces come before descendant surfaces */
|
/* Ancestor surfaces come before descendant surfaces */
|
||||||
@ -156,12 +157,25 @@ meta_wayland_transaction_apply (MetaWaylandTransaction *transaction,
|
|||||||
g_autofree MetaWaylandSurface **surfaces = NULL;
|
g_autofree MetaWaylandSurface **surfaces = NULL;
|
||||||
g_autofree MetaWaylandSurfaceState **states = NULL;
|
g_autofree MetaWaylandSurfaceState **states = NULL;
|
||||||
unsigned int num_surfaces;
|
unsigned int num_surfaces;
|
||||||
|
MetaWaylandSurface *surface;
|
||||||
|
MetaWaylandTransactionEntry *entry;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
surfaces = (MetaWaylandSurface **)
|
surfaces = (MetaWaylandSurface **)
|
||||||
g_hash_table_get_keys_as_array (transaction->entries, &num_surfaces);
|
g_hash_table_get_keys_as_array (transaction->entries, &num_surfaces);
|
||||||
states = g_new (MetaWaylandSurfaceState *, num_surfaces);
|
states = g_new (MetaWaylandSurfaceState *, num_surfaces);
|
||||||
|
|
||||||
|
/* Apply sub-surface states to ensure output surface hierarchy is up to date */
|
||||||
|
for (i = 0; i < num_surfaces; i++)
|
||||||
|
{
|
||||||
|
surface = surfaces[i];
|
||||||
|
entry = meta_wayland_transaction_get_entry (transaction, surface);
|
||||||
|
meta_wayland_transaction_apply_subsurface_position (surface, entry);
|
||||||
|
|
||||||
|
if (entry->state && entry->state->subsurface_placement_ops)
|
||||||
|
meta_wayland_surface_apply_placement_ops (surface, entry->state);
|
||||||
|
}
|
||||||
|
|
||||||
/* Sort surfaces from ancestors to descendants */
|
/* Sort surfaces from ancestors to descendants */
|
||||||
qsort (surfaces, num_surfaces, sizeof (MetaWaylandSurface *),
|
qsort (surfaces, num_surfaces, sizeof (MetaWaylandSurface *),
|
||||||
meta_wayland_transaction_compare);
|
meta_wayland_transaction_compare);
|
||||||
@ -169,12 +183,10 @@ meta_wayland_transaction_apply (MetaWaylandTransaction *transaction,
|
|||||||
/* Apply states from ancestors to descendants */
|
/* Apply states from ancestors to descendants */
|
||||||
for (i = 0; i < num_surfaces; i++)
|
for (i = 0; i < num_surfaces; i++)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = surfaces[i];
|
surface = surfaces[i];
|
||||||
MetaWaylandTransactionEntry *entry;
|
|
||||||
|
|
||||||
entry = meta_wayland_transaction_get_entry (transaction, surface);
|
entry = meta_wayland_transaction_get_entry (transaction, surface);
|
||||||
|
|
||||||
states[i] = entry->state;
|
states[i] = entry->state;
|
||||||
meta_wayland_transaction_apply_subsurface_position (surface, entry);
|
|
||||||
if (entry->state)
|
if (entry->state)
|
||||||
meta_wayland_surface_apply_state (surface, entry->state);
|
meta_wayland_surface_apply_state (surface, entry->state);
|
||||||
|
|
||||||
@ -314,7 +326,6 @@ meta_wayland_transaction_entry_free (MetaWaylandTransactionEntry *entry)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
meta_wayland_transaction_add_placement_surfaces (MetaWaylandTransaction *transaction,
|
meta_wayland_transaction_add_placement_surfaces (MetaWaylandTransaction *transaction,
|
||||||
MetaWaylandSurface *surface,
|
|
||||||
MetaWaylandSurfaceState *state)
|
MetaWaylandSurfaceState *state)
|
||||||
{
|
{
|
||||||
GSList *l;
|
GSList *l;
|
||||||
@ -323,7 +334,6 @@ meta_wayland_transaction_add_placement_surfaces (MetaWaylandTransaction *transa
|
|||||||
{
|
{
|
||||||
MetaWaylandSubsurfacePlacementOp *op = l->data;
|
MetaWaylandSubsurfacePlacementOp *op = l->data;
|
||||||
|
|
||||||
if (op->surface)
|
|
||||||
meta_wayland_transaction_ensure_entry (transaction, op->surface);
|
meta_wayland_transaction_ensure_entry (transaction, op->surface);
|
||||||
|
|
||||||
if (op->sibling)
|
if (op->sibling)
|
||||||
@ -339,10 +349,27 @@ meta_wayland_transaction_add_entry (MetaWaylandTransaction *transaction,
|
|||||||
g_hash_table_insert (transaction->entries, g_object_ref (surface), entry);
|
g_hash_table_insert (transaction->entries, g_object_ref (surface), entry);
|
||||||
|
|
||||||
if (entry->state)
|
if (entry->state)
|
||||||
{
|
meta_wayland_transaction_add_placement_surfaces (transaction, entry->state);
|
||||||
meta_wayland_transaction_add_placement_surfaces (transaction, surface,
|
|
||||||
entry->state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_transaction_add_placement_op (MetaWaylandTransaction *transaction,
|
||||||
|
MetaWaylandSurface *surface,
|
||||||
|
MetaWaylandSubsurfacePlacementOp *op)
|
||||||
|
{
|
||||||
|
MetaWaylandTransactionEntry *entry;
|
||||||
|
MetaWaylandSurfaceState *state;
|
||||||
|
|
||||||
|
entry = meta_wayland_transaction_ensure_entry (transaction, surface);
|
||||||
|
|
||||||
|
if (!entry->state)
|
||||||
|
entry->state = meta_wayland_surface_state_new ();
|
||||||
|
|
||||||
|
state = entry->state;
|
||||||
|
state->subsurface_placement_ops =
|
||||||
|
g_slist_append (state->subsurface_placement_ops, op);
|
||||||
|
|
||||||
|
meta_wayland_transaction_add_placement_surfaces (transaction, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -402,10 +429,7 @@ meta_wayland_transaction_merge_into (MetaWaylandTransaction *from,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (from_entry->state)
|
if (from_entry->state)
|
||||||
{
|
meta_wayland_transaction_add_placement_surfaces (to, from_entry->state);
|
||||||
meta_wayland_transaction_add_placement_surfaces (to, surface,
|
|
||||||
from_entry->state);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_wayland_transaction_entry_merge_into (from_entry, to_entry);
|
meta_wayland_transaction_entry_merge_into (from_entry, to_entry);
|
||||||
g_hash_table_iter_remove (&iter);
|
g_hash_table_iter_remove (&iter);
|
||||||
|
@ -21,9 +21,14 @@
|
|||||||
#define META_WAYLAND_TRANSACTION_H
|
#define META_WAYLAND_TRANSACTION_H
|
||||||
|
|
||||||
#include "wayland/meta-wayland-types.h"
|
#include "wayland/meta-wayland-types.h"
|
||||||
|
#include "wayland/meta-wayland-subsurface.h"
|
||||||
|
|
||||||
void meta_wayland_transaction_commit (MetaWaylandTransaction *transaction);
|
void meta_wayland_transaction_commit (MetaWaylandTransaction *transaction);
|
||||||
|
|
||||||
|
void meta_wayland_transaction_add_placement_op (MetaWaylandTransaction *transaction,
|
||||||
|
MetaWaylandSurface *surface,
|
||||||
|
MetaWaylandSubsurfacePlacementOp *op);
|
||||||
|
|
||||||
void meta_wayland_transaction_add_subsurface_position (MetaWaylandTransaction *transaction,
|
void meta_wayland_transaction_add_subsurface_position (MetaWaylandTransaction *transaction,
|
||||||
MetaWaylandSurface *surface,
|
MetaWaylandSurface *surface,
|
||||||
int x,
|
int x,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user