[PATCH weston] compositor: add a layer clipping mechanism

Giulio Camuffo giuliocamuffo at gmail.com
Sat Aug 10 14:13:34 PDT 2013


this adds a mechanism to clip the surfaces belonging to a layer
to an arbitrary rect
---

This is a rebase and v2 of 
http://lists.freedesktop.org/archives/wayland-devel/2013-April/008548.html

I'm using this functionality in my shell plugin 
(https://github.com/giucam/orbital/tree/workspaces) to implement workspaces.
See http://www.youtube.com/watch?v=_o-sKdyUPO8 for a screencast.
As you see there i need to be able to show all the windows of all the
workspaces, but clipped to their workspace, so they don't stick out over
neighbour ones. So simply showing/hiding layers does not work.

 src/compositor.c | 32 ++++++++++++++++++++++++++++++--
 src/compositor.h |  8 ++++++++
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 3213a7b..c1034df 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -945,10 +945,16 @@ weston_compositor_pick_surface(struct weston_compositor *compositor,
 			       wl_fixed_t *sx, wl_fixed_t *sy)
 {
 	struct weston_surface *surface;
+	int ix = wl_fixed_to_int(x);
+	int iy = wl_fixed_to_int(y);
 
 	wl_list_for_each(surface, &compositor->surface_list, link) {
 		weston_surface_from_global_fixed(surface, x, y, sx, sy);
-		if (pixman_region32_contains_point(&surface->input,
+
+
+		if (pixman_region32_contains_point(&surface->layer->mask,
+						   ix, iy, NULL) &&
+			pixman_region32_contains_point(&surface->input,
 						   wl_fixed_to_int(*sx),
 						   wl_fixed_to_int(*sy),
 						   NULL))
@@ -1196,7 +1202,15 @@ surface_accumulate_damage(struct weston_surface *surface,
 	pixman_region32_union(&surface->plane->damage,
 			      &surface->plane->damage, &surface->damage);
 	empty_region(&surface->damage);
-	pixman_region32_copy(&surface->clip, opaque);
+
+	/* set surface->clip with the part of surface->transform.boundingbox
+	 * that doesn't fit into surface->layer->mask, then add the opaque region
+	 * to it. We don't do the opposite, adding surface->clip to opaque,
+	 * because opaque is then passed to the next surfaces, which may be
+	 * in a different layer with a different mask.
+	 */
+	pixman_region32_subtract(&surface->clip, &surface->transform.boundingbox, &surface->layer->mask);
+	pixman_region32_union(&surface->clip, &surface->clip, opaque);
 	pixman_region32_union(opaque, opaque, &surface->transform.opaque);
 }
 
@@ -1276,6 +1290,7 @@ weston_compositor_build_surface_list(struct weston_compositor *compositor)
 	wl_list_init(&compositor->surface_list);
 	wl_list_for_each(layer, &compositor->layer_list, link) {
 		wl_list_for_each(surface, &layer->surface_list, layer_link) {
+			surface->layer = layer;
 			surface_list_add(compositor, surface);
 		}
 	}
@@ -1386,11 +1401,24 @@ WL_EXPORT void
 weston_layer_init(struct weston_layer *layer, struct wl_list *below)
 {
 	wl_list_init(&layer->surface_list);
+	region_init_infinite(&layer->mask);
 	if (below != NULL)
 		wl_list_insert(below, &layer->link);
 }
 
 WL_EXPORT void
+weston_layer_set_mask(struct weston_layer *layer, int x, int y, int width, int height)
+{
+	pixman_region32_init_rect(&layer->mask, x, y, width, height);
+}
+
+WL_EXPORT void
+weston_layer_set_mask_infinite(struct weston_layer *layer)
+{
+    region_init_infinite(&layer->mask);
+}
+
+WL_EXPORT void
 weston_output_schedule_repaint(struct weston_output *output)
 {
 	struct weston_compositor *compositor = output->compositor;
diff --git a/src/compositor.h b/src/compositor.h
index 7600ce3..f7553b3 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -489,6 +489,7 @@ enum {
 struct weston_layer {
 	struct wl_list surface_list;
 	struct wl_list link;
+	pixman_region32_t mask;
 };
 
 struct weston_plane {
@@ -709,6 +710,7 @@ struct weston_surface {
 	struct wl_list layer_link;
 	float alpha;                     /* part of geometry, see below */
 	struct weston_plane *plane;
+	struct weston_layer *layer;
 
 	void *renderer_state;
 
@@ -909,6 +911,12 @@ void
 weston_layer_init(struct weston_layer *layer, struct wl_list *below);
 
 void
+weston_layer_set_mask(struct weston_layer *layer, int x, int y, int width, int height);
+
+void
+weston_layer_set_mask_infinite(struct weston_layer *layer);
+
+void
 weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y);
 void
 weston_plane_release(struct weston_plane *plane);
-- 
1.8.3.4



More information about the wayland-devel mailing list