[PATCH resend] winex11.drv: Try harder to grab pointer.
Zhiyi Zhang
zzhang at codeweavers.com
Thu Aug 1 11:46:52 CDT 2019
Some window managers temporarily grab the pointer during window transition.
We need to wait a while for window manager to release its grab, otherwise
XGrabPointer may fail with AlreadyGrabbed, causing cursor clipping to fail.
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
dlls/winex11.drv/mouse.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index f737a306a5..7501959369 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -378,9 +378,13 @@ static BOOL grab_clipping_window( const RECT *clip )
{
static const WCHAR messageW[] = {'M','e','s','s','a','g','e',0};
struct x11drv_thread_data *data = x11drv_thread_data();
+ static DWORD timeout = 5000;
+ static DWORD step = 100;
+ DWORD time = 0;
Window clip_window;
HWND msg_hwnd = 0;
POINT pos;
+ INT ret;
if (GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId())
return TRUE; /* don't clip in the desktop process */
@@ -416,13 +420,24 @@ static BOOL grab_clipping_window( const RECT *clip )
clip->right < clip_rect.right || clip->bottom < clip_rect.bottom)
data->warp_serial = NextRequest( data->display );
- if (!XGrabPointer( data->display, clip_window, False,
- PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
- GrabModeAsync, GrabModeAsync, clip_window, None, CurrentTime ))
+ /* Some windows managers temporarily grab the pointer during window transition. Retry grabbing. */
+ do
+ {
+ ret = XGrabPointer( data->display, clip_window, False, PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync, clip_window, None, CurrentTime );
+ if (ret == AlreadyGrabbed || ret == GrabFrozen)
+ {
+ time += step;
+ Sleep(step);
+ }
+ } while ((ret == AlreadyGrabbed || ret == GrabFrozen) && time < timeout);
+
+ if (ret == GrabSuccess)
clipping_cursor = TRUE;
if (!clipping_cursor)
{
+ ERR("Failed to grab pointer\n");
disable_xinput2();
DestroyWindow( msg_hwnd );
return FALSE;
--
2.20.1
More information about the wine-devel
mailing list