Compare configure serials across wraparound
dc74e0b4055325b5c643abce66b391612969f0ba
A resize issued near the end of the Wayland serial range could remain pending after the display counter wrapped to zero. Compare serials by their wrapping difference so acknowledgements after rollover still complete the resize.
1 parent
1fd76d4b
swm.c
+7 -1
| 1164 | 1164 | static inline void client_set_scale(struct wlr_surface *s, float scale) { |
|
| 1165 | 1165 | wlr_fractional_scale_v1_notify_scale(s, scale); |
|
| 1166 | 1166 | wlr_surface_set_preferred_buffer_scale(s, (int32_t)ceilf(scale)); |
|
| 1167 | 1167 | } |
|
| 1168 | 1168 | ||
| 1169 | + | /* Compare Wayland serials while preserving their wraparound ordering. */ |
|
| 1170 | + | static inline bool serial_at_least(uint32_t serial, uint32_t target) { |
|
| 1171 | + | return (int32_t)(serial - target) >= 0; |
|
| 1172 | + | } |
|
| 1173 | + | ||
| 1169 | 1174 | /* Configure the client surface size. */ |
|
| 1170 | 1175 | static inline uint32_t client_set_size(client_t *c, uint32_t width, uint32_t height) { |
|
| 1171 | 1176 | if (client_is_x11(c)) { |
|
| 1172 | 1177 | wlr_xwayland_surface_configure( |
|
| 1173 | 1178 | c->surface.xwayland, c->geom.x + c->bw, c->geom.y + c->bw, width, height |
| 2279 | 2284 | (struct swm_box *)&c->geom, geom.width, geom.height, c->bw, c->resize_edges |
|
| 2280 | 2285 | ); |
|
| 2281 | 2286 | } |
|
| 2282 | 2287 | if (c->resize && c->mon) { |
|
| 2283 | 2288 | uint32_t resize_serial = c->resize; |
|
| 2284 | - | int latest = resize_serial <= c->surface.xdg->current.configure_serial; |
|
| 2289 | + | int latest = |
|
| 2290 | + | serial_at_least(c->surface.xdg->current.configure_serial, resize_serial); |
|
| 2285 | 2291 | ||
| 2286 | 2292 | apply_bounds(c, &c->mon->w); |
|
| 2287 | 2293 | resize_apply(c); |
|
| 2288 | 2294 | ||
| 2289 | 2295 | if (latest) |
test/unit.c
+5 -0
| 543 | 543 | struct wlr_seat fake_seat = {}; |
|
| 544 | 544 | ||
| 545 | 545 | apply_bounds(&client, &bounds); |
|
| 546 | 546 | assert(client.geom.x == 0 && client.geom.y == 55); |
|
| 547 | 547 | assert(client.geom.width == 5 && client.geom.height == 5); |
|
| 548 | + | assert(serial_at_least(10, 10)); |
|
| 549 | + | assert(serial_at_least(11, 10)); |
|
| 550 | + | assert(!serial_at_least(9, 10)); |
|
| 551 | + | assert(serial_at_least(1, UINT32_MAX)); |
|
| 552 | + | assert(!serial_at_least(UINT32_MAX, 1)); |
|
| 548 | 553 | seat = &fake_seat; |
|
| 549 | 554 | assert(shortcuts_inhibited() == 0); |
|
| 550 | 555 | assert(focus_close(nullptr) == nullptr); |
|
| 551 | 556 | slot = pool_take(&static_listener_pool); |
|
| 552 | 557 | assert(slot); |