[PATCH v4 0/2] MR11357: winewayland: Some rawinput fixes
The second commit accumulates unaccelerated inputs like we currently do for accelerated inputs, since dx_unaccel uses wl_fixed type the compositor could send 0.375 for example, and we would treat that as zero. The values are typically integers in my experience, but I think it would be good to ensure that we don't drop any valid inputs. -- v4: winewayland: Accumulate unaccelerated motion delta. https://gitlab.winehq.org/wine/wine/-/merge_requests/11357
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_pointer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 0c190a9a48a..7f3124e4bd8 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -362,7 +362,7 @@ static void relative_pointer_v1_relative_motion(void *private, { const POINT raw_pos = { .x = wl_fixed_to_double(dx_unaccel), .y = wl_fixed_to_double(dy_unaccel) }; struct raw_mouse raw = { .count = 1, .data = { raw_pos } }; - INPUT input = { .type = INPUT_MOUSE }; + INPUT input = { .type = INPUT_MOUSE, .mi.dwFlags = MOUSEEVENTF_MOVE }; HWND hwnd; struct wayland_win_data *data; double screen_x = 0.0, screen_y = 0.0; @@ -386,7 +386,6 @@ static void relative_pointer_v1_relative_motion(void *private, input.mi.dx = round(pointer->accum_x); input.mi.dy = round(pointer->accum_y); - input.mi.dwFlags = MOUSEEVENTF_MOVE; pointer->accum_x -= input.mi.dx; pointer->accum_y -= input.mi.dy; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11357
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_pointer.c | 20 ++++++++++++-------- dlls/winewayland.drv/waylanddrv.h | 4 ++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 7f3124e4bd8..1cce6c09727 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -197,6 +197,8 @@ static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, pthread_mutex_lock(&pointer->mutex); pointer->focused_hwnd = hwnd; pointer->enter_serial = serial; + pointer->accum_x = pointer->accum_y = 0; + pointer->accum_raw_x = pointer->accum_raw_y = 0; pthread_mutex_unlock(&pointer->mutex); /* The cursor is undefined at every enter, so we set it again with @@ -360,8 +362,7 @@ static void relative_pointer_v1_relative_motion(void *private, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel) { - const POINT raw_pos = { .x = wl_fixed_to_double(dx_unaccel), .y = wl_fixed_to_double(dy_unaccel) }; - struct raw_mouse raw = { .count = 1, .data = { raw_pos } }; + struct raw_mouse raw = { .count = 1 }; INPUT input = { .type = INPUT_MOUSE, .mi.dwFlags = MOUSEEVENTF_MOVE }; HWND hwnd; struct wayland_win_data *data; @@ -379,23 +380,26 @@ static void relative_pointer_v1_relative_motion(void *private, pthread_mutex_lock(&pointer->mutex); + pointer->accum_raw_x += wl_fixed_to_double(dx_unaccel); + pointer->accum_raw_y += wl_fixed_to_double(dy_unaccel); + + pointer->accum_raw_x -= (raw.data[0].x = round(pointer->accum_raw_x)); + pointer->accum_raw_y -= (raw.data[0].y = round(pointer->accum_raw_y)); + if (pointer->relative_mode) { pointer->accum_x += screen_x; pointer->accum_y += screen_y; - input.mi.dx = round(pointer->accum_x); - input.mi.dy = round(pointer->accum_y); - - pointer->accum_x -= input.mi.dx; - pointer->accum_y -= input.mi.dy; + pointer->accum_x -= (input.mi.dx = round(pointer->accum_x)); + pointer->accum_y -= (input.mi.dy = round(pointer->accum_y)); } pthread_mutex_unlock(&pointer->mutex); TRACE("hwnd=%p wayland_dxdy=%.2f,%.2f accum_dxdy=%d,%d wayland_raw=%.2f,%.2f raw_dxdy=%d,%d\n", hwnd, wl_fixed_to_double(dx), wl_fixed_to_double(dy), input.mi.dx, input.mi.dy, - wl_fixed_to_double(dx_unaccel), wl_fixed_to_double(dy_unaccel), raw_pos.x, raw_pos.y); + wl_fixed_to_double(dx_unaccel), wl_fixed_to_double(dy_unaccel), raw.data[0].x, raw.data[0].y); NtUserSendHardwareInput(hwnd, SEND_HWMSG_RAWINPUT, &input, (LPARAM)&raw); } diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index fa590eecd13..c2630fc89c1 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -118,8 +118,8 @@ struct wayland_pointer uint32_t enter_serial; uint32_t button_serial; struct wayland_cursor cursor; - double accum_x; - double accum_y; + double accum_x; double accum_y; + double accum_raw_x; double accum_raw_y; pthread_mutex_t mutex; }; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11357
The second commit accumulates unaccelerated inputs like we currently do for accelerated inputs, since dx_unaccel uses wl_fixed type the compositor could send 0.375 for example, and we would treat that as zero. The values are typically integers in my experience, but I think it would be good to ensure that we don't drop any valid inputs.
I don't think this is necessary, the raw values should be integer. At most we could have a FIXME in anything has a decimal part just in case. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11357#note_145363
On Fri Jul 10 07:11:36 2026 +0000, Rémi Bernon wrote:
The second commit accumulates unaccelerated inputs like we currently do for accelerated inputs, since dx_unaccel uses wl_fixed type the compositor could send 0.375 for example, and we would treat that as zero. The values are typically integers in my experience, but I think it would be good to ensure that we don't drop any valid inputs. I don't think this is necessary, the raw values should be integer. At most we could have a FIXME in anything has a decimal part just in case. From https://wayland.app/protocols/relative-pointer-unstable-v1
It says:
Note that the non-accelerated delta does not represent 'raw' events as they were read from some device. Pointer motion acceleration is device- and configuration-specific and non-accelerated deltas and accelerated deltas may have the same value on some devices.
It does say that unaccel isn't raw but it's closer to raw than pretending that the accelerated values are also raw. I guess it's probably fine to assume they are integer (since that is typically what happens) but it is better to be safe imo -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11357#note_145364
Rémi Bernon (@rbernon) commented about dlls/winewayland.drv/waylanddrv.h:
uint32_t enter_serial; uint32_t button_serial; struct wayland_cursor cursor; - double accum_x; - double accum_y; + double accum_x; double accum_y; + double accum_raw_x; double accum_raw_y;
```suggestion:-1+0 double accum_x; double accum_y; double accum_raw_x; double accum_raw_y; ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11357#note_145365
Rémi Bernon (@rbernon) commented about dlls/winewayland.drv/wayland_pointer.c:
pthread_mutex_lock(&pointer->mutex);
+ pointer->accum_raw_x += wl_fixed_to_double(dx_unaccel); + pointer->accum_raw_y += wl_fixed_to_double(dy_unaccel); + + pointer->accum_raw_x -= (raw.data[0].x = round(pointer->accum_raw_x)); + pointer->accum_raw_y -= (raw.data[0].y = round(pointer->accum_raw_y));
```suggestion:-4+0 pointer->accum_raw_x += wl_fixed_to_double(dx_unaccel); pointer->accum_raw_y += wl_fixed_to_double(dy_unaccel); raw.data[0].x = round(pointer->accum_raw_x); raw.data[0].y = round(pointer->accum_raw_y) pointer->accum_raw_x -= raw.data[0].x; pointer->accum_raw_y -= raw.data[0].y; ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11357#note_145366
Rémi Bernon (@rbernon) commented about dlls/winewayland.drv/wayland_pointer.c:
+ + pointer->accum_raw_x -= (raw.data[0].x = round(pointer->accum_raw_x)); + pointer->accum_raw_y -= (raw.data[0].y = round(pointer->accum_raw_y)); + if (pointer->relative_mode) { pointer->accum_x += screen_x; pointer->accum_y += screen_y;
- input.mi.dx = round(pointer->accum_x); - input.mi.dy = round(pointer->accum_y); - - pointer->accum_x -= input.mi.dx; - pointer->accum_y -= input.mi.dy; + pointer->accum_x -= (input.mi.dx = round(pointer->accum_x)); + pointer->accum_y -= (input.mi.dy = round(pointer->accum_y)); Lets keep this like it was. I don't think combining -= and assignment makes it very readable.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/11357#note_145367
On Fri Jul 10 07:12:56 2026 +0000, Etaash Mathamsetty wrote:
From https://wayland.app/protocols/relative-pointer-unstable-v1 It says:
Note that the non-accelerated delta does not represent 'raw' events as they were read from some device. Pointer motion acceleration is device- and configuration-specific and non-accelerated deltas and accelerated deltas may have the same value on some devices. It does say that unaccel isn't raw but it's closer to raw than pretending that the accelerated values are also raw. I guess it's probably fine to assume they are integer (since that is typically what happens) but it is better to be safe imo I would rather not add extra handling for things that don't happen in practice, but if you really think it's useful, then I'm also probably fine with it, with the suggested changes.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/11357#note_145369
participants (3)
-
Etaash Mathamsetty -
Etaash Mathamsetty (@etaash.mathamsetty) -
Rémi Bernon (@rbernon)