mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 21:34:09 +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);
|
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
|
||||||
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
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);
|
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);
|
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
|
static void
|
||||||
wl_subsurface_place_above (struct wl_client *client,
|
wl_subsurface_place_above (struct wl_client *client,
|
||||||
struct wl_resource *resource,
|
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 *surface = wl_container_of (subsurface, surface, subsurface);
|
||||||
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
|
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));
|
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
|
||||||
|
|
||||||
clutter_actor_set_child_above_sibling (parent_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 *surface = wl_container_of (subsurface, surface, subsurface);
|
||||||
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
|
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));
|
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
|
||||||
|
|
||||||
clutter_actor_set_child_below_sibling (parent_actor,
|
clutter_actor_set_child_below_sibling (parent_actor,
|
||||||
@ -1086,6 +1121,18 @@ wl_subcompositor_destroy (struct wl_client *client,
|
|||||||
wl_resource_destroy (resource);
|
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
|
static void
|
||||||
wl_subcompositor_get_subsurface (struct wl_client *client,
|
wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||||
struct wl_resource *resource,
|
struct wl_resource *resource,
|
||||||
@ -1108,6 +1155,13 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
|||||||
return;
|
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_add_child (CLUTTER_ACTOR (parent->surface_actor),
|
||||||
CLUTTER_ACTOR (surface->surface_actor));
|
CLUTTER_ACTOR (surface->surface_actor));
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,13 @@ struct _MetaWaylandSurface
|
|||||||
MetaWaylandSurfaceExtension gtk_surface;
|
MetaWaylandSurfaceExtension gtk_surface;
|
||||||
MetaWaylandSurfaceExtension subsurface;
|
MetaWaylandSurfaceExtension subsurface;
|
||||||
|
|
||||||
|
GList *subsurfaces;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
MetaWaylandSurface *parent;
|
||||||
|
struct wl_listener parent_destroy_listener;
|
||||||
|
} sub;
|
||||||
|
|
||||||
/* All the pending state, that wl_surface.commit will apply. */
|
/* All the pending state, that wl_surface.commit will apply. */
|
||||||
MetaWaylandDoubleBufferedState pending;
|
MetaWaylandDoubleBufferedState pending;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user