mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
wayland: Report error when trying to stack subsurface incorrectly
Don't allow a client to stack a subsurface next to a subsurface with another parent, or to a non-parent non-subsurface surface. Signed-off-by: Jonas Ådahl <jadahl@gmail.com> https://bugzilla.gnome.org/show_bug.cgi?id=705502
This commit is contained in:
parent
c3b0faec82
commit
799c27484d
@ -999,7 +999,14 @@ wl_subsurface_destructor (struct wl_resource *resource)
|
||||
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
||||
|
||||
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;
|
||||
}
|
||||
destroy_surface_extension (subsurface);
|
||||
}
|
||||
|
||||
@ -1022,6 +1029,16 @@ wl_subsurface_set_position (struct wl_client *client,
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor), x, y);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_valid_sibling (MetaWaylandSurface *surface, MetaWaylandSurface *sibling)
|
||||
{
|
||||
if (surface->sub.parent == sibling)
|
||||
return TRUE;
|
||||
if (surface->sub.parent == sibling->sub.parent)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
wl_subsurface_place_above (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
@ -1032,6 +1049,15 @@ wl_subsurface_place_above (struct wl_client *client,
|
||||
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
||||
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
|
||||
|
||||
if (!is_valid_sibling (surface, sibling))
|
||||
{
|
||||
wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
|
||||
"wl_subsurface::place_above: wl_surface@%d is "
|
||||
"not a valid parent or sibling",
|
||||
wl_resource_get_id (sibling->resource));
|
||||
return;
|
||||
}
|
||||
|
||||
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
|
||||
|
||||
clutter_actor_set_child_above_sibling (parent_actor,
|
||||
@ -1049,6 +1075,15 @@ wl_subsurface_place_below (struct wl_client *client,
|
||||
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
||||
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
|
||||
|
||||
if (!is_valid_sibling (surface, sibling))
|
||||
{
|
||||
wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
|
||||
"wl_subsurface::place_below: wl_surface@%d is "
|
||||
"not a valid parent or sibling",
|
||||
wl_resource_get_id (sibling->resource));
|
||||
return;
|
||||
}
|
||||
|
||||
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
|
||||
|
||||
clutter_actor_set_child_below_sibling (parent_actor,
|
||||
@ -1086,6 +1121,18 @@ wl_subcompositor_destroy (struct wl_client *client,
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
surface_handle_parent_surface_destroyed (struct wl_listener *listener,
|
||||
void *data)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_container_of (listener,
|
||||
surface,
|
||||
sub.parent_destroy_listener);
|
||||
|
||||
surface->sub.parent = NULL;
|
||||
unparent_actor (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
@ -1108,6 +1155,13 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
surface->sub.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);
|
||||
parent->subsurfaces = g_list_append (parent->subsurfaces, surface);
|
||||
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (parent->surface_actor),
|
||||
CLUTTER_ACTOR (surface->surface_actor));
|
||||
}
|
||||
|
@ -85,6 +85,13 @@ struct _MetaWaylandSurface
|
||||
MetaWaylandSurfaceExtension gtk_surface;
|
||||
MetaWaylandSurfaceExtension subsurface;
|
||||
|
||||
GList *subsurfaces;
|
||||
|
||||
struct {
|
||||
MetaWaylandSurface *parent;
|
||||
struct wl_listener parent_destroy_listener;
|
||||
} sub;
|
||||
|
||||
/* All the pending state, that wl_surface.commit will apply. */
|
||||
MetaWaylandDoubleBufferedState pending;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user