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@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;