[PATCH v3 0/3] MR7429: winex11: Support absolute rawinput events and use window-relative coordinates.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51357 Now that we're tracking window position changes as they arrive, they should always be consistent with the received mouse input events. Absolute rawinput is useful for tablets, touchpad or touchscreen when they are exposed as absolute mouse devices. -- v3: winex11: Use window-relative coordinates for mouse input. winex11: Add support for absolute position in RawMotion events. winex11: Clear the MOUSEEVENTF_MOVE flag when accumulating motion. https://gitlab.winehq.org/wine/wine/-/merge_requests/7429
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/winex11.drv/mouse.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 4a74c18672a..049e461d0a9 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -1699,19 +1699,17 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) values++; } - input->mi.dx = round( x->value ); - input->mi.dy = round( y->value ); - - TRACE( "event %f,%f value %f,%f input %d,%d\n", x_value, y_value, x->value, y->value, - (int)input->mi.dx, (int)input->mi.dy ); - - x->value -= input->mi.dx; - y->value -= input->mi.dy; - - if (!input->mi.dx && !input->mi.dy) + if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value ))) { - TRACE( "accumulating motion\n" ); - return FALSE; + TRACE( "event %f,%f value %f,%f, accumulating motion\n", x_value, y_value, x->value, y->value ); + input->mi.dwFlags &= ~MOUSEEVENTF_MOVE; + } + else + { + TRACE( "event %f,%f value %f,%f, input %d,%d\n", x_value, y_value, x->value, y->value, + (int)input->mi.dx, (int)input->mi.dy ); + x->value -= input->mi.dx; + y->value -= input->mi.dy; } return TRUE; @@ -1739,6 +1737,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) input.mi.dx = 0; input.mi.dy = 0; if (!map_raw_event_coords( event, &input )) return FALSE; + if (!(input.mi.dwFlags & MOUSEEVENTF_MOVE)) return FALSE; NtUserSendHardwareInput( 0, 0, &input, 0 ); return TRUE; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7429
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/winex11.drv/mouse.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 049e461d0a9..d3fe328db9d 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -240,12 +240,18 @@ static void update_relative_valuators( XIAnyClassInfo **classes, int num_classes { valuator = (XIValuatorClassInfo *)classes[num_classes]; if (classes[num_classes]->type != XIValuatorClass) continue; - if (valuator->number == 0 && valuator->mode == XIModeRelative) thread_data->x_valuator = *valuator; - if (valuator->number == 1 && valuator->mode == XIModeRelative) thread_data->y_valuator = *valuator; + if (valuator->number == 0) thread_data->x_valuator = *valuator; + if (valuator->number == 1) thread_data->y_valuator = *valuator; } if (thread_data->x_valuator.number < 0 || thread_data->y_valuator.number < 0) WARN( "X/Y axis valuators not found, ignoring RawMotion events\n" ); + else if (thread_data->x_valuator.mode != thread_data->y_valuator.mode) + { + WARN( "Relative/Absolute mismatch between X/Y axis, ignoring RawMotion events\n" ); + thread_data->x_valuator.number = -1; + thread_data->y_valuator.number = -1; + } thread_data->x_valuator.value = 0; thread_data->y_valuator.value = 0; @@ -1666,6 +1672,7 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) { struct x11drv_thread_data *thread_data = x11drv_thread_data(); XIValuatorClassInfo *x = &thread_data->x_valuator, *y = &thread_data->y_valuator; + const UINT absolute_flags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK; double x_value = 0, y_value = 0, x_scale, y_scale; const double *values = event->valuators.values; RECT virtual_rect; @@ -1676,7 +1683,15 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) if (!xinput2_available) return FALSE; if (event->deviceid != thread_data->xinput2_pointer) return FALSE; - virtual_rect = NtUserGetVirtualScreenRect( MDT_RAW_DPI ); + if (x->mode == XIModeRelative && y->mode == XIModeRelative) + input->mi.dwFlags &= ~absolute_flags; + else if (x->mode == XIModeAbsolute && y->mode == XIModeAbsolute) + input->mi.dwFlags |= absolute_flags; + else + FIXME( "Unsupported relative/absolute X/Y axis mismatch\n." ); + + if (input->mi.dwFlags & MOUSEEVENTF_VIRTUALDESK) SetRect( &virtual_rect, 0, 0, 65535, 65535 ); + else virtual_rect = NtUserGetVirtualScreenRect( MDT_RAW_DPI ); if (x->max <= x->min) x_scale = 1; else x_scale = (virtual_rect.right - virtual_rect.left) / (x->max - x->min); @@ -1689,17 +1704,26 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) if (i == x->number) { x_value = *values; - x->value += x_value * x_scale; + if (x->mode == XIModeRelative) x->value += x_value * x_scale; + else x->value = (x_value - x->min) * x_scale; } if (i == y->number) { y_value = *values; - y->value += y_value * y_scale; + if (y->mode == XIModeRelative) y->value += y_value * y_scale; + else y->value = (y_value - y->min) * y_scale; } values++; } - if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value ))) + if (input->mi.dwFlags & MOUSEEVENTF_ABSOLUTE) + { + input->mi.dx = round( x->value ); + input->mi.dy = round( y->value ); + TRACE( "event %f,%f value %f,%f absolute input %d,%d\n", x_value, y_value, x->value, y->value, + (int)input->mi.dx, (int)input->mi.dy ); + } + else if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value ))) { TRACE( "event %f,%f value %f,%f, accumulating motion\n", x_value, y_value, x->value, y->value ); input->mi.dwFlags &= ~MOUSEEVENTF_MOVE; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7429
From: Rémi Bernon <rbernon(a)codeweavers.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51357 --- dlls/winex11.drv/mouse.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index d3fe328db9d..e13545adee1 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -504,7 +504,6 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x x_root, y_root, input ); if (window == root_window) pt = root_to_virtual_screen( pt.x, pt.y ); - else if (event_root == root_window) pt = root_to_virtual_screen( x_root, y_root ); else if (!hwnd) { thread_data = x11drv_thread_data(); @@ -522,8 +521,8 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x } else { - pt.x += data->rects.visible.left; - pt.y += data->rects.visible.top; + pt.x += data->current_state.rect.left; + pt.y += data->current_state.rect.top; } release_win_data( data ); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7429
mouse will acting weird after this patch, it will stop moving after some distance Test by https://store.steampowered.com/app/1502980 -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7429#note_100552
Before patch  After patch  I believe the video should be clearly enough for the issue. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7429#note_100556
This merge request was closed by Rémi Bernon. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7429
participants (3)
-
Chunhao Hung (@otakuxtom) -
Rémi Bernon -
Rémi Bernon (@rbernon)