[PATCH weston] compositor: allow using nested parent as a subsurface sibling

Arnaud Vrac avrac at freebox.fr
Wed Jun 8 16:38:06 UTC 2016


The parent of a subsurface can be used as a sibling in the place_below
and place_above calls. However this did not work when the parent is
nested, so fix the sibling check and add a test to check this case.
---
 src/compositor.c        | 28 ++++++++++------------------
 tests/subsurface-test.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index c6feae2..c2c6764 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -3334,17 +3334,16 @@ subsurface_set_position(struct wl_client *client,
 }
 
 static struct weston_subsurface *
-subsurface_from_surface(struct weston_surface *surface)
+subsurface_find_sibling(struct weston_subsurface *sub,
+		       struct weston_surface *surface)
 {
-	struct weston_subsurface *sub;
-
-	sub = weston_surface_to_subsurface(surface);
-	if (sub)
-		return sub;
+	struct weston_surface *parent = sub->parent;
+	struct weston_subsurface *sibling;
 
-	wl_list_for_each(sub, &surface->subsurface_list, parent_link)
-		if (sub->surface == surface)
-			return sub;
+	wl_list_for_each(sibling, &parent->subsurface_list, parent_link) {
+		if (sibling->surface == surface && sibling != sub)
+			return sibling;
+	}
 
 	return NULL;
 }
@@ -3356,8 +3355,7 @@ subsurface_sibling_check(struct weston_subsurface *sub,
 {
 	struct weston_subsurface *sibling;
 
-	sibling = subsurface_from_surface(surface);
-
+	sibling = subsurface_find_sibling(sub, surface);
 	if (!sibling) {
 		wl_resource_post_error(sub->resource,
 			WL_SUBSURFACE_ERROR_BAD_SURFACE,
@@ -3366,13 +3364,7 @@ subsurface_sibling_check(struct weston_subsurface *sub,
 		return NULL;
 	}
 
-	if (sibling->parent != sub->parent) {
-		wl_resource_post_error(sub->resource,
-			WL_SUBSURFACE_ERROR_BAD_SURFACE,
-			"%s: wl_surface@%d has a different parent",
-			request, wl_resource_get_id(surface->resource));
-		return NULL;
-	}
+	assert(sibling->parent == sub->parent);
 
 	return sibling;
 }
diff --git a/tests/subsurface-test.c b/tests/subsurface-test.c
index 3ababdd..d565a5b 100644
--- a/tests/subsurface-test.c
+++ b/tests/subsurface-test.c
@@ -250,6 +250,50 @@ TEST(test_subsurface_loop_paradox)
 			      WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE);
 }
 
+TEST(test_subsurface_place_above_nested_parent)
+{
+	struct client *client;
+	struct compound_surface com;
+	struct wl_surface *parent;
+	struct wl_subcompositor *subco;
+	struct wl_subsurface *sub;
+
+	client = create_client_and_test_surface(100, 50, 123, 77);
+	assert(client);
+
+	populate_compound_surface(&com, client);
+
+	subco = get_subcompositor(client);
+	parent = wl_compositor_create_surface(client->wl_compositor);
+	sub = wl_subcompositor_get_subsurface(subco, parent, com.child[0]);
+
+	wl_subsurface_place_above(sub, com.child[0]);
+
+	client_roundtrip(client);
+}
+
+TEST(test_subsurface_place_below_nested_parent)
+{
+	struct client *client;
+	struct compound_surface com;
+	struct wl_surface *parent;
+	struct wl_subcompositor *subco;
+	struct wl_subsurface *sub;
+
+	client = create_client_and_test_surface(100, 50, 123, 77);
+	assert(client);
+
+	populate_compound_surface(&com, client);
+
+	subco = get_subcompositor(client);
+	parent = wl_compositor_create_surface(client->wl_compositor);
+	sub = wl_subcompositor_get_subsurface(subco, parent, com.child[0]);
+
+	wl_subsurface_place_below(sub, com.child[0]);
+
+	client_roundtrip(client);
+}
+
 TEST(test_subsurface_place_above_stranger)
 {
 	struct client *client;
-- 
2.7.4



More information about the wayland-devel mailing list