Rémi Bernon : winex11.drv: Use X11 root-relative coordinates when possible.

Alexandre Julliard julliard at winehq.org
Tue Apr 6 15:50:14 CDT 2021


Module: wine
Branch: master
Commit: 5a8bc554ef06c4a21d8b49ea8d936299f2cb2f34
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5a8bc554ef06c4a21d8b49ea8d936299f2cb2f34

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Tue Apr  6 17:47:41 2021 +0200

winex11.drv: Use X11 root-relative coordinates when possible.

Since whole_rect / client_rect are updated asynchronously, there may be
a small lag between X11 and Wine regarding the expected window position.

Then, as events' x and y fields are reported relative to the X11 window
position, this lag can cause inconsistencies when we compute absolute
mouse positions.

Also, applications that control their own position while being moved
cause additional whole_rect / client_rect updates, before X11 knows
about it.

This can make applications like Winamp go nuts when they are being moved
and move all over the place "randomly".

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46309
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/tests/input.c |  6 +++---
 dlls/winex11.drv/mouse.c  | 14 ++++++++------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 1fd9383e80a..646a9a66eb5 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -3195,7 +3195,7 @@ static LRESULT CALLBACK mouse_move_wndproc(HWND hwnd, UINT msg, WPARAM wparam, L
         POINT pt = {LOWORD(lparam), HIWORD(lparam)};
         MapWindowPoints(hwnd, NULL, &pt, 1);
 
-        if (pt.x != last_x) todo_wine ok( pt.x == expect_x, "got unexpected WM_MOUSEMOVE x %d, expected %d\n", pt.x, expect_x );
+        if (pt.x != last_x) ok( pt.x == expect_x, "got unexpected WM_MOUSEMOVE x %d, expected %d\n", pt.x, expect_x );
 
         expect_x = pt.x == 200 ? 210 : 200;
         last_x = pt.x;
@@ -3449,13 +3449,13 @@ static void test_Input_mouse(void)
     SetWindowPos(hwnd, NULL, 110, 100, 0, 0, SWP_NOSIZE);
     empty_message_queue();
     GetCursorPos(&pt);
-    todo_wine ok(pt.x == 210 && pt.y == 200, "GetCursorPos returned %dx%d, expected 210x200\n", pt.x, pt.y);
+    ok(pt.x == 210 && pt.y == 200, "GetCursorPos returned %dx%d, expected 210x200\n", pt.x, pt.y);
 
     SetCursorPos(200, 200);
     SetWindowPos(hwnd, NULL, 100, 100, 0, 0, SWP_NOSIZE);
     empty_message_queue();
     GetCursorPos(&pt);
-    todo_wine ok(pt.x == 200 && pt.y == 200, "GetCursorPos returned %dx%d, expected 200x200\n", pt.x, pt.y);
+    ok(pt.x == 200 && pt.y == 200, "GetCursorPos returned %dx%d, expected 200x200\n", pt.x, pt.y);
 
     SetCursorPos(pt_org.x, pt_org.y);
     empty_message_queue();
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 25b0b742fe3..94dece652b6 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -592,13 +592,14 @@ static BOOL is_old_motion_event( unsigned long serial )
  *
  * Map the input event coordinates so they're relative to the desktop.
  */
-static void map_event_coords( HWND hwnd, Window window, INPUT *input )
+static void map_event_coords( HWND hwnd, Window window, Window event_root, int x_root, int y_root, INPUT *input )
 {
     struct x11drv_thread_data *thread_data;
     struct x11drv_win_data *data;
     POINT pt = { input->u.mi.dx, input->u.mi.dy };
 
-    TRACE( "hwnd %p, window %lx, input %p\n", hwnd, window, input );
+    TRACE( "hwnd %p, window %lx, event_root %lx, x_root %d, y_root %d, input %p\n", hwnd, window, event_root,
+           x_root, y_root, input );
 
     if (!hwnd)
     {
@@ -611,6 +612,7 @@ static void map_event_coords( HWND hwnd, Window window, INPUT *input )
     else if ((data = get_win_data( hwnd )))
     {
         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 (window == data->whole_window)
@@ -1709,7 +1711,7 @@ BOOL X11DRV_ButtonPress( HWND hwnd, XEvent *xev )
     input.u.mi.dwExtraInfo = 0;
 
     update_user_time( event->time );
-    map_event_coords( hwnd, event->window, &input );
+    map_event_coords( hwnd, event->window, event->root, event->x_root, event->y_root, &input );
     send_mouse_input( hwnd, event->window, event->state, &input );
     return TRUE;
 }
@@ -1735,7 +1737,7 @@ BOOL X11DRV_ButtonRelease( HWND hwnd, XEvent *xev )
     input.u.mi.time        = EVENT_x11_time_to_win32_time( event->time );
     input.u.mi.dwExtraInfo = 0;
 
-    map_event_coords( hwnd, event->window, &input );
+    map_event_coords( hwnd, event->window, event->root, event->x_root, event->y_root, &input );
     send_mouse_input( hwnd, event->window, event->state, &input );
     return TRUE;
 }
@@ -1764,7 +1766,7 @@ BOOL X11DRV_MotionNotify( HWND hwnd, XEvent *xev )
         TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, event->serial );
         return FALSE;
     }
-    map_event_coords( hwnd, event->window, &input );
+    map_event_coords( hwnd, event->window, event->root, event->x_root, event->y_root, &input );
     send_mouse_input( hwnd, event->window, event->state, &input );
     return TRUE;
 }
@@ -1796,7 +1798,7 @@ BOOL X11DRV_EnterNotify( HWND hwnd, XEvent *xev )
         TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, event->serial );
         return FALSE;
     }
-    map_event_coords( hwnd, event->window, &input );
+    map_event_coords( hwnd, event->window, event->root, event->x_root, event->y_root, &input );
     send_mouse_input( hwnd, event->window, event->state, &input );
     return TRUE;
 }




More information about the wine-cvs mailing list