diff --git a/libweston/compositor.c b/libweston/compositor.c index 8d6175e18..9ded23f3e 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -2179,6 +2179,12 @@ view_list_add_subsurface_view(struct weston_compositor *compositor, } } +/* This recursively adds the sub-surfaces for a view, relying on the + * sub-surface order. Thus, if a client restacks the sub-surfaces, that + * change first happens to the sub-surface list, and then automatically + * propagates here. See weston_surface_damage_subsurfaces() for how the + * sub-surfaces receive damage when the client changes the state. + */ static void view_list_add(struct weston_compositor *compositor, struct weston_view *view) @@ -2682,6 +2688,24 @@ surface_set_input_region(struct wl_client *client, } } +/* Cause damage to this sub-surface and all its children. + * + * This is useful when there are state changes that need an implicit + * damage, e.g. a z-order change. + */ +static void +weston_surface_damage_subsurfaces(struct weston_subsurface *sub) +{ + struct weston_subsurface *child; + + weston_surface_damage(sub->surface); + sub->reordered = false; + + wl_list_for_each(child, &sub->surface->subsurface_list, parent_link) + if (child != sub) + weston_surface_damage_subsurfaces(child); +} + static void weston_surface_commit_subsurface_order(struct weston_surface *surface) { @@ -2691,6 +2715,9 @@ weston_surface_commit_subsurface_order(struct weston_surface *surface) parent_link_pending) { wl_list_remove(&sub->parent_link); wl_list_insert(&surface->subsurface_list, &sub->parent_link); + + if (sub->reordered) + weston_surface_damage_subsurfaces(sub); } } @@ -3640,6 +3667,8 @@ subsurface_place_above(struct wl_client *client, wl_list_remove(&sub->parent_link_pending); wl_list_insert(sibling->parent_link_pending.prev, &sub->parent_link_pending); + + sub->reordered = true; } static void @@ -3662,6 +3691,8 @@ subsurface_place_below(struct wl_client *client, wl_list_remove(&sub->parent_link_pending); wl_list_insert(&sibling->parent_link_pending, &sub->parent_link_pending); + + sub->reordered = true; } static void diff --git a/libweston/compositor.h b/libweston/compositor.h index b049c9801..08e728a94 100644 --- a/libweston/compositor.h +++ b/libweston/compositor.h @@ -1235,6 +1235,9 @@ struct weston_subsurface { struct weston_surface_state cached; struct weston_buffer_reference cached_buffer_ref; + /* Sub-surface has been reordered; need to apply damage. */ + bool reordered; + int synchronized; /* Used for constructing the view tree */ diff --git a/tests/subsurface-shot-test.c b/tests/subsurface-shot-test.c index 8e4f7c19b..10415ec76 100644 --- a/tests/subsurface-shot-test.c +++ b/tests/subsurface-shot-test.c @@ -174,7 +174,7 @@ surface_commit_color(struct client *client, struct wl_surface *surface, return buf; } -FAIL_TEST(subsurface_z_order) +TEST(subsurface_z_order) { const char *test_name = get_test_name(); struct client *client;