From 033c9cab74801db9ad1165cbdfc4c4c63cb40dda Mon Sep 17 00:00:00 2001 From: Tudor Brindus Date: Thu, 5 Aug 2021 09:15:49 -0400 Subject: [PATCH] input/pointer: try harder to not send duplicate motion events wl_fixed_t is a 32-bit data type, but our doubles are 64-bit. This meant that two doubles that would map to the same wl_fixed_t could compare unequal, and send a duplicate motion event. Refs swaywm/sway#4632. --- types/seat/wlr_seat_pointer.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/types/seat/wlr_seat_pointer.c b/types/seat/wlr_seat_pointer.c index c93df4cb..27ece5e8 100644 --- a/types/seat/wlr_seat_pointer.c +++ b/types/seat/wlr_seat_pointer.c @@ -230,18 +230,21 @@ void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time, return; } - if (wlr_seat->pointer_state.sx == sx && wlr_seat->pointer_state.sy == sy) { - return; - } + // Ensure we don't send duplicate motion events. Instead of comparing with an + // epsilon, chop off some precision by converting to a `wl_fixed_t` first, + // since that is what a client receives. + wl_fixed_t sx_fixed = wl_fixed_from_double(sx); + wl_fixed_t sy_fixed = wl_fixed_from_double(sy); + if (wl_fixed_from_double(wlr_seat->pointer_state.sx) != sx_fixed || + wl_fixed_from_double(wlr_seat->pointer_state.sy) != sy_fixed) { + struct wl_resource *resource; + wl_resource_for_each(resource, &client->pointers) { + if (wlr_seat_client_from_pointer_resource(resource) == NULL) { + continue; + } - struct wl_resource *resource; - wl_resource_for_each(resource, &client->pointers) { - if (wlr_seat_client_from_pointer_resource(resource) == NULL) { - continue; + wl_pointer_send_motion(resource, time, sx_fixed, sy_fixed); } - - wl_pointer_send_motion(resource, time, wl_fixed_from_double(sx), - wl_fixed_from_double(sy)); } wlr_seat_pointer_warp(wlr_seat, sx, sy);