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.
From: Rémi Bernon rbernon@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;
From: Rémi Bernon rbernon@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;
From: Rémi Bernon rbernon@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 ); }
mouse will acting weird after this patch, it will stop moving after some distance Test by https://store.steampowered.com/app/1502980
Before patch  After patch  I believe the video should be clearly enough for the issue.