commit 5b23c48

shrub  ·  2026-04-26 13:18:13 +0000 UTC
parent cc19cf9
decor, the easy part
4 files changed,  +95, -7
+65, -6
  1@@ -331,6 +331,30 @@ repaint_view(struct target *target, struct compositor_view *view,
  2 	pixman_region32_fini(&in_rect);
  3 	pixman_region32_fini(&out_border);
  4 	pixman_region32_fini(&in_border);
  5+
  6+	if ((view->decor.top || view->decor.right || view->decor.bottom ||
  7+	     view->decor.left)) {
  8+		pixman_region32_t decor_region, content_region;
  9+		int32_t x = geom->x - (int32_t)view->decor.left;
 10+		int32_t y = geom->y - (int32_t)view->decor.top;
 11+		uint32_t width = geom->width + view->decor.left + view->decor.right;
 12+		uint32_t height = geom->height + view->decor.top + view->decor.bottom;
 13+
 14+		pixman_region32_init_rect(&decor_region, x, y, width, height);
 15+		pixman_region32_init_rect(&content_region, geom->x, geom->y,
 16+		                          geom->width, geom->height);
 17+		pixman_region32_subtract(&decor_region, &decor_region, &content_region);
 18+		pixman_region32_intersect(&decor_region, &decor_region, damage);
 19+		pixman_region32_subtract(&decor_region, &decor_region, &view->clip);
 20+		if (pixman_region32_not_empty(&decor_region)) {
 21+			pixman_region32_translate(&decor_region, -target_geom->x,
 22+			                          -target_geom->y);
 23+			wld_fill_region(swc.drm->renderer, view->decor.color,
 24+			                &decor_region);
 25+		}
 26+		pixman_region32_fini(&decor_region);
 27+		pixman_region32_fini(&content_region);
 28+	}
 29 }
 30 
 31 static void
 32@@ -526,6 +550,10 @@ update_extents(struct compositor_view *view)
 33 	int64_t border_y1 = geom_y - total_border;
 34 	int64_t border_x2 = geom_x + geom_w + total_border;
 35 	int64_t border_y2 = geom_y + geom_h + total_border;
 36+	int64_t decor_x1 = geom_x - (int64_t)view->decor.left;
 37+	int64_t decor_y1 = geom_y - (int64_t)view->decor.top;
 38+	int64_t decor_x2 = geom_x + geom_w + (int64_t)view->decor.right;
 39+	int64_t decor_y2 = geom_y + geom_h + (int64_t)view->decor.bottom;
 40 
 41 	int64_t buffer_x1 = geom_x - view->buffer_offset_x;
 42 	int64_t buffer_y1 = geom_y - view->buffer_offset_y;
 43@@ -536,10 +564,10 @@ update_extents(struct compositor_view *view)
 44 	    buffer_y1 +
 45 	    (view->base.buffer ? view->base.buffer->height : (uint32_t)geom_h);
 46 
 47-	view->extents.x1 = clamp_i32(MIN(border_x1, buffer_x1));
 48-	view->extents.y1 = clamp_i32(MIN(border_y1, buffer_y1));
 49-	view->extents.x2 = clamp_i32(MAX(border_x2, buffer_x2));
 50-	view->extents.y2 = clamp_i32(MAX(border_y2, buffer_y2));
 51+	view->extents.x1 = clamp_i32(MIN(MIN(border_x1, decor_x1), buffer_x1));
 52+	view->extents.y1 = clamp_i32(MIN(MIN(border_y1, decor_y1), buffer_y1));
 53+	view->extents.x2 = clamp_i32(MAX(MAX(border_x2, decor_x2), buffer_x2));
 54+	view->extents.y2 = clamp_i32(MAX(MAX(border_y2, decor_y2), buffer_y2));
 55 
 56 	if (view->extents.x2 < view->extents.x1) {
 57 		view->extents.x2 = view->extents.x1;
 58@@ -551,6 +579,7 @@ update_extents(struct compositor_view *view)
 59 	/* Damage border. */
 60 	view->border.damaged_border1 = true;
 61 	view->border.damaged_border2 = true;
 62+	view->decor.damaged = true;
 63 }
 64 
 65 static void
 66@@ -1266,6 +1295,12 @@ compositor_create_view(struct surface *surface)
 67 	view->border.inwidth = 0;
 68 	view->border.incolor = 0x000000;
 69 	view->border.damaged_border2 = false;
 70+	view->decor.color = 0x000000;
 71+	view->decor.top = 0;
 72+	view->decor.right = 0;
 73+	view->decor.bottom = 0;
 74+	view->decor.left = 0;
 75+	view->decor.damaged = false;
 76 	pixman_region32_init(&view->clip);
 77 	wl_signal_init(&view->destroy_signal);
 78 	surface_set_view(surface, &view->base);
 79@@ -1431,6 +1466,28 @@ compositor_view_set_border_color(struct compositor_view *view,
 80 	update(&view->base);
 81 }
 82 
 83+void
 84+compositor_view_set_decor(struct compositor_view *view, uint32_t color,
 85+                          uint32_t top, uint32_t right, uint32_t bottom,
 86+                          uint32_t left)
 87+{
 88+	if (view->decor.color == color && view->decor.top == top &&
 89+	    view->decor.right == right && view->decor.bottom == bottom &&
 90+	    view->decor.left == left) {
 91+		return;
 92+	}
 93+
 94+	view->decor.color = color;
 95+	view->decor.top = top;
 96+	view->decor.right = right;
 97+	view->decor.bottom = bottom;
 98+	view->decor.left = left;
 99+	view->decor.damaged = true;
100+
101+	update_extents(view);
102+	update(&view->base);
103+}
104+
105 /* }}} */
106 
107 static void
108@@ -1487,8 +1544,9 @@ calculate_damage(void)
109 			pixman_region32_clear(surface_damage);
110 		}
111 
112-		/* redraw entire thingy if either */
113-		if (view->border.damaged_border1 || view->border.damaged_border2) {
114+		/* redraw entire thingy if border or decor changed */
115+		if (view->border.damaged_border1 || view->border.damaged_border2 ||
116+		    view->decor.damaged) {
117 			pixman_region32_t border_region;
118 
119 			pixman_region32_init_with_extents(&border_region, &view->extents);
120@@ -1503,6 +1561,7 @@ calculate_damage(void)
121 
122 			view->border.damaged_border1 = false;
123 			view->border.damaged_border2 = false;
124+			view->decor.damaged = false;
125 		}
126 
127 		pixman_region32_fini(&view_region);
+10, -0
 1@@ -88,6 +88,12 @@ struct compositor_view {
 2 		bool damaged_border2;
 3 	} border;
 4 
 5+	struct {
 6+		uint32_t color;
 7+		uint32_t top, right, bottom, left;
 8+		bool damaged;
 9+	} decor;
10+
11 	struct wl_list link;
12 	struct wl_signal destroy_signal;
13 };
14@@ -122,6 +128,10 @@ compositor_view_set_border_color(struct compositor_view *view,
15 void
16 compositor_view_set_border_width(struct compositor_view *view,
17                                  uint32_t outwidth, uint32_t inwidth);
18+void
19+compositor_view_set_decor(struct compositor_view *view, uint32_t color,
20+                          uint32_t top, uint32_t right, uint32_t bottom,
21+                          uint32_t left);
22 
23 /**
24  * get the current composited buffer for a screen for screenshotss.
+10, -0
 1@@ -390,6 +390,16 @@ swc_window_set_border(struct swc_window *window, uint32_t inner_border_color,
 2                       uint32_t inner_border_width, uint32_t outer_border_color,
 3                       uint32_t outer_border_width);
 4 
 5+/**
 6+ * Set decor around the window content
 7+ *
 8+ * the dimensions are independent for each edge and extend outward from the
 9+ * window content geometry. passing all dimensions as 0 disables this decor.
10+ */
11+void
12+swc_window_set_decor(struct swc_window *window, uint32_t color, uint32_t top,
13+                     uint32_t right, uint32_t bottom, uint32_t left);
14+
15 /**
16  * Begin an interactive move of the specified window.
17  */
+10, -1
 1@@ -367,6 +367,15 @@ swc_window_set_border(struct swc_window *window, uint32_t inner_border_color,
 2 	                                 inner_border_width);
 3 }
 4 
 5+EXPORT void
 6+swc_window_set_decor(struct swc_window *window, uint32_t color, uint32_t top,
 7+                     uint32_t right, uint32_t bottom, uint32_t left)
 8+{
 9+	struct compositor_view *view = INTERNAL(window)->view;
10+
11+	compositor_view_set_decor(view, color, top, right, bottom, left);
12+}
13+
14 EXPORT void
15 swc_window_begin_move(struct swc_window *window)
16 {
17@@ -541,7 +550,7 @@ window_initialize(struct window *window, const struct window_impl *impl,
18 	window->resize.interaction.active = false;
19 	window->resize.interaction.handler = (struct pointer_handler){
20 	    .motion = resize_motion,
21-	    .button = handle_button,
22+		.button = handle_button,
23 	};
24 	window->resize.last_time = 0;
25