[mutter/wayland] wayland: Report error when trying to stack subsurface incorrectly
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wayland] wayland: Report error when trying to stack subsurface incorrectly
- Date: Thu, 30 Jan 2014 20:13:53 +0000 (UTC)
commit 799c27484dc7ba307d6f62311a1b468e27581676
Author: Jonas Ådahl <jadahl gmail com>
Date: Sun Jan 12 22:02:09 2014 +0100
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
src/wayland/meta-wayland-surface.c | 56 +++++++++++++++++++++++++++++++++++-
src/wayland/meta-wayland-surface.h | 7 ++++
2 files changed, 62 insertions(+), 1 deletions(-)
---
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 1ca38e5..e96c922 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -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,
@@ -1087,6 +1122,18 @@ wl_subcompositor_destroy (struct wl_client *client,
}
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,
guint32 id,
@@ -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));
}
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 9533731..fe2bfea 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -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;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]