From b8c16c995b02ca797a5ea7625756e6debe91220b Mon Sep 17 00:00:00 2001 From: Arnaud Vrac Date: Wed, 8 Jun 2016 18:37:57 +0200 Subject: [PATCH] compositor: allow using nested parent as a subsurface sibling 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. Signed-off-by: Daniel Stone --- libweston/compositor.c | 28 ++++++++++---------------- tests/subsurface-test.c | 44 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/libweston/compositor.c b/libweston/compositor.c index d552e18f..ee0a007f 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -3521,17 +3521,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; } @@ -3543,8 +3542,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, @@ -3553,13 +3551,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 3ababdd3..03ff5392 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 *grandchild; + 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); + grandchild = wl_compositor_create_surface(client->wl_compositor); + sub = wl_subcompositor_get_subsurface(subco, grandchild, 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_subcompositor *subco; + struct wl_surface *grandchild; + 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); + grandchild = wl_compositor_create_surface(client->wl_compositor); + sub = wl_subcompositor_get_subsurface(subco, grandchild, com.child[0]); + + wl_subsurface_place_below(sub, com.child[0]); + + client_roundtrip(client); +} + TEST(test_subsurface_place_above_stranger) { struct client *client;