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 {