Based on a patch from Gabriel Ivăncescu gabrielopcode@gmail.com. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46309
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
This patch has been in staging and proton for a while and been sent already but it silently dropped off the patch list.
It's causing conflicts with some other patches I have that deal with __wine_send_input and that I'd like to send too, and so I cleaned it up a bit and I'm now sending it with Gabriel's blessing.
I can reproduce the issue with Winamp, but not on my regular desktop. The issue is however pretty easy to reproduce when there's lag between Wine and X11, such as when using a remote X11 server.
dlls/winex11.drv/mouse.c | 46 +++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index dd25f8b172c..8a379e5a3b7 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -587,6 +587,34 @@ static BOOL is_old_motion_event( unsigned long serial ) }
+/*********************************************************************** + * map_event_coords + * + * Map the input event coordinates so they're relative to the desktop. + */ +static POINT map_event_coords( HWND hwnd, Window window, struct x11drv_win_data *data, const INPUT *input ) +{ + POINT pt = { input->u.mi.dx, input->u.mi.dy }; + + TRACE( "hwnd %p, window %lx, data %p, input %p\n", hwnd, window, data, input ); + + if (window == root_window) pt = root_to_virtual_screen( pt.x, pt.y ); + if (window == data->whole_window) + { + pt.x += data->whole_rect.left - data->client_rect.left; + pt.y += data->whole_rect.top - data->client_rect.top; + } + + if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) + pt.x = data->client_rect.right - data->client_rect.left - 1 - pt.x; + MapWindowPoints( hwnd, 0, &pt, 1 ); + + TRACE( "mapped %s to %s\n", wine_dbgstr_point( (POINT *)&input->u.mi.dx ), wine_dbgstr_point( &pt ) ); + + return pt; +} + + /*********************************************************************** * send_mouse_input * @@ -618,24 +646,8 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU return; }
- if (window != root_window) - { - pt.x = input->u.mi.dx; - pt.y = input->u.mi.dy; - } - else pt = root_to_virtual_screen( input->u.mi.dx, input->u.mi.dy ); - if (!(data = get_win_data( hwnd ))) return; - - if (window == data->whole_window) - { - pt.x += data->whole_rect.left - data->client_rect.left; - pt.y += data->whole_rect.top - data->client_rect.top; - } - - if (GetWindowLongW( data->hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) - pt.x = data->client_rect.right - data->client_rect.left - 1 - pt.x; - MapWindowPoints( hwnd, 0, &pt, 1 ); + pt = map_event_coords( hwnd, window, data, input );
if (InterlockedExchangePointer( (void **)&cursor_window, hwnd ) != hwnd || input->u.mi.time - last_cursor_change > 100)