diff --git a/patches/winex11.drv-mouse-coorrds/0001-winex11.drv-mouse-Use-root-relative-coordinates-for-ev.patch b/patches/winex11.drv-mouse-coorrds/0001-winex11.drv-mouse-Use-root-relative-coordinates-for-ev.patch index 0dd18006..e1a21c2c 100644 --- a/patches/winex11.drv-mouse-coorrds/0001-winex11.drv-mouse-Use-root-relative-coordinates-for-ev.patch +++ b/patches/winex11.drv-mouse-coorrds/0001-winex11.drv-mouse-Use-root-relative-coordinates-for-ev.patch @@ -1,6 +1,6 @@ -From 292705b9649903fec512844773110b235b5ea8f8 Mon Sep 17 00:00:00 2001 +From 712e41cd7a3d09291616d50836215b79a867d43a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Iv=C4=83ncescu?= -Date: Thu, 20 Dec 2018 12:52:48 +0200 +Date: Tue, 7 May 2019 14:43:42 +0300 Subject: [PATCH] winex11.drv/mouse: Use root-relative coordinates for events, if possible MIME-Version: 1.0 @@ -13,46 +13,55 @@ apparently result in them being out of sync from the X server side and ours (hwnd). This makes applications like Winamp go nuts when they are being moved and move all over the place "randomly". -The solution is to use x_root and y_root instead, when the root is the -same as our root_window, which solves this issue. The final coordinates -will have to be relative to the virtual screen anyway so this actually -simplifies most of the code in send_mouse_input. - Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46309 Signed-off-by: Gabriel Ivăncescu --- - dlls/winex11.drv/mouse.c | 100 ++++++++++++++++++++++++--------------- - 1 file changed, 62 insertions(+), 38 deletions(-) + dlls/winex11.drv/mouse.c | 106 +++++++++++++++++++++++++-------------- + 1 file changed, 68 insertions(+), 38 deletions(-) diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c -index d678706..b12e214 100644 +index f737a30..e59a281 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c -@@ -554,6 +554,32 @@ static BOOL is_old_motion_event( unsigned long serial ) +@@ -554,6 +554,46 @@ static BOOL is_old_motion_event( unsigned long serial ) } +/*********************************************************************** -+ * map_to_root_coords ++ * map_event_coords + * -+ * Map the window-relative coordinates so they're relative to the root. ++ * Map the input event coordinates so they're relative to the desktop. + */ -+static POINT map_to_root_coords(HWND hwnd, Window window, int x, int y) ++static POINT map_event_coords(const XButtonEvent *event, HWND hwnd) +{ ++ POINT pt = { event->x, event->y }; + struct x11drv_win_data *data; -+ POINT pt = { x, y }; + -+ if (!(data = get_win_data(hwnd))) return pt; -+ if (window == data->whole_window) ++ if (event->window == root_window) ++ pt = root_to_virtual_screen(event->x, event->y); ++ ++ if ((data = get_win_data(hwnd))) + { -+ pt.x += data->whole_rect.left - data->client_rect.left; -+ pt.y += data->whole_rect.top - data->client_rect.top; -+ } ++ if (event->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; -+ release_win_data(data); -+ MapWindowPoints(hwnd, 0, &pt, 1); ++ 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); ++ ++ if (event->root == root_window && event->same_screen && data->managed) ++ { ++ /* Try to use root coordinates, unless the window is at the (0,0) ++ position on the desktop to workaround full-screen or apps like ++ vst-bridge which reparent the window, so they don't break. */ ++ if (pt.x != event->x || pt.y != event->y) ++ pt = root_to_virtual_screen(event->x_root, event->y_root); ++ } ++ release_win_data(data); ++ } + + return pt; +} @@ -61,7 +70,7 @@ index d678706..b12e214 100644 /*********************************************************************** * send_mouse_input * -@@ -562,7 +588,6 @@ static BOOL is_old_motion_event( unsigned long serial ) +@@ -562,7 +602,6 @@ static BOOL is_old_motion_event( unsigned long serial ) static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPUT *input ) { struct x11drv_win_data *data; @@ -69,7 +78,7 @@ index d678706..b12e214 100644 input->type = INPUT_MOUSE; -@@ -585,32 +610,14 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU +@@ -585,32 +624,14 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU return; } @@ -106,7 +115,7 @@ index d678706..b12e214 100644 if (hwnd != GetDesktopWindow()) { -@@ -625,8 +632,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU +@@ -625,8 +646,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU /* ignore event if a button is pressed, since the mouse is then grabbed too */ !(state & (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask|Button6Mask|Button7Mask))) { @@ -116,7 +125,7 @@ index d678706..b12e214 100644 SERVER_START_REQ( update_window_zorder ) { -@@ -640,8 +646,6 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU +@@ -640,8 +660,6 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU SERVER_END_REQ; } @@ -125,7 +134,7 @@ index d678706..b12e214 100644 __wine_send_input( hwnd, input ); } -@@ -1598,13 +1602,18 @@ BOOL X11DRV_ButtonPress( HWND hwnd, XEvent *xev ) +@@ -1598,13 +1616,16 @@ BOOL X11DRV_ButtonPress( HWND hwnd, XEvent *xev ) XButtonEvent *event = &xev->xbutton; int buttonNum = event->button - 1; INPUT input; @@ -134,9 +143,7 @@ index d678706..b12e214 100644 if (buttonNum >= NB_BUTTONS) return FALSE; - TRACE( "hwnd %p/%lx button %u pos %d,%d\n", hwnd, event->window, buttonNum, event->x, event->y ); -+ pt = root_to_virtual_screen(event->x_root, event->y_root); -+ if (event->root != root_window || !event->same_screen) -+ pt = map_to_root_coords(hwnd, event->window, event->x, event->y); ++ pt = map_event_coords(event, hwnd); + + TRACE( "hwnd %p/%lx button %u pos %d,%d\n", hwnd, event->window, buttonNum, pt.x, pt.y ); @@ -147,7 +154,7 @@ index d678706..b12e214 100644 input.u.mi.mouseData = button_down_data[buttonNum]; input.u.mi.dwFlags = button_down_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; input.u.mi.time = EVENT_x11_time_to_win32_time( event->time ); -@@ -1624,13 +1633,18 @@ BOOL X11DRV_ButtonRelease( HWND hwnd, XEvent *xev ) +@@ -1624,13 +1645,16 @@ BOOL X11DRV_ButtonRelease( HWND hwnd, XEvent *xev ) XButtonEvent *event = &xev->xbutton; int buttonNum = event->button - 1; INPUT input; @@ -156,9 +163,7 @@ index d678706..b12e214 100644 if (buttonNum >= NB_BUTTONS || !button_up_flags[buttonNum]) return FALSE; - TRACE( "hwnd %p/%lx button %u pos %d,%d\n", hwnd, event->window, buttonNum, event->x, event->y ); -+ pt = root_to_virtual_screen(event->x_root, event->y_root); -+ if (event->root != root_window || !event->same_screen) -+ pt = map_to_root_coords(hwnd, event->window, event->x, event->y); ++ pt = map_event_coords(event, hwnd); + + TRACE( "hwnd %p/%lx button %u pos %d,%d\n", hwnd, event->window, buttonNum, pt.x, pt.y ); @@ -169,15 +174,13 @@ index d678706..b12e214 100644 input.u.mi.mouseData = button_up_data[buttonNum]; input.u.mi.dwFlags = button_up_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; input.u.mi.time = EVENT_x11_time_to_win32_time( event->time ); -@@ -1648,12 +1662,17 @@ BOOL X11DRV_MotionNotify( HWND hwnd, XEvent *xev ) +@@ -1648,12 +1672,15 @@ BOOL X11DRV_MotionNotify( HWND hwnd, XEvent *xev ) { XMotionEvent *event = &xev->xmotion; INPUT input; + POINT pt; + -+ pt = root_to_virtual_screen(event->x_root, event->y_root); -+ if (event->root != root_window || !event->same_screen) -+ pt = map_to_root_coords(hwnd, event->window, event->x, event->y); ++ pt = map_event_coords((XButtonEvent*)event, hwnd); TRACE( "hwnd %p/%lx pos %d,%d is_hint %d serial %lu\n", - hwnd, event->window, event->x, event->y, event->is_hint, event->serial ); @@ -190,7 +193,7 @@ index d678706..b12e214 100644 input.u.mi.mouseData = 0; input.u.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; input.u.mi.time = EVENT_x11_time_to_win32_time( event->time ); -@@ -1676,6 +1695,7 @@ BOOL X11DRV_EnterNotify( HWND hwnd, XEvent *xev ) +@@ -1676,6 +1703,7 @@ BOOL X11DRV_EnterNotify( HWND hwnd, XEvent *xev ) { XCrossingEvent *event = &xev->xcrossing; INPUT input; @@ -198,15 +201,13 @@ index d678706..b12e214 100644 TRACE( "hwnd %p/%lx pos %d,%d detail %d\n", hwnd, event->window, event->x, event->y, event->detail ); -@@ -1683,8 +1703,12 @@ BOOL X11DRV_EnterNotify( HWND hwnd, XEvent *xev ) +@@ -1683,8 +1711,10 @@ BOOL X11DRV_EnterNotify( HWND hwnd, XEvent *xev ) if (hwnd == x11drv_thread_data()->grab_hwnd) return FALSE; /* simulate a mouse motion event */ - input.u.mi.dx = event->x; - input.u.mi.dy = event->y; -+ pt = root_to_virtual_screen(event->x_root, event->y_root); -+ if (event->root != root_window || !event->same_screen) -+ pt = map_to_root_coords(hwnd, event->window, event->x, event->y); ++ pt = map_event_coords((XButtonEvent*)event, hwnd); + + input.u.mi.dx = pt.x; + input.u.mi.dy = pt.y; @@ -214,5 +215,5 @@ index d678706..b12e214 100644 input.u.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; input.u.mi.time = EVENT_x11_time_to_win32_time( event->time ); -- -2.19.1 +2.21.0