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 }