commit b8d53ba
dalem
·
2025-12-16 01:01:10 +0000 UTC
parent 29d45ba
add support for inner and outer window borders, lovingly known as 'double borders'
4 files changed,
+83,
-36
+63,
-27
1@@ -212,15 +212,38 @@ repaint_view(struct target *target, struct compositor_view *view, pixman_region3
2 wld_copy_region(swc.drm->renderer, view->buffer, geom->x - target_geom->x, geom->y - target_geom->y, &view_damage);
3 }
4
5- pixman_region32_fini(&view_damage);
6+ pixman_region32_t in_rect;
7+ pixman_region32_init_rect(&in_rect,
8+ geom->x - view->border.inwidth,
9+ geom->y - view->border.inwidth,
10+ geom->width + (2 * view->border.inwidth),
11+ geom->height + (2 * view->border.inwidth));
12+
13+ pixman_region32_t out_border;
14+ pixman_region32_init(&out_border);
15+ pixman_region32_subtract(&out_border, &border_damage, &in_rect);
16+
17+ pixman_region32_t in_border;
18+ pixman_region32_init(&in_border);
19+ pixman_region32_subtract(&in_border, &in_rect, &view_region);
20+
21
22 /* Draw border */
23- if (pixman_region32_not_empty(&border_damage)) {
24- pixman_region32_translate(&border_damage, -target_geom->x, -target_geom->y);
25- wld_fill_region(swc.drm->renderer, view->border.color, &border_damage);
26+ if (view->border.outwidth > 0 && pixman_region32_not_empty(&out_border)) {
27+ pixman_region32_translate(&out_border, -target_geom->x, -target_geom->y);
28+ wld_fill_region(swc.drm->renderer, view->border.outcolor, &out_border);
29+ }
30+
31+ if (view->border.inwidth > 0 && pixman_region32_not_empty(&in_border)) {
32+ pixman_region32_translate(&in_border, -target_geom->x, -target_geom->y);
33+ wld_fill_region(swc.drm->renderer, view->border.incolor, &in_border);
34 }
35
36 pixman_region32_fini(&border_damage);
37+ pixman_region32_fini(&in_rect);
38+ pixman_region32_fini(&out_border);
39+ pixman_region32_fini(&in_border);
40+
41 }
42
43 static void
44@@ -361,21 +384,26 @@ static void
45 damage_view(struct compositor_view *view)
46 {
47 damage_below_view(view);
48- view->border.damaged = true;
49-}
50+ view->border.damaged_border1 = true;
51+ view->border.damaged_border2 = true;
52
53+}
54 static void
55 update_extents(struct compositor_view *view)
56 {
57- view->extents.x1 = view->base.geometry.x - view->border.width;
58- view->extents.y1 = view->base.geometry.y - view->border.width;
59- view->extents.x2 = view->base.geometry.x + view->base.geometry.width + view->border.width;
60- view->extents.y2 = view->base.geometry.y + view->base.geometry.height + view->border.width;
61+ uint32_t total_border = view->border.outwidth + view->border.inwidth;
62+
63+ view->extents.x1 = view->base.geometry.x - total_border;
64+ view->extents.y1 = view->base.geometry.y - total_border;
65+ view->extents.x2 = view->base.geometry.x + view->base.geometry.width + total_border;
66+ view->extents.y2 = view->base.geometry.y + view->base.geometry.height + total_border;
67
68 /* Damage border. */
69- view->border.damaged = true;
70+ view->border.damaged_border1 = true;
71+ view->border.damaged_border2 = true;
72 }
73
74+
75 static void
76 schedule_updates(uint32_t screens)
77 {
78@@ -590,7 +618,7 @@ raise_window(struct compositor_view *view)
79 wl_list_remove(&view->link);
80 wl_list_insert(insert_after, &view->link);
81
82- view->border.damaged = true;
83+ view->border.damaged_border1 = true;
84 pixman_region32_union_rect(&compositor.damage, &compositor.damage,
85 view->extents.x1, view->extents.y1,
86 (uint32_t)(view->extents.x2 - view->extents.x1),
87@@ -626,9 +654,12 @@ compositor_create_view(struct surface *surface)
88 view->extents.y1 = 0;
89 view->extents.x2 = 0;
90 view->extents.y2 = 0;
91- view->border.width = 0;
92- view->border.color = 0x000000;
93- view->border.damaged = false;
94+ view->border.outwidth = 0;
95+ view->border.outcolor = 0x000000;
96+ view->border.damaged_border1 = false;
97+ view->border.inwidth = 0;
98+ view->border.incolor = 0x000000;
99+ view->border.damaged_border2 = false;
100 pixman_region32_init(&view->clip);
101 wl_signal_init(&view->destroy_signal);
102 surface_set_view(surface, &view->base);
103@@ -711,13 +742,16 @@ compositor_view_hide(struct compositor_view *view)
104 }
105
106 void
107-compositor_view_set_border_width(struct compositor_view *view, uint32_t width)
108+compositor_view_set_border_width(struct compositor_view *view, uint32_t outwidth, uint32_t inwidth)
109 {
110- if (view->border.width == width)
111+ if (view->border.outwidth == outwidth && view->border.inwidth == inwidth)
112 return;
113
114- view->border.width = width;
115- view->border.damaged = true;
116+ view->border.outwidth = outwidth;
117+ view->border.damaged_border1 = true;
118+
119+ view->border.inwidth = inwidth;
120+ view->border.damaged_border2 = true;
121
122 /* XXX: Damage above surface for transparent surfaces? */
123
124@@ -726,19 +760,22 @@ compositor_view_set_border_width(struct compositor_view *view, uint32_t width)
125 }
126
127 void
128-compositor_view_set_border_color(struct compositor_view *view, uint32_t color)
129+compositor_view_set_border_color(struct compositor_view *view, uint32_t outcolor, uint32_t incolor)
130 {
131- if (view->border.color == color)
132+ if (view->border.outcolor == outcolor && view->border.incolor == incolor)
133 return;
134
135- view->border.color = color;
136- view->border.damaged = true;
137+ view->border.outcolor = outcolor;
138+ view->border.damaged_border1 = true;
139+
140+ view->border.incolor = incolor;
141+ view->border.damaged_border2 = true;
142+
143
144 /* XXX: Damage above surface for transparent surfaces? */
145
146 update(&view->base);
147 }
148-
149 /* }}} */
150
151 static void
152@@ -781,7 +818,8 @@ calculate_damage(void)
153 pixman_region32_clear(surface_damage);
154 }
155
156- if (view->border.damaged) {
157+ /* redraw entire thingy if either */
158+ if (view->border.damaged_border1 || view->border.damaged_border2) {
159 pixman_region32_t border_region, view_region;
160
161 pixman_region32_init_with_extents(&border_region, &view->extents);
162@@ -793,8 +831,6 @@ calculate_damage(void)
163
164 pixman_region32_fini(&border_region);
165 pixman_region32_fini(&view_region);
166-
167- view->border.damaged = false;
168 }
169 }
170
+12,
-5
1@@ -64,9 +64,16 @@ struct compositor_view {
2 pixman_region32_t clip;
3
4 struct {
5- uint32_t width;
6- uint32_t color;
7- bool damaged;
8+ uint32_t outwidth;
9+ uint32_t outcolor;
10+
11+ bool damaged_border1;
12+
13+ /* sir, a second border has hit the compositor! */
14+ uint32_t inwidth;
15+ uint32_t incolor;
16+
17+ bool damaged_border2;
18 } border;
19
20 struct wl_list link;
21@@ -87,7 +94,7 @@ void compositor_view_set_parent(struct compositor_view *view, struct compositor_
22 void compositor_view_show(struct compositor_view *view);
23 void compositor_view_hide(struct compositor_view *view);
24
25-void compositor_view_set_border_color(struct compositor_view *view, uint32_t color);
26-void compositor_view_set_border_width(struct compositor_view *view, uint32_t width);
27+void compositor_view_set_border_color(struct compositor_view *view, uint32_t outcolor, uint32_t incolor);
28+void compositor_view_set_border_width(struct compositor_view *view, uint32_t outwidth, uint32_t inwidth);
29
30 #endif
+3,
-1
1@@ -267,8 +267,10 @@ void swc_window_set_geometry(struct swc_window *window, const struct swc_rectang
2 *
3 * NOTE: The window's geometry remains unchanged, and should be updated if a
4 * fixed top-left corner of the border is desired.
5+ *
6+ * info from dalem: unsure how much double borders break!
7 */
8-void swc_window_set_border(struct swc_window *window, uint32_t color, uint32_t width);
9+void swc_window_set_border(struct swc_window *window, uint32_t inner_border_color, uint32_t inner_border_width, uint32_t outer_border_color, uint32_t outer_border_width);
10
11 /**
12 * Begin an interactive move of the specified window.
+5,
-3
1@@ -249,14 +249,16 @@ swc_window_set_geometry(struct swc_window *window, const struct swc_rectangle *g
2 }
3
4 EXPORT void
5-swc_window_set_border(struct swc_window *window, uint32_t border_color, uint32_t border_width)
6+swc_window_set_border(struct swc_window *window, uint32_t inner_border_color, uint32_t inner_border_width,
7+ uint32_t outer_border_color, uint32_t outer_border_width)
8 {
9 struct compositor_view *view = INTERNAL(window)->view;
10
11- compositor_view_set_border_color(view, border_color);
12- compositor_view_set_border_width(view, border_width);
13+ compositor_view_set_border_color(view, outer_border_color, inner_border_color);
14+ compositor_view_set_border_width(view, outer_border_width, inner_border_width);
15 }
16
17+
18 EXPORT void
19 swc_window_begin_move(struct swc_window *window)
20 {