[PATCH v3 5/6] winex11.drv: Only grab or warp the cursor when keyboard isn't grabbed

Rémi Bernon rbernon at codeweavers.com
Thu Jun 27 09:30:14 CDT 2019


When some other window has a keyboard grab, it is good citizenship to
wait for it to end. Grabbing or moving the cursor at the same time could
interfer with it.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winex11.drv/event.c  |  9 +++++++++
 dlls/winex11.drv/mouse.c  | 12 ++++++++++++
 dlls/winex11.drv/x11drv.h |  1 +
 3 files changed, 22 insertions(+)

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 83e09477ba7..21ee2aa084e 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -155,6 +155,9 @@ static const char * event_names[MAX_EVENT_HANDLERS] =
     "SelectionNotify", "ColormapNotify", "ClientMessage", "MappingNotify", "GenericEvent"
 };
 
+/* is someone else grabbing the keyboard, for example the WM, when manipulating the window */
+BOOL keyboard_grabbed = FALSE;
+
 int xinput2_opcode = 0;
 
 /* return the name of an X event */
@@ -778,10 +781,13 @@ static BOOL X11DRV_FocusIn( HWND hwnd, XEvent *xev )
         WARN( "unexpected FocusIn event with NotifyGrab mode\n" );
         break;
     case NotifyWhileGrabbed:
+        keyboard_grabbed = TRUE;
         break;
     case NotifyNormal:
+        keyboard_grabbed = FALSE;
         break;
     case NotifyUngrab:
+        keyboard_grabbed = FALSE;
         return FALSE; /* ignore wm specific NotifyUngrab / NotifyGrab events w.r.t focus */
     }
 
@@ -875,10 +881,13 @@ static BOOL X11DRV_FocusOut( HWND hwnd, XEvent *xev )
         WARN( "unexpected FocusOut event with NotifyUngrab mode\n" );
         break;
     case NotifyNormal:
+        keyboard_grabbed = FALSE;
         break;
     case NotifyWhileGrabbed:
+        keyboard_grabbed = TRUE;
         break;
     case NotifyGrab:
+        keyboard_grabbed = TRUE;
         return FALSE; /* ignore wm specific NotifyUngrab / NotifyGrab events w.r.t focus */
     }
 
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index c3a9a027957..fa976cae7fb 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -392,6 +392,12 @@ static BOOL grab_clipping_window( const RECT *clip )
                                     GetModuleHandleW(0), NULL )))
         return TRUE;
 
+    if (keyboard_grabbed)
+    {
+        WARN( "refusing to clip to %s\n", wine_dbgstr_rect(clip) );
+        return FALSE;
+    }
+
     /* enable XInput2 unless we are already clipping */
     if (!data->clip_hwnd) enable_xinput2();
 
@@ -1430,6 +1436,12 @@ BOOL CDECL X11DRV_SetCursorPos( INT x, INT y )
     struct x11drv_thread_data *data = x11drv_init_thread_data();
     POINT pos = virtual_screen_to_root( x, y );
 
+    if (keyboard_grabbed)
+    {
+        WARN( "refusing to warp to %u, %u\n", pos.x, pos.y );
+        return FALSE;
+    }
+
     if (!clipping_cursor &&
         XGrabPointer( data->display, root_window, False,
                       PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 9ab948f7246..2dfa2a20ce9 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -382,6 +382,7 @@ extern Colormap default_colormap DECLSPEC_HIDDEN;
 extern XPixmapFormatValues **pixmap_formats DECLSPEC_HIDDEN;
 extern Window root_window DECLSPEC_HIDDEN;
 extern BOOL clipping_cursor DECLSPEC_HIDDEN;
+extern BOOL keyboard_grabbed DECLSPEC_HIDDEN;
 extern unsigned int screen_bpp DECLSPEC_HIDDEN;
 extern BOOL use_xkb DECLSPEC_HIDDEN;
 extern BOOL usexrandr DECLSPEC_HIDDEN;
-- 
2.20.1




More information about the wine-devel mailing list