mirror of
https://github.com/brl/mutter.git
synced 2025-02-18 06:04:10 +00: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>
|
* 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 "compositor/meta-window-actor-wayland.h"
|
||||||
#include "meta/meta-window-actor.h"
|
#include "meta/meta-window-actor.h"
|
||||||
|
#include "wayland/meta-wayland-surface.h"
|
||||||
|
|
||||||
struct _MetaWindowActorWayland
|
struct _MetaWindowActorWayland
|
||||||
{
|
{
|
||||||
@ -31,6 +32,88 @@ struct _MetaWindowActorWayland
|
|||||||
|
|
||||||
G_DEFINE_TYPE (MetaWindowActorWayland, meta_window_actor_wayland, META_TYPE_WINDOW_ACTOR)
|
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
|
static void
|
||||||
meta_window_actor_wayland_frame_complete (MetaWindowActor *actor,
|
meta_window_actor_wayland_frame_complete (MetaWindowActor *actor,
|
||||||
ClutterFrameInfo *frame_info,
|
ClutterFrameInfo *frame_info,
|
||||||
@ -64,6 +147,7 @@ meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
|
|||||||
{
|
{
|
||||||
MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (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->frame_complete = meta_window_actor_wayland_frame_complete;
|
||||||
window_actor_class->queue_frame_drawn = meta_window_actor_wayland_queue_frame_drawn;
|
window_actor_class->queue_frame_drawn = meta_window_actor_wayland_queue_frame_drawn;
|
||||||
window_actor_class->pre_paint = meta_window_actor_wayland_pre_paint;
|
window_actor_class->pre_paint = meta_window_actor_wayland_pre_paint;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#define META_WINDOW_ACTOR_WAYLAND_H
|
#define META_WINDOW_ACTOR_WAYLAND_H
|
||||||
|
|
||||||
#include "compositor/meta-window-actor-private.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())
|
#define META_TYPE_WINDOW_ACTOR_WAYLAND (meta_window_actor_wayland_get_type())
|
||||||
G_DECLARE_FINAL_TYPE (MetaWindowActorWayland,
|
G_DECLARE_FINAL_TYPE (MetaWindowActorWayland,
|
||||||
@ -31,4 +32,7 @@ G_DECLARE_FINAL_TYPE (MetaWindowActorWayland,
|
|||||||
META, WINDOW_ACTOR_WAYLAND,
|
META, WINDOW_ACTOR_WAYLAND,
|
||||||
MetaWindowActor)
|
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 */
|
#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);
|
parent_class->assign_surface_actor (actor, surface_actor);
|
||||||
|
|
||||||
|
clutter_actor_add_child (CLUTTER_ACTOR (actor),
|
||||||
|
CLUTTER_ACTOR (surface_actor));
|
||||||
|
|
||||||
actor_x11->repaint_scheduled_id =
|
actor_x11->repaint_scheduled_id =
|
||||||
g_signal_connect (surface_actor, "repaint-scheduled",
|
g_signal_connect (surface_actor, "repaint-scheduled",
|
||||||
G_CALLBACK (surface_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",
|
priv->size_changed_id = g_signal_connect (priv->surface, "size-changed",
|
||||||
G_CALLBACK (surface_size_changed),
|
G_CALLBACK (surface_size_changed),
|
||||||
self);
|
self);
|
||||||
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
|
|
||||||
|
|
||||||
meta_window_actor_update_shape (self);
|
meta_window_actor_update_shape (self);
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
#include "backends/meta-logical-monitor.h"
|
#include "backends/meta-logical-monitor.h"
|
||||||
#include "compositor/meta-surface-actor-wayland.h"
|
#include "compositor/meta-surface-actor-wayland.h"
|
||||||
|
#include "compositor/meta-window-actor-wayland.h"
|
||||||
#include "compositor/region-utils.h"
|
#include "compositor/region-utils.h"
|
||||||
#include "wayland/meta-wayland-surface.h"
|
#include "wayland/meta-wayland-surface.h"
|
||||||
#include "wayland/meta-window-wayland.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));
|
meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (surface_role));
|
||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
GList *l;
|
|
||||||
|
|
||||||
meta_surface_actor_wayland_add_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (priv->actor),
|
meta_surface_actor_wayland_add_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (priv->actor),
|
||||||
&surface->pending_frame_callback_list);
|
&surface->pending_frame_callback_list);
|
||||||
wl_list_init (&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
|
void
|
||||||
@ -139,7 +132,7 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor
|
|||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
MetaSurfaceActor *surface_actor;
|
MetaSurfaceActor *surface_actor;
|
||||||
MetaShapedTexture *stex;
|
MetaShapedTexture *stex;
|
||||||
GList *l;
|
GNode *n;
|
||||||
cairo_rectangle_int_t surface_rect;
|
cairo_rectangle_int_t surface_rect;
|
||||||
int geometry_scale;
|
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);
|
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;
|
MetaWaylandSurface *subsurface_surface = n->data;
|
||||||
MetaWaylandActorSurface *subsurface_actor_surface =
|
MetaWaylandActorSurface *subsurface_actor_surface;
|
||||||
META_WAYLAND_ACTOR_SURFACE (subsurface_surface->role);
|
|
||||||
|
|
||||||
|
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);
|
meta_wayland_actor_surface_sync_actor_state (subsurface_actor_surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1194,14 +1194,19 @@ static gboolean
|
|||||||
pointer_can_grab_surface (MetaWaylandPointer *pointer,
|
pointer_can_grab_surface (MetaWaylandPointer *pointer,
|
||||||
MetaWaylandSurface *surface)
|
MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
GList *l;
|
GNode *n;
|
||||||
|
|
||||||
if (pointer->focus_surface == surface)
|
if (pointer->focus_surface == surface)
|
||||||
return TRUE;
|
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))
|
if (pointer_can_grab_surface (pointer, subsurface))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -43,19 +43,24 @@ meta_wayland_shell_surface_calculate_geometry (MetaWaylandShellSurface *shell_su
|
|||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
MetaRectangle geometry;
|
MetaRectangle geometry;
|
||||||
GList *l;
|
GNode *n;
|
||||||
|
|
||||||
geometry = (MetaRectangle) {
|
geometry = (MetaRectangle) {
|
||||||
.width = meta_wayland_surface_get_width (surface),
|
.width = meta_wayland_surface_get_width (surface),
|
||||||
.height = meta_wayland_surface_get_height (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;
|
MetaWaylandSurface *subsurface_surface = n->data;
|
||||||
MetaWaylandSubsurface *subsurface =
|
MetaWaylandSubsurface *subsurface;
|
||||||
META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
|
||||||
|
|
||||||
|
if (G_NODE_IS_LEAF (n))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
subsurface = META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
||||||
meta_wayland_subsurface_union_geometry (subsurface,
|
meta_wayland_subsurface_union_geometry (subsurface,
|
||||||
0, 0,
|
0, 0,
|
||||||
&geometry);
|
&geometry);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "wayland/meta-wayland-subsurface.h"
|
#include "wayland/meta-wayland-subsurface.h"
|
||||||
|
|
||||||
#include "compositor/meta-surface-actor-wayland.h"
|
#include "compositor/meta-surface-actor-wayland.h"
|
||||||
|
#include "compositor/meta-window-actor-wayland.h"
|
||||||
#include "wayland/meta-wayland.h"
|
#include "wayland/meta-wayland.h"
|
||||||
#include "wayland/meta-wayland-actor-surface.h"
|
#include "wayland/meta-wayland-actor-surface.h"
|
||||||
#include "wayland/meta-wayland-buffer.h"
|
#include "wayland/meta-wayland-buffer.h"
|
||||||
@ -51,6 +52,21 @@ G_DEFINE_TYPE (MetaWaylandSubsurface,
|
|||||||
meta_wayland_subsurface,
|
meta_wayland_subsurface,
|
||||||
META_TYPE_WAYLAND_ACTOR_SURFACE)
|
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
|
static void
|
||||||
sync_actor_subsurface_state (MetaWaylandSurface *surface)
|
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)
|
if (toplevel_window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
x = surface->offset_x + surface->sub.x;
|
x = y = 0;
|
||||||
y = surface->offset_y + surface->sub.y;
|
transform_subsurface_position (surface, &x, &y);
|
||||||
|
|
||||||
clutter_actor_set_position (actor, x, y);
|
clutter_actor_set_position (actor, x, y);
|
||||||
|
|
||||||
@ -76,6 +92,26 @@ sync_actor_subsurface_state (MetaWaylandSurface *surface)
|
|||||||
clutter_actor_hide (actor);
|
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
|
void
|
||||||
meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
|
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)
|
if (surface->sub.pending_placement_ops)
|
||||||
{
|
{
|
||||||
GSList *it;
|
GSList *it;
|
||||||
MetaWaylandSurface *parent = surface->sub.parent;
|
MetaWaylandSurface *parent;
|
||||||
ClutterActor *parent_actor =
|
MetaWindowActor *window_actor;
|
||||||
clutter_actor_get_parent (CLUTTER_ACTOR (meta_wayland_surface_get_actor (parent)));
|
|
||||||
ClutterActor *surface_actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
|
parent = surface->sub.parent;
|
||||||
|
|
||||||
for (it = surface->sub.pending_placement_ops; it; it = it->next)
|
for (it = surface->sub.pending_placement_ops; it; it = it->next)
|
||||||
{
|
{
|
||||||
MetaWaylandSubsurfacePlacementOp *op = it->data;
|
MetaWaylandSubsurfacePlacementOp *op = it->data;
|
||||||
ClutterActor *sibling_actor;
|
MetaWaylandSurface *sibling;
|
||||||
|
GNode *sibling_node;
|
||||||
|
|
||||||
if (!op->sibling)
|
if (!op->sibling)
|
||||||
{
|
{
|
||||||
@ -111,19 +148,25 @@ meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
|
|||||||
continue;
|
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)
|
switch (op->placement)
|
||||||
{
|
{
|
||||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
|
case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
|
||||||
clutter_actor_set_child_above_sibling (parent_actor,
|
g_node_insert_after (parent->subsurface_branch_node,
|
||||||
surface_actor,
|
sibling_node,
|
||||||
sibling_actor);
|
surface->subsurface_branch_node);
|
||||||
break;
|
break;
|
||||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
|
case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
|
||||||
clutter_actor_set_child_below_sibling (parent_actor,
|
g_node_insert_before (parent->subsurface_branch_node,
|
||||||
surface_actor,
|
sibling_node,
|
||||||
sibling_actor);
|
surface->subsurface_branch_node);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,6 +176,10 @@ meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
|
|||||||
|
|
||||||
g_slist_free (surface->sub.pending_placement_ops);
|
g_slist_free (surface->sub.pending_placement_ops);
|
||||||
surface->sub.pending_placement_ops = NULL;
|
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))
|
if (meta_wayland_surface_is_effectively_synchronized (surface))
|
||||||
@ -151,7 +198,7 @@ meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
|||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
MetaRectangle geometry;
|
MetaRectangle geometry;
|
||||||
GList *l;
|
GNode *n;
|
||||||
|
|
||||||
geometry = (MetaRectangle) {
|
geometry = (MetaRectangle) {
|
||||||
.x = surface->offset_x + surface->sub.x,
|
.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);
|
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;
|
MetaWaylandSurface *subsurface_surface = n->data;
|
||||||
MetaWaylandSubsurface *subsurface =
|
MetaWaylandSubsurface *subsurface;
|
||||||
META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
|
||||||
|
|
||||||
|
if (G_NODE_IS_LEAF (n))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
subsurface = META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
||||||
meta_wayland_subsurface_union_geometry (subsurface,
|
meta_wayland_subsurface_union_geometry (subsurface,
|
||||||
parent_x + geometry.x,
|
parent_x + geometry.x,
|
||||||
parent_y + geometry.y,
|
parent_y + geometry.y,
|
||||||
@ -242,12 +294,13 @@ wl_subsurface_destructor (struct wl_resource *resource)
|
|||||||
|
|
||||||
meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
|
meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
|
||||||
surface);
|
surface);
|
||||||
|
|
||||||
|
g_node_unlink (surface->subsurface_branch_node);
|
||||||
|
unparent_actor (surface);
|
||||||
|
|
||||||
if (surface->sub.parent)
|
if (surface->sub.parent)
|
||||||
{
|
{
|
||||||
wl_list_remove (&surface->sub.parent_destroy_listener.link);
|
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;
|
surface->sub.parent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,9 +332,9 @@ static gboolean
|
|||||||
is_valid_sibling (MetaWaylandSurface *surface,
|
is_valid_sibling (MetaWaylandSurface *surface,
|
||||||
MetaWaylandSurface *sibling)
|
MetaWaylandSurface *sibling)
|
||||||
{
|
{
|
||||||
if (surface->sub.parent == sibling)
|
if (is_child (surface, sibling))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (surface->sub.parent == sibling->sub.parent)
|
if (is_sibling (surface, sibling))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -409,7 +462,6 @@ surface_handle_parent_surface_destroyed (struct wl_listener *listener,
|
|||||||
sub.parent_destroy_listener);
|
sub.parent_destroy_listener);
|
||||||
|
|
||||||
surface->sub.parent = NULL;
|
surface->sub.parent = NULL;
|
||||||
unparent_actor (surface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -422,6 +474,8 @@ 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);
|
||||||
MetaWindow *toplevel_window;
|
MetaWindow *toplevel_window;
|
||||||
|
MetaWindowActor *window_actor;
|
||||||
|
MetaSurfaceActor *surface_actor;
|
||||||
|
|
||||||
if (surface->wl_subsurface)
|
if (surface->wl_subsurface)
|
||||||
{
|
{
|
||||||
@ -463,15 +517,16 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
|||||||
surface_handle_parent_surface_destroyed;
|
surface_handle_parent_surface_destroyed;
|
||||||
wl_resource_add_destroy_listener (parent->resource,
|
wl_resource_add_destroy_listener (parent->resource,
|
||||||
&surface->sub.parent_destroy_listener);
|
&surface->sub.parent_destroy_listener);
|
||||||
parent->subsurfaces = g_list_append (parent->subsurfaces, surface);
|
|
||||||
|
|
||||||
if (meta_wayland_surface_get_actor (parent))
|
g_node_append (parent->subsurface_branch_node,
|
||||||
{
|
surface->subsurface_branch_node);
|
||||||
clutter_actor_add_child (CLUTTER_ACTOR (meta_wayland_surface_get_actor (parent)),
|
|
||||||
CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)));
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = {
|
static const struct wl_subcompositor_interface meta_wayland_subcompositor_interface = {
|
||||||
|
@ -646,12 +646,16 @@ meta_wayland_surface_is_effectively_synchronized (MetaWaylandSurface *surface)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parent_surface_state_applied (gpointer data,
|
parent_surface_state_applied (GNode *subsurface_node,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = data;
|
MetaWaylandSurface *surface = subsurface_node->data;
|
||||||
MetaWaylandSubsurface *subsurface = META_WAYLAND_SUBSURFACE (surface->role);
|
MetaWaylandSubsurface *subsurface;
|
||||||
|
|
||||||
|
if (G_NODE_IS_LEAF (subsurface_node))
|
||||||
|
return;
|
||||||
|
|
||||||
|
subsurface = META_WAYLAND_SUBSURFACE (surface->role);
|
||||||
meta_wayland_subsurface_parent_state_applied (subsurface);
|
meta_wayland_subsurface_parent_state_applied (subsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,7 +840,10 @@ cleanup:
|
|||||||
|
|
||||||
pending_state_reset (pending);
|
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
|
static void
|
||||||
@ -1254,14 +1261,22 @@ meta_wayland_surface_update_outputs (MetaWaylandSurface *surface)
|
|||||||
static void
|
static void
|
||||||
meta_wayland_surface_update_outputs_recursively (MetaWaylandSurface *surface)
|
meta_wayland_surface_update_outputs_recursively (MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
GList *l;
|
GNode *n;
|
||||||
|
|
||||||
meta_wayland_surface_update_outputs (surface);
|
meta_wayland_surface_update_outputs (surface);
|
||||||
|
|
||||||
for (l = surface->subsurfaces; l != NULL; l = l->next)
|
for (n = g_node_first_child (surface->subsurface_branch_node);
|
||||||
meta_wayland_surface_update_outputs_recursively (l->data);
|
n;
|
||||||
|
n = g_node_next_sibling (n))
|
||||||
|
{
|
||||||
|
if (G_NODE_IS_LEAF (n))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
meta_wayland_surface_update_outputs_recursively (n->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_wayland_surface_set_window (MetaWaylandSurface *surface,
|
meta_wayland_surface_set_window (MetaWaylandSurface *surface,
|
||||||
MetaWindow *window)
|
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
|
static void
|
||||||
wl_surface_destructor (struct wl_resource *resource)
|
wl_surface_destructor (struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
@ -1355,6 +1377,15 @@ wl_surface_destructor (struct wl_resource *resource)
|
|||||||
if (surface->wl_subsurface)
|
if (surface->wl_subsurface)
|
||||||
wl_resource_destroy (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_hash_table_destroy (surface->shortcut_inhibited_seats);
|
||||||
|
|
||||||
g_object_unref (surface);
|
g_object_unref (surface);
|
||||||
@ -1612,6 +1643,9 @@ static void
|
|||||||
meta_wayland_surface_init (MetaWaylandSurface *surface)
|
meta_wayland_surface_init (MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
surface->pending = g_object_new (META_TYPE_WAYLAND_PENDING_STATE, NULL);
|
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_signal_connect (surface, "geometry-changed",
|
||||||
G_CALLBACK (meta_wayland_surface_update_outputs_recursively),
|
G_CALLBACK (meta_wayland_surface_update_outputs_recursively),
|
||||||
|
@ -145,7 +145,8 @@ 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;
|
||||||
GList *subsurfaces;
|
GNode *subsurface_branch_node;
|
||||||
|
GNode *subsurface_leaf_node;
|
||||||
GHashTable *outputs_to_destroy_notify_id;
|
GHashTable *outputs_to_destroy_notify_id;
|
||||||
MetaMonitorTransform buffer_transform;
|
MetaMonitorTransform buffer_transform;
|
||||||
|
|
||||||
|
@ -989,14 +989,19 @@ static gboolean
|
|||||||
tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
|
tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
|
||||||
MetaWaylandSurface *surface)
|
MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
GList *l;
|
GNode *n;
|
||||||
|
|
||||||
if (tool->focus_surface == surface)
|
if (tool->focus_surface == surface)
|
||||||
return TRUE;
|
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))
|
if (tablet_tool_can_grab_surface (tool, subsurface))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user