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