[5/5] winex11.drv: Use a dedicated window for mouse capture.
Vincent Povirk
madewokherd at gmail.com
Wed Apr 16 14:13:02 CDT 2014
-------------- next part --------------
From 5762b43eca7ade336dd9ca02f88211999e72542d Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Thu, 6 Mar 2014 15:30:46 -0600
Subject: [PATCH 05/11] winex11.drv: Use a dedicated window for mouse capture.
---
dlls/winex11.drv/mouse.c | 63 ++++++++++++++++++++++++++++++++++++++++++-----
dlls/winex11.drv/window.c | 35 +++-----------------------
dlls/winex11.drv/x11drv.h | 1 +
3 files changed, 61 insertions(+), 38 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index f1e58fe..0ae0758 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -535,18 +535,25 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
if (!hwnd)
{
struct x11drv_thread_data *thread_data = x11drv_thread_data();
- HWND clip_hwnd = thread_data->clip_hwnd;
+ HWND cursor_hwnd;
- if (!clip_hwnd) return;
- if (thread_data->clip_window != window) return;
- if (InterlockedExchangePointer( (void **)&cursor_window, clip_hwnd ) != clip_hwnd ||
+ if (thread_data->clip_window == window)
+ {
+ if (!thread_data->clip_hwnd) return;
+ cursor_hwnd = thread_data->clip_hwnd;
+ input->u.mi.dx += clip_rect.left;
+ input->u.mi.dy += clip_rect.top;
+ }
+ else if (thread_data->grab_window == window)
+ cursor_hwnd = GetCapture();
+ else
+ return;
+ if (InterlockedExchangePointer( (void **)&cursor_window, cursor_hwnd ) != cursor_hwnd ||
input->u.mi.time - last_cursor_change > 100)
{
sync_window_cursor( window );
last_cursor_change = input->u.mi.time;
}
- input->u.mi.dx += clip_rect.left;
- input->u.mi.dy += clip_rect.top;
__wine_send_input( hwnd, input );
return;
}
@@ -1421,6 +1428,50 @@ BOOL CDECL X11DRV_ClipCursor( LPCRECT clip )
return TRUE;
}
+
+/***********************************************************************
+ * SetCapture (X11DRV.@)
+ */
+void CDECL X11DRV_SetCapture( HWND hwnd, UINT flags )
+{
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
+
+ if (!thread_data) return;
+ if (!(flags & (GUI_INMOVESIZE | GUI_INMENUMODE))) return;
+
+ if (hwnd)
+ {
+ if (!thread_data->capture_window)
+ {
+ XSetWindowAttributes attr;
+
+ attr.override_redirect = TRUE;
+ attr.event_mask = StructureNotifyMask | FocusChangeMask;
+ thread_data->capture_window = XCreateWindow( thread_data->display,
+ root_window, 0, 0, 1, 1, 0, 0, InputOnly, default_visual.visual,
+ CWOverrideRedirect | CWEventMask, &attr );
+
+ if (!thread_data->capture_window) return;
+ }
+
+ XFlush( gdi_display );
+ XMapWindow( thread_data->display, thread_data->capture_window );
+ XGrabPointer( thread_data->display, thread_data->capture_window, False,
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync, None, None, CurrentTime );
+ sync_window_cursor( thread_data->capture_window );
+ InterlockedExchangePointer( (void **)&cursor_window, hwnd );
+ thread_data->grab_window = thread_data->capture_window;
+ }
+ else if (thread_data->capture_window) /* release capture */
+ {
+ XFlush( gdi_display );
+ XUnmapWindow( thread_data->display, thread_data->capture_window );
+ XFlush( thread_data->display );
+ thread_data->grab_window = None;
+ }
+}
+
/***********************************************************************
* move_resize_window
*/
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index a9caa0d..c150cae 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2060,37 +2060,6 @@ BOOL CDECL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
}
-/***********************************************************************
- * SetCapture (X11DRV.@)
- */
-void CDECL X11DRV_SetCapture( HWND hwnd, UINT flags )
-{
- struct x11drv_thread_data *thread_data = x11drv_thread_data();
-
- if (!thread_data) return;
- if (!(flags & (GUI_INMOVESIZE | GUI_INMENUMODE))) return;
-
- if (hwnd)
- {
- Window grab_win = X11DRV_get_whole_window( GetAncestor( hwnd, GA_ROOT ) );
-
- if (!grab_win) return;
- XFlush( gdi_display );
- XGrabPointer( thread_data->display, grab_win, False,
- PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
- GrabModeAsync, GrabModeAsync, None, None, CurrentTime );
- thread_data->grab_window = grab_win;
- }
- else /* release capture */
- {
- XFlush( gdi_display );
- XUngrabPointer( thread_data->display, CurrentTime );
- XFlush( thread_data->display );
- thread_data->grab_window = None;
- }
-}
-
-
/*****************************************************************
* SetParent (X11DRV.@)
*/
@@ -2603,7 +2572,9 @@ LRESULT CDECL X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
X11DRV_resize_desktop( LOWORD(lp), HIWORD(lp) );
return 0;
case WM_X11DRV_SET_CURSOR:
- if ((data = get_win_data( hwnd )))
+ if (x11drv_thread_data()->grab_window)
+ set_window_cursor( x11drv_thread_data()->grab_window, (HCURSOR)lp );
+ else if ((data = get_win_data( hwnd )))
{
if (data->whole_window) set_window_cursor( data->whole_window, (HCURSOR)lp );
release_win_data( data );
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 7a3374d..b0b6ba9 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -311,6 +311,7 @@ struct x11drv_thread_data
Display *display;
XEvent *current_event; /* event currently being processed */
Window grab_window; /* window that currently grabs the mouse */
+ Window capture_window; /* window used for capture */
HWND last_focus; /* last window that had focus */
XIM xim; /* input method */
HWND last_xic_hwnd; /* last xic window */
--
1.8.3.2
More information about the wine-patches
mailing list