mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 17:40:40 -05:00
wayland: Implement subsurface.place_below() for parents
Flatten the subsurface actor tree, making all surface actors children of the window actor. Save the subsurface state in a GNode tree in MetaWaylandSurface, where each surface holds two nodes, one branch, which can be the tree root or be attached to a parent surfaces branch, and a leaf, which is used to save the position relative to child branch nodes. Each time a surface is added or reordered in the tree, unparent all surface actors from the window actor, traverse all leaves of the tree and readd the corresponding surface actors back to the window actor. https://gitlab.gnome.org/GNOME/mutter/merge_requests/664
This commit is contained in:
parent
a51437ee2b
commit
77229f99b8
@ -20,9 +20,10 @@
|
||||
* Georges Basile Stavracas Neto <gbsneto@gnome.org>
|
||||
*/
|
||||
|
||||
#include "compositor/meta-surface-actor.h"
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
#include "compositor/meta-window-actor-wayland.h"
|
||||
#include "meta/meta-window-actor.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
|
||||
struct _MetaWindowActorWayland
|
||||
{
|
||||
@ -31,6 +32,88 @@ struct _MetaWindowActorWayland
|
||||
|
||||
G_DEFINE_TYPE (MetaWindowActorWayland, meta_window_actor_wayland, META_TYPE_WINDOW_ACTOR)
|
||||
|
||||
static gboolean
|
||||
remove_surface_actor_from_children (GNode *node,
|
||||
gpointer data)
|
||||
{
|
||||
MetaWaylandSurface *surface = node->data;
|
||||
MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface);
|
||||
MetaWindowActor *window_actor = data;
|
||||
ClutterActor *parent;
|
||||
|
||||
parent = clutter_actor_get_parent (CLUTTER_ACTOR (surface_actor));
|
||||
if (!parent)
|
||||
return FALSE;
|
||||
|
||||
g_return_val_if_fail (parent == CLUTTER_ACTOR (window_actor), FALSE);
|
||||
|
||||
clutter_actor_remove_child (CLUTTER_ACTOR (window_actor),
|
||||
CLUTTER_ACTOR (surface_actor));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_surface_actor_to_children (GNode *node,
|
||||
gpointer data)
|
||||
{
|
||||
MetaWaylandSurface *surface = node->data;
|
||||
MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface);
|
||||
MetaWindowActor *window_actor = data;
|
||||
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (window_actor),
|
||||
CLUTTER_ACTOR (surface_actor));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor)
|
||||
{
|
||||
MetaSurfaceActor *surface_actor =
|
||||
meta_window_actor_get_surface (actor);
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (
|
||||
META_SURFACE_ACTOR_WAYLAND (surface_actor));
|
||||
GNode *root_node = surface->subsurface_branch_node;
|
||||
|
||||
g_node_traverse (root_node,
|
||||
G_IN_ORDER,
|
||||
G_TRAVERSE_LEAVES,
|
||||
-1,
|
||||
remove_surface_actor_from_children,
|
||||
actor);
|
||||
|
||||
g_node_traverse (root_node,
|
||||
G_IN_ORDER,
|
||||
G_TRAVERSE_LEAVES,
|
||||
-1,
|
||||
add_surface_actor_to_children,
|
||||
actor);
|
||||
}
|
||||
|
||||
MetaWindowActor *
|
||||
meta_window_actor_wayland_from_surface (MetaWaylandSurface *surface)
|
||||
{
|
||||
if (surface->window)
|
||||
return meta_window_actor_from_window (surface->window);
|
||||
else if (surface->sub.parent)
|
||||
return meta_window_actor_wayland_from_surface (surface->sub.parent);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_wayland_assign_surface_actor (MetaWindowActor *actor,
|
||||
MetaSurfaceActor *surface_actor)
|
||||
{
|
||||
MetaWindowActorClass *parent_class =
|
||||
META_WINDOW_ACTOR_CLASS (meta_window_actor_wayland_parent_class);
|
||||
|
||||
parent_class->assign_surface_actor (actor, surface_actor);
|
||||
|
||||
meta_window_actor_wayland_rebuild_surface_tree (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_wayland_frame_complete (MetaWindowActor *actor,
|
||||
ClutterFrameInfo *frame_info,
|
||||
@ -64,6 +147,7 @@ meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
|
||||
{
|
||||
MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass);
|
||||
|
||||
window_actor_class->assign_surface_actor = meta_window_actor_wayland_assign_surface_actor;
|
||||
window_actor_class->frame_complete = meta_window_actor_wayland_frame_complete;
|
||||
window_actor_class->queue_frame_drawn = meta_window_actor_wayland_queue_frame_drawn;
|
||||
window_actor_class->pre_paint = meta_window_actor_wayland_pre_paint;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define META_WINDOW_ACTOR_WAYLAND_H
|
||||
|
||||
#include "compositor/meta-window-actor-private.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
|
||||
#define META_TYPE_WINDOW_ACTOR_WAYLAND (meta_window_actor_wayland_get_type())
|
||||
G_DECLARE_FINAL_TYPE (MetaWindowActorWayland,
|
||||
@ -31,4 +32,7 @@ G_DECLARE_FINAL_TYPE (MetaWindowActorWayland,
|
||||
META, WINDOW_ACTOR_WAYLAND,
|
||||
MetaWindowActor)
|
||||
|
||||
void meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor);
|
||||
MetaWindowActor * meta_window_actor_wayland_from_surface (MetaWaylandSurface *surface);
|
||||
|
||||
#endif /*META_WINDOW_ACTOR_WAYLAND_H */
|
||||
|
@ -338,6 +338,9 @@ meta_window_actor_x11_assign_surface_actor (MetaWindowActor *actor,
|
||||
|
||||
parent_class->assign_surface_actor (actor, surface_actor);
|
||||
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (actor),
|
||||
CLUTTER_ACTOR (surface_actor));
|
||||
|
||||
actor_x11->repaint_scheduled_id =
|
||||
g_signal_connect (surface_actor, "repaint-scheduled",
|
||||
G_CALLBACK (surface_repaint_scheduled),
|
||||
|
@ -377,7 +377,6 @@ meta_window_actor_real_assign_surface_actor (MetaWindowActor *self,
|
||||
priv->size_changed_id = g_signal_connect (priv->surface, "size-changed",
|
||||
G_CALLBACK (surface_size_changed),
|
||||
self);
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
|
||||
|
||||
meta_window_actor_update_shape (self);
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
#include "compositor/meta-window-actor-wayland.h"
|
||||
#include "compositor/region-utils.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
@ -76,18 +77,10 @@ meta_wayland_actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||
meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (surface_role));
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
GList *l;
|
||||
|
||||
meta_surface_actor_wayland_add_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (priv->actor),
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
|
||||
for (l = surface->subsurfaces; l; l = l->next)
|
||||
{
|
||||
ClutterActor *subsurface_actor =
|
||||
CLUTTER_ACTOR (meta_wayland_surface_get_actor (l->data));
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (priv->actor), subsurface_actor);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -139,7 +132,7 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaSurfaceActor *surface_actor;
|
||||
MetaShapedTexture *stex;
|
||||
GList *l;
|
||||
GNode *n;
|
||||
cairo_rectangle_int_t surface_rect;
|
||||
int geometry_scale;
|
||||
|
||||
@ -205,12 +198,18 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor
|
||||
meta_surface_actor_reset_viewport_dst_size (surface_actor);
|
||||
}
|
||||
|
||||
for (l = surface->subsurfaces; l; l = l->next)
|
||||
for (n = g_node_first_child (surface->subsurface_branch_node);
|
||||
n;
|
||||
n = g_node_next_sibling (n))
|
||||
{
|
||||
MetaWaylandSurface *subsurface_surface = l->data;
|
||||
MetaWaylandActorSurface *subsurface_actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (subsurface_surface->role);
|
||||
MetaWaylandSurface *subsurface_surface = n->data;
|
||||
MetaWaylandActorSurface *subsurface_actor_surface;
|
||||
|
||||
if (G_NODE_IS_LEAF (n))
|
||||
continue;
|
||||
|
||||
subsurface_actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (subsurface_surface->role);
|
||||
meta_wayland_actor_surface_sync_actor_state (subsurface_actor_surface);
|
||||
}
|
||||
}
|
||||
|
@ -1194,14 +1194,19 @@ static gboolean
|
||||
pointer_can_grab_surface (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
GList *l;
|
||||
GNode *n;
|
||||
|
||||
if (pointer->focus_surface == surface)
|
||||
return TRUE;
|
||||
|
||||
for (l = surface->subsurfaces; l; l = l->next)
|
||||
for (n = g_node_first_child (surface->subsurface_branch_node);
|
||||
n;
|
||||
n = g_node_next_sibling (n))
|
||||
{
|
||||
MetaWaylandSurface *subsurface = l->data;
|
||||
MetaWaylandSurface *subsurface = n->data;
|
||||
|
||||
if (G_NODE_IS_LEAF (n))
|
||||
continue;
|
||||
|
||||
if (pointer_can_grab_surface (pointer, subsurface))
|
||||
return TRUE;
|
||||
|
@ -43,19 +43,24 @@ meta_wayland_shell_surface_calculate_geometry (MetaWaylandShellSurface *shell_su
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaRectangle geometry;
|
||||
GList *l;
|
||||
GNode *n;
|
||||
|
||||
geometry = (MetaRectangle) {
|
||||
.width = meta_wayland_surface_get_width (surface),
|
||||
.height = meta_wayland_surface_get_height (surface),
|
||||
};
|
||||
|
||||
for (l = surface->subsurfaces; l; l = l->next)
|
||||
for (n = g_node_first_child (surface->subsurface_branch_node);
|
||||
n;
|
||||
n = g_node_next_sibling (n))
|
||||
{
|
||||
MetaWaylandSurface *subsurface_surface = l->data;
|
||||
MetaWaylandSubsurface *subsurface =
|
||||
META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
||||
MetaWaylandSurface *subsurface_surface = n->data;
|
||||
MetaWaylandSubsurface *subsurface;
|
||||
|
||||
if (G_NODE_IS_LEAF (n))
|
||||
continue;
|
||||
|
||||
subsurface = META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
||||
meta_wayland_subsurface_union_geometry (subsurface,
|
||||
0, 0,
|
||||
&geometry);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "wayland/meta-wayland-subsurface.h"
|
||||
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
#include "compositor/meta-window-actor-wayland.h"
|
||||
#include "wayland/meta-wayland.h"
|
||||
#include "wayland/meta-wayland-actor-surface.h"
|
||||
#include "wayland/meta-wayland-buffer.h"
|
||||
@ -51,6 +52,21 @@ G_DEFINE_TYPE (MetaWaylandSubsurface,
|
||||
meta_wayland_subsurface,
|
||||
META_TYPE_WAYLAND_ACTOR_SURFACE)
|
||||
|
||||
static void
|
||||
transform_subsurface_position (MetaWaylandSurface *surface,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
do
|
||||
{
|
||||
*x += surface->sub.x;
|
||||
*y += surface->sub.y;
|
||||
|
||||
surface = surface->sub.parent;
|
||||
}
|
||||
while (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
sync_actor_subsurface_state (MetaWaylandSurface *surface)
|
||||
{
|
||||
@ -65,8 +81,8 @@ sync_actor_subsurface_state (MetaWaylandSurface *surface)
|
||||
if (toplevel_window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
return;
|
||||
|
||||
x = surface->offset_x + surface->sub.x;
|
||||
y = surface->offset_y + surface->sub.y;
|
||||
x = y = 0;
|
||||
transform_subsurface_position (surface, &x, &y);
|
||||
|
||||
clutter_actor_set_position (actor, x, y);
|
||||
|
||||
@ -76,6 +92,26 @@ sync_actor_subsurface_state (MetaWaylandSurface *surface)
|
||||
clutter_actor_hide (actor);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_child (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurface *sibling)
|
||||
{
|
||||
if (surface->sub.parent == sibling)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_sibling (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurface *sibling)
|
||||
{
|
||||
if (surface->sub.parent == sibling->sub.parent)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
|
||||
{
|
||||
@ -95,15 +131,16 @@ meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
|
||||
if (surface->sub.pending_placement_ops)
|
||||
{
|
||||
GSList *it;
|
||||
MetaWaylandSurface *parent = surface->sub.parent;
|
||||
ClutterActor *parent_actor =
|
||||
clutter_actor_get_parent (CLUTTER_ACTOR (meta_wayland_surface_get_actor (parent)));
|
||||
ClutterActor *surface_actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
|
||||
MetaWaylandSurface *parent;
|
||||
MetaWindowActor *window_actor;
|
||||
|
||||
parent = surface->sub.parent;
|
||||
|
||||
for (it = surface->sub.pending_placement_ops; it; it = it->next)
|
||||
{
|
||||
MetaWaylandSubsurfacePlacementOp *op = it->data;
|
||||
ClutterActor *sibling_actor;
|
||||
MetaWaylandSurface *sibling;
|
||||
GNode *sibling_node;
|
||||
|
||||
if (!op->sibling)
|
||||
{
|
||||
@ -111,19 +148,25 @@ meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
|
||||
continue;
|
||||
}
|
||||
|
||||
sibling_actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (op->sibling));
|
||||
sibling = op->sibling;
|
||||
if (is_child (surface, sibling))
|
||||
sibling_node = sibling->subsurface_leaf_node;
|
||||
else
|
||||
sibling_node = sibling->subsurface_branch_node;
|
||||
|
||||
g_node_unlink (surface->subsurface_branch_node);
|
||||
|
||||
switch (op->placement)
|
||||
{
|
||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
|
||||
clutter_actor_set_child_above_sibling (parent_actor,
|
||||
surface_actor,
|
||||
sibling_actor);
|
||||
g_node_insert_after (parent->subsurface_branch_node,
|
||||
sibling_node,
|
||||
surface->subsurface_branch_node);
|
||||
break;
|
||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
|
||||
clutter_actor_set_child_below_sibling (parent_actor,
|
||||
surface_actor,
|
||||
sibling_actor);
|
||||
g_node_insert_before (parent->subsurface_branch_node,
|
||||
sibling_node,
|
||||
surface->subsurface_branch_node);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -133,6 +176,10 @@ meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
|
||||
|
||||
g_slist_free (surface->sub.pending_placement_ops);
|
||||
surface->sub.pending_placement_ops = NULL;
|
||||
|
||||
window_actor = meta_window_actor_wayland_from_surface (surface);
|
||||
if (window_actor)
|
||||
meta_window_actor_wayland_rebuild_surface_tree (window_actor);
|
||||
}
|
||||
|
||||
if (meta_wayland_surface_is_effectively_synchronized (surface))
|
||||
@ -151,7 +198,7 @@ meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaRectangle geometry;
|
||||
GList *l;
|
||||
GNode *n;
|
||||
|
||||
geometry = (MetaRectangle) {
|
||||
.x = surface->offset_x + surface->sub.x,
|
||||
@ -162,12 +209,17 @@ meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
||||
|
||||
meta_rectangle_union (out_geometry, &geometry, out_geometry);
|
||||
|
||||
for (l = surface->subsurfaces; l; l = l->next)
|
||||
for (n = g_node_first_child (surface->subsurface_branch_node);
|
||||
n;
|
||||
n = g_node_next_sibling (n))
|
||||
{
|
||||
MetaWaylandSurface *subsurface_surface = l->data;
|
||||
MetaWaylandSubsurface *subsurface =
|
||||
META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
||||
MetaWaylandSurface *subsurface_surface = n->data;
|
||||
MetaWaylandSubsurface *subsurface;
|
||||
|
||||
if (G_NODE_IS_LEAF (n))
|
||||
continue;
|
||||
|
||||
subsurface = META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
||||
meta_wayland_subsurface_union_geometry (subsurface,
|
||||
parent_x + geometry.x,
|
||||
parent_y + geometry.y,
|
||||
@ -242,12 +294,13 @@ wl_subsurface_destructor (struct wl_resource *resource)
|
||||
|
||||
meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
|
||||
surface);
|
||||
|
||||
g_node_unlink (surface->subsurface_branch_node);
|
||||
unparent_actor (surface);
|
||||
|
||||
if (surface->sub.parent)
|
||||
{
|
||||
wl_list_remove (&surface->sub.parent_destroy_listener.link);
|
||||
surface->sub.parent->subsurfaces =
|
||||
g_list_remove (surface->sub.parent->subsurfaces, surface);
|
||||
unparent_actor (surface);
|
||||
surface->sub.parent = NULL;
|
||||
}
|
||||
|
||||
@ -279,9 +332,9 @@ static gboolean
|
||||
is_valid_sibling (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurface *sibling)
|
||||
{
|
||||
if (surface->sub.parent == sibling)
|
||||
if (is_child (surface, sibling))
|
||||
return TRUE;
|
||||
if (surface->sub.parent == sibling->sub.parent)
|
||||
if (is_sibling (surface, sibling))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@ -409,7 +462,6 @@ surface_handle_parent_surface_destroyed (struct wl_listener *listener,
|
||||
sub.parent_destroy_listener);
|
||||
|
||||
surface->sub.parent = NULL;
|
||||
unparent_actor (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -422,6 +474,8 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||
MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource);
|
||||
MetaWindow *toplevel_window;
|
||||
MetaWindowActor *window_actor;
|
||||
MetaSurfaceActor *surface_actor;
|
||||
|
||||
if (surface->wl_subsurface)
|
||||
{
|
||||
@ -463,15 +517,16 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||
surface_handle_parent_surface_destroyed;
|
||||
wl_resource_add_destroy_listener (parent->resource,
|
||||
&surface->sub.parent_destroy_listener);
|
||||
parent->subsurfaces = g_list_append (parent->subsurfaces, surface);
|
||||
|
||||
if (meta_wayland_surface_get_actor (parent))
|
||||
{
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (meta_wayland_surface_get_actor (parent)),
|
||||
CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)));
|
||||
}
|
||||
g_node_append (parent->subsurface_branch_node,
|
||||
surface->subsurface_branch_node);
|
||||
|
||||
clutter_actor_set_reactive (CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)), TRUE);
|
||||
window_actor = meta_window_actor_wayland_from_surface (surface);
|
||||
if (window_actor)
|
||||
meta_window_actor_wayland_rebuild_surface_tree (window_actor);
|
||||
|
||||
surface_actor = meta_wayland_surface_get_actor (surface);
|
||||
clutter_actor_set_reactive (CLUTTER_ACTOR (surface_actor), TRUE);
|
||||
}
|
||||
|
||||
static const struct wl_subcompositor_interface meta_wayland_subcompositor_interface = {
|
||||
|
@ -646,12 +646,16 @@ meta_wayland_surface_is_effectively_synchronized (MetaWaylandSurface *surface)
|
||||
}
|
||||
|
||||
static void
|
||||
parent_surface_state_applied (gpointer data,
|
||||
gpointer user_data)
|
||||
parent_surface_state_applied (GNode *subsurface_node,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaWaylandSurface *surface = data;
|
||||
MetaWaylandSubsurface *subsurface = META_WAYLAND_SUBSURFACE (surface->role);
|
||||
MetaWaylandSurface *surface = subsurface_node->data;
|
||||
MetaWaylandSubsurface *subsurface;
|
||||
|
||||
if (G_NODE_IS_LEAF (subsurface_node))
|
||||
return;
|
||||
|
||||
subsurface = META_WAYLAND_SUBSURFACE (surface->role);
|
||||
meta_wayland_subsurface_parent_state_applied (subsurface);
|
||||
}
|
||||
|
||||
@ -836,7 +840,10 @@ cleanup:
|
||||
|
||||
pending_state_reset (pending);
|
||||
|
||||
g_list_foreach (surface->subsurfaces, parent_surface_state_applied, NULL);
|
||||
g_node_children_foreach (surface->subsurface_branch_node,
|
||||
G_TRAVERSE_ALL,
|
||||
parent_surface_state_applied,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1254,14 +1261,22 @@ meta_wayland_surface_update_outputs (MetaWaylandSurface *surface)
|
||||
static void
|
||||
meta_wayland_surface_update_outputs_recursively (MetaWaylandSurface *surface)
|
||||
{
|
||||
GList *l;
|
||||
GNode *n;
|
||||
|
||||
meta_wayland_surface_update_outputs (surface);
|
||||
|
||||
for (l = surface->subsurfaces; l != NULL; l = l->next)
|
||||
meta_wayland_surface_update_outputs_recursively (l->data);
|
||||
for (n = g_node_first_child (surface->subsurface_branch_node);
|
||||
n;
|
||||
n = g_node_next_sibling (n))
|
||||
{
|
||||
if (G_NODE_IS_LEAF (n))
|
||||
continue;
|
||||
|
||||
meta_wayland_surface_update_outputs_recursively (n->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
meta_wayland_surface_set_window (MetaWaylandSurface *surface,
|
||||
MetaWindow *window)
|
||||
@ -1306,6 +1321,13 @@ meta_wayland_surface_set_window (MetaWaylandSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unlink_note (GNode *node,
|
||||
gpointer data)
|
||||
{
|
||||
g_node_unlink (node);
|
||||
}
|
||||
|
||||
static void
|
||||
wl_surface_destructor (struct wl_resource *resource)
|
||||
{
|
||||
@ -1355,6 +1377,15 @@ wl_surface_destructor (struct wl_resource *resource)
|
||||
if (surface->wl_subsurface)
|
||||
wl_resource_destroy (surface->wl_subsurface);
|
||||
|
||||
if (surface->subsurface_branch_node)
|
||||
{
|
||||
g_node_children_foreach (surface->subsurface_branch_node,
|
||||
G_TRAVERSE_NON_LEAVES,
|
||||
unlink_note,
|
||||
NULL);
|
||||
g_clear_pointer (&surface->subsurface_branch_node, g_node_destroy);
|
||||
}
|
||||
|
||||
g_hash_table_destroy (surface->shortcut_inhibited_seats);
|
||||
|
||||
g_object_unref (surface);
|
||||
@ -1612,6 +1643,9 @@ static void
|
||||
meta_wayland_surface_init (MetaWaylandSurface *surface)
|
||||
{
|
||||
surface->pending = g_object_new (META_TYPE_WAYLAND_PENDING_STATE, NULL);
|
||||
surface->subsurface_branch_node = g_node_new (surface);
|
||||
surface->subsurface_leaf_node =
|
||||
g_node_prepend_data (surface->subsurface_branch_node, surface);
|
||||
|
||||
g_signal_connect (surface, "geometry-changed",
|
||||
G_CALLBACK (meta_wayland_surface_update_outputs_recursively),
|
||||
|
@ -145,7 +145,8 @@ struct _MetaWaylandSurface
|
||||
cairo_region_t *opaque_region;
|
||||
int scale;
|
||||
int32_t offset_x, offset_y;
|
||||
GList *subsurfaces;
|
||||
GNode *subsurface_branch_node;
|
||||
GNode *subsurface_leaf_node;
|
||||
GHashTable *outputs_to_destroy_notify_id;
|
||||
MetaMonitorTransform buffer_transform;
|
||||
|
||||
|
@ -989,14 +989,19 @@ static gboolean
|
||||
tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
GList *l;
|
||||
GNode *n;
|
||||
|
||||
if (tool->focus_surface == surface)
|
||||
return TRUE;
|
||||
|
||||
for (l = surface->subsurfaces; l; l = l->next)
|
||||
for (n = g_node_first_child (surface->subsurface_branch_node);
|
||||
n;
|
||||
n = g_node_next_sibling (n))
|
||||
{
|
||||
MetaWaylandSurface *subsurface = l->data;
|
||||
MetaWaylandSurface *subsurface = n->data;
|
||||
|
||||
if (G_NODE_IS_LEAF (n))
|
||||
continue;
|
||||
|
||||
if (tablet_tool_can_grab_surface (tool, subsurface))
|
||||
return TRUE;
|
||||
|
Loading…
Reference in New Issue
Block a user