commit 6570f7b

shrub  ·  2025-12-16 02:28:16 +0000 UTC
parent fc92a02
various fixes:
- fix how border damage is calculated
- ignore null axis handlers
2 files changed,  +71, -30
+5, -3
 1@@ -134,9 +134,10 @@ static bool
 2 handle_binding(uint32_t time, struct press *press, uint32_t state, struct binding *(*find_binding)(uint32_t, uint32_t))
 3 {
 4 	struct binding *binding;
 5+	uint32_t modifiers = swc.seat && swc.seat->keyboard ? swc.seat->keyboard->modifiers : 0;
 6 
 7 	if (state) {
 8-		binding = find_binding(swc.seat->keyboard->modifiers, press->value);
 9+		binding = find_binding(modifiers, press->value);
10 
11 		if (!binding)
12 			return false;
13@@ -170,10 +171,11 @@ handle_axis(struct pointer_handler *handler, uint32_t time, enum wl_pointer_axis
14 	(void)handler;
15 	(void)source;
16 
17-	struct axis_binding *binding = find_axis_binding(swc.seat->keyboard->modifiers, axis);
18+	uint32_t modifiers = swc.seat && swc.seat->keyboard ? swc.seat->keyboard->modifiers : 0;
19+	struct axis_binding *binding = find_axis_binding(modifiers, axis);
20 	int32_t delta120 = value120;
21 
22-	if (!binding)
23+	if (!binding || !binding->handler)
24 		return false;
25 
26 	if (!delta120 && value) {
+66, -27
  1@@ -49,10 +49,33 @@
  2 #include <stdlib.h>
  3 #include <stdio.h>
  4 #include <assert.h>
  5+#include <limits.h>
  6 #include <wld/wld.h>
  7 #include <wld/drm.h>
  8 #include <xkbcommon/xkbcommon-keysyms.h>
  9 
 10+static inline int32_t
 11+clamp_i32(int64_t v)
 12+{
 13+	if (v > INT32_MAX)
 14+		return INT32_MAX;
 15+	if (v < INT32_MIN)
 16+		return INT32_MIN;
 17+	return (int32_t)v;
 18+}
 19+
 20+static inline uint32_t
 21+span_u32(int32_t a, int32_t b)
 22+{
 23+	int64_t d = (int64_t)b - (int64_t)a;
 24+
 25+	if (d <= 0)
 26+		return 0;
 27+	if (d > UINT32_MAX)
 28+		return UINT32_MAX;
 29+	return (uint32_t)d;
 30+}
 31+
 32 struct target {
 33 	struct wld_surface *surface;
 34 	struct wld_buffer *next_buffer, *current_buffer;
 35@@ -205,13 +228,13 @@ repaint_view(struct target *target, struct compositor_view *view, pixman_region3
 36 	pixman_region32_subtract(&border_damage, &view_damage, &view_region);
 37 	pixman_region32_intersect(&view_damage, &view_damage, &view_region);
 38 
 39-	pixman_region32_fini(&view_region);
 40-
 41 	if (pixman_region32_not_empty(&view_damage)) {
 42 		pixman_region32_translate(&view_damage, -geom->x, -geom->y);
 43 		wld_copy_region(swc.drm->renderer, view->buffer, geom->x - target_geom->x, geom->y - target_geom->y, &view_damage);
 44 	}
 45 
 46+	pixman_region32_fini(&view_damage);
 47+
 48 	pixman_region32_t in_rect;
 49 	pixman_region32_init_rect(&in_rect, 
 50 			geom->x - view->border.inwidth, 
 51@@ -226,7 +249,9 @@ repaint_view(struct target *target, struct compositor_view *view, pixman_region3
 52 	pixman_region32_t in_border;
 53 	pixman_region32_init(&in_border);
 54 	pixman_region32_subtract(&in_border, &in_rect, &view_region);
 55+	pixman_region32_intersect(&in_border, &in_border, &border_damage);
 56 		
 57+	pixman_region32_fini(&view_region);
 58 
 59 	/* Draw border */
 60 	if (view->border.outwidth > 0 && pixman_region32_not_empty(&out_border)) {
 61@@ -386,17 +411,26 @@ damage_view(struct compositor_view *view)
 62 	damage_below_view(view);
 63 	view->border.damaged_border1 = true;
 64 	view->border.damaged_border2 = true;
 65-
 66 }
 67+
 68 static void
 69 update_extents(struct compositor_view *view)
 70 {
 71-	uint32_t total_border = view->border.outwidth + view->border.inwidth;
 72-
 73-	view->extents.x1 = view->base.geometry.x - total_border;
 74-	view->extents.y1 = view->base.geometry.y - total_border;
 75-	view->extents.x2 = view->base.geometry.x + view->base.geometry.width + total_border;
 76-	view->extents.y2 = view->base.geometry.y + view->base.geometry.height + total_border;
 77+	int64_t total_border = (int64_t)view->border.outwidth + (int64_t)view->border.inwidth;
 78+	int64_t x = view->base.geometry.x;
 79+	int64_t y = view->base.geometry.y;
 80+	int64_t w = view->base.geometry.width;
 81+	int64_t h = view->base.geometry.height;
 82+
 83+	view->extents.x1 = clamp_i32(x - total_border);
 84+	view->extents.y1 = clamp_i32(y - total_border);
 85+	view->extents.x2 = clamp_i32(x + w + total_border);
 86+	view->extents.y2 = clamp_i32(y + h + total_border);
 87+
 88+	if (view->extents.x2 < view->extents.x1)
 89+		view->extents.x2 = view->extents.x1;
 90+	if (view->extents.y2 < view->extents.y1)
 91+		view->extents.y2 = view->extents.y1;
 92 
 93 	/* Damage border. */
 94 	view->border.damaged_border1 = true;
 95@@ -621,8 +655,8 @@ raise_window(struct compositor_view *view)
 96 	view->border.damaged_border1 = true;
 97 	pixman_region32_union_rect(&compositor.damage, &compositor.damage,
 98 	                           view->extents.x1, view->extents.y1,
 99-	                           (uint32_t)(view->extents.x2 - view->extents.x1),
100-	                           (uint32_t)(view->extents.y2 - view->extents.y1));
101+	                           span_u32(view->extents.x1, view->extents.x2),
102+	                           span_u32(view->extents.y1, view->extents.y2));
103 	schedule_updates(screens);
104 }
105 
106@@ -683,18 +717,20 @@ damage_views(struct compositor_view *a, struct compositor_view *b)
107 {
108 	uint32_t screens = a->base.screens | (b ? b->base.screens : 0);
109 
110-	a->border.damaged = true;
111+	a->border.damaged_border1 = true;
112+	a->border.damaged_border2 = true;
113 	pixman_region32_union_rect(&compositor.damage, &compositor.damage,
114 	                           a->extents.x1, a->extents.y1,
115-	                           (uint32_t)(a->extents.x2 - a->extents.x1),
116-	                           (uint32_t)(a->extents.y2 - a->extents.y1));
117+	                           span_u32(a->extents.x1, a->extents.x2),
118+	                           span_u32(a->extents.y1, a->extents.y2));
119 
120 	if (b) {
121-		b->border.damaged = true;
122+		b->border.damaged_border1 = true;
123+		b->border.damaged_border2 = true;
124 		pixman_region32_union_rect(&compositor.damage, &compositor.damage,
125 		                           b->extents.x1, b->extents.y1,
126-		                           (uint32_t)(b->extents.x2 - b->extents.x1),
127-		                           (uint32_t)(b->extents.y2 - b->extents.y1));
128+		                           span_u32(b->extents.x1, b->extents.x2),
129+		                           span_u32(b->extents.y1, b->extents.y2));
130 	}
131 
132 	schedule_updates(screens);
133@@ -910,21 +946,24 @@ calculate_damage(void)
134 			pixman_region32_clear(surface_damage);
135 		}
136 
137-                /* redraw entire thingy if either */
138-		if (view->border.damaged_border1 || view->border.damaged_border2) {
139-			pixman_region32_t border_region, view_region;
140+	                /* redraw entire thingy if either */
141+			if (view->border.damaged_border1 || view->border.damaged_border2) {
142+				pixman_region32_t border_region, view_region;
143+
144+				pixman_region32_init_with_extents(&border_region, &view->extents);
145+				pixman_region32_init_rect(&view_region, geom->x, geom->y, geom->width, geom->height);
146 
147-			pixman_region32_init_with_extents(&border_region, &view->extents);
148-			pixman_region32_init_rect(&view_region, geom->x, geom->y, geom->width, geom->height);
149+				pixman_region32_subtract(&border_region, &border_region, &view_region);
150 
151-			pixman_region32_subtract(&border_region, &border_region, &view_region);
152+				pixman_region32_union(&compositor.damage, &compositor.damage, &border_region);
153 
154-			pixman_region32_union(&compositor.damage, &compositor.damage, &border_region);
155+				pixman_region32_fini(&border_region);
156+				pixman_region32_fini(&view_region);
157 
158-			pixman_region32_fini(&border_region);
159-			pixman_region32_fini(&view_region);
160+				view->border.damaged_border1 = false;
161+				view->border.damaged_border2 = false;
162+			}
163 		}
164-	}
165 
166 	pixman_region32_fini(&surface_opaque);
167 }