commit 1ca2f8f
uint
·
2026-02-15 12:40:13 +0000 UTC
parent 736088f
add motion throttle fixes random crashes from overloading the server with events. window managers are unaffected as there is a def_motion_throttle_ms=60 and should even fix some
3 files changed,
+30,
-0
+1,
-0
1@@ -249,6 +249,7 @@ struct swc_window {
2 char *app_id;
3
4 struct swc_window *parent;
5+ uint32_t motion_throttle_ms;
6 };
7
8 /**
+27,
-0
1@@ -38,8 +38,23 @@
2
3 #define INTERNAL(w) ((struct window *)(w))
4
5+static const uint32_t def_motion_throttle_ms = 16;
6+
7 static const struct swc_window_handler null_handler;
8
9+static bool
10+should_throttle_motion(uint32_t throttle_ms, uint32_t *last_time, uint32_t time)
11+{
12+ if (!throttle_ms)
13+ return false;
14+
15+ if (*last_time && time - *last_time < throttle_ms)
16+ return true;
17+
18+ *last_time = time;
19+ return false;
20+}
21+
22 static void
23 handle_window_enter(struct wl_listener *listener, void *data)
24 {
25@@ -313,6 +328,10 @@ static bool
26 move_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t fx, wl_fixed_t fy)
27 {
28 struct window *window = wl_container_of(handler, window, move.interaction.handler);
29+
30+ if (should_throttle_motion(window->base.motion_throttle_ms, &window->move.last_time, time))
31+ return true;
32+
33 int32_t x = wl_fixed_to_int(fx) + window->move.offset.x,
34 y = wl_fixed_to_int(fy) + window->move.offset.y;
35
36@@ -327,6 +346,9 @@ resize_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t fx, wl_
37 const struct swc_rectangle *geometry = &window->view->base.geometry;
38 uint32_t width = geometry->width, height = geometry->height;
39
40+ if (should_throttle_motion(window->base.motion_throttle_ms, &window->resize.last_time, time))
41+ return true;
42+
43 if (window->resize.edges & SWC_WINDOW_EDGE_LEFT)
44 width -= wl_fixed_to_int(fx) + window->resize.offset.x - geometry->x;
45 else if (window->resize.edges & SWC_WINDOW_EDGE_RIGHT)
46@@ -409,9 +431,11 @@ window_initialize(struct window *window, const struct window_impl *impl, struct
47 window->handler = &null_handler;
48 window->view_handler.impl = &view_handler_impl;
49 window->view->window = window;
50+ window->base.motion_throttle_ms = def_motion_throttle_ms;
51 window->managed = false;
52 window->mode = WINDOW_MODE_STACKED;
53 window->move.pending = false;
54+ window->move.last_time = 0;
55 window->move.interaction.active = false;
56 window->move.interaction.handler = (struct pointer_handler){
57 .motion = move_motion,
58@@ -425,6 +449,7 @@ window_initialize(struct window *window, const struct window_impl *impl, struct
59 .motion = resize_motion,
60 .button = handle_button,
61 };
62+ window->resize.last_time = 0;
63
64 wl_list_insert(&window->view->base.handlers, &window->view_handler.link);
65
66@@ -511,6 +536,7 @@ window_begin_move(struct window *window, struct button *button)
67 py = wl_fixed_to_int(swc.seat->pointer->y);
68
69 begin_interaction(&window->move.interaction, button);
70+ window->move.last_time = 0;
71 window->move.offset.x = geometry->x - px;
72 window->move.offset.y = geometry->y - py;
73 }
74@@ -529,6 +555,7 @@ window_begin_resize(struct window *window, uint32_t edges, struct button *button
75 py = wl_fixed_to_int(swc.seat->pointer->y);
76
77 begin_interaction(&window->resize.interaction, button);
78+ window->resize.last_time = 0;
79
80 if (!edges) {
81 edges |= (px < geometry->x + geometry->width / 2) ? SWC_WINDOW_EDGE_LEFT : SWC_WINDOW_EDGE_RIGHT;
+2,
-0
1@@ -66,6 +66,7 @@ struct window {
2
3 bool pending;
4 int32_t x, y;
5+ uint32_t last_time;
6 } move;
7
8 struct {
9@@ -74,6 +75,7 @@ struct window {
10 int32_t x, y;
11 } offset;
12 uint32_t edges;
13+ uint32_t last_time;
14 } resize;
15
16 struct {