[PATCH weston] compositor: fix sub-surface view stacking order

ppaalanen at gmail.com ppaalanen at gmail.com
Tue Nov 19 04:03:35 PST 2013

From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

If you opened a window with sub-surfaces, and then raised another window
on top of that, the underlaying window's main surface was stacked
properly, but the sub-surfaces remained on top of the raised window.
IOW, the raised window was in between the other window and its

This got broken in a7af70436b7dccfacd736626d6719b3e751fd985, "Split the
geometry information from weston_surface out into weston_view".

Fix the issues:

In view_list_add_subsurface_view(), the views need to be added to the
end of the list, not to the head. This alone fixes the above problem,
but causes the sub-surface views to be stacked irrespective of their
surface stacking order. The stacking order in this test case is fixed by
the changes to view_list_add(), but for sub-sub-surfaces a similar
change is needed in view_list_add_subsurface_view() too.

In view_list_add(), build the view list in the sub-surface stacking
order, instead of pulling the parent surface always on top. Also handle
the case, when the subsurface_list is completely empty: the parent
surface's view must still be added.

Reported-by: Julien Isorce <julien.isorce at collabora.com>
Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
Cc: Jason Ekstrand <jason at jlekstrand.net>
 src/compositor.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index b8e0c6e..7c688ef 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1612,11 +1612,18 @@ view_list_add_subsurface_view(struct weston_compositor *compositor,
-	wl_list_insert(compositor->view_list.next, &view->link);
-	wl_list_for_each(child, &sub->surface->subsurface_list, parent_link)
-		if (child->surface != sub->surface)
+	if (wl_list_empty(&sub->surface->subsurface_list)) {
+		wl_list_insert(compositor->view_list.prev, &view->link);
+		return;
+	}
+	wl_list_for_each(child, &sub->surface->subsurface_list, parent_link) {
+		if (child->surface == sub->surface)
+			wl_list_insert(compositor->view_list.prev, &view->link);
+		else
 			view_list_add_subsurface_view(compositor, child, view);
+	}
 static void
@@ -1626,11 +1633,18 @@ view_list_add(struct weston_compositor *compositor,
 	struct weston_subsurface *sub;
-	wl_list_insert(compositor->view_list.prev, &view->link);
-	wl_list_for_each(sub, &view->surface->subsurface_list, parent_link)
-		if (sub->surface != view->surface)
+	if (wl_list_empty(&view->surface->subsurface_list)) {
+		wl_list_insert(compositor->view_list.prev, &view->link);
+		return;
+	}
+	wl_list_for_each(sub, &view->surface->subsurface_list, parent_link) {
+		if (sub->surface == view->surface)
+			wl_list_insert(compositor->view_list.prev, &view->link);
+		else
 			view_list_add_subsurface_view(compositor, sub, view);
+	}
 static void

More information about the wayland-devel mailing list