Alexandre Julliard : winex11: Grab the mouse in the thread that owns the foreground window if possible.
Alexandre Julliard
julliard at winehq.org
Thu Apr 28 12:18:56 CDT 2011
Module: wine
Branch: master
Commit: 84f085fb91a17e2efe83de0642b757948f4e8a7d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=84f085fb91a17e2efe83de0642b757948f4e8a7d
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Apr 28 13:07:05 2011 +0200
winex11: Grab the mouse in the thread that owns the foreground window if possible.
---
dlls/winex11.drv/mouse.c | 99 +++++++++++++++++++++++++++++-----------------
1 files changed, 62 insertions(+), 37 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 7f45a2a..96d93e5 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -369,44 +369,18 @@ static HWND create_clipping_msg_window(void)
}
/***********************************************************************
- * clip_cursor_notify
- *
- * Notification function called upon receiving a WM_X11DRV_CLIP_CURSOR.
- */
-LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd )
-{
- struct x11drv_thread_data *data = x11drv_thread_data();
-
- if (hwnd == GetDesktopWindow()) /* change the clip window stored in the desktop process */
- {
- static HWND clip_hwnd;
-
- HWND prev = clip_hwnd;
- clip_hwnd = new_clip_hwnd;
- if (prev || new_clip_hwnd) TRACE( "clip hwnd changed from %p to %p\n", prev, new_clip_hwnd );
- if (prev) SendNotifyMessageW( prev, WM_X11DRV_CLIP_CURSOR, 0, 0 );
- }
- else if (hwnd == data->clip_hwnd) /* this is a notification that clipping has been reset */
- {
- data->clip_hwnd = 0;
- disable_xinput2();
- DestroyWindow( hwnd );
- }
- return 0;
-}
-
-/***********************************************************************
* grab_clipping_window
*
* Start a pointer grab on the clip window.
*/
static BOOL grab_clipping_window( const RECT *clip )
{
- struct x11drv_thread_data *data = x11drv_init_thread_data();
- Window clip_window = init_clip_window();
+ struct x11drv_thread_data *data = x11drv_thread_data();
+ Window clip_window;
HWND msg_hwnd = 0;
- if (!clip_window) return TRUE;
+ if (!data) return FALSE;
+ if (!(clip_window = init_clip_window())) return TRUE;
/* create a clip message window unless we are already clipping */
if (!data->clip_hwnd)
@@ -475,6 +449,42 @@ void ungrab_clipping_window(void)
}
/***********************************************************************
+ * clip_cursor_notify
+ *
+ * Notification function called upon receiving a WM_X11DRV_CLIP_CURSOR.
+ */
+LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd )
+{
+ struct x11drv_thread_data *data = x11drv_thread_data();
+
+ if (hwnd == GetDesktopWindow()) /* change the clip window stored in the desktop process */
+ {
+ static HWND clip_hwnd;
+
+ HWND prev = clip_hwnd;
+ clip_hwnd = new_clip_hwnd;
+ if (prev || new_clip_hwnd) TRACE( "clip hwnd changed from %p to %p\n", prev, new_clip_hwnd );
+ if (prev) SendNotifyMessageW( prev, WM_X11DRV_CLIP_CURSOR, 0, 0 );
+ }
+ else if (hwnd == data->clip_hwnd) /* this is a notification that clipping has been reset */
+ {
+ data->clip_hwnd = 0;
+ disable_xinput2();
+ DestroyWindow( hwnd );
+ }
+ else if (hwnd == GetForegroundWindow()) /* request to clip */
+ {
+ RECT clip;
+
+ GetClipCursor( &clip );
+ if (clip.left > virtual_screen_rect.left || clip.right < virtual_screen_rect.right ||
+ clip.top > virtual_screen_rect.top || clip.bottom < virtual_screen_rect.bottom)
+ return grab_clipping_window( &clip );
+ }
+ return 0;
+}
+
+/***********************************************************************
* send_mouse_input
*
* Update the various window states on a mouse event.
@@ -1191,16 +1201,31 @@ BOOL CDECL X11DRV_GetCursorPos(LPPOINT pos)
*/
BOOL CDECL X11DRV_ClipCursor( LPCRECT clip )
{
+ if (!clip)
+ {
+ ungrab_clipping_window();
+ return TRUE;
+ }
+
+ if (X11DRV_get_win_data( GetDesktopWindow() )) return TRUE; /* don't clip in the desktop process */
+
/* we are clipping if the clip rectangle is smaller than the screen */
- if (clip && (clip->left > virtual_screen_rect.left ||
- clip->right < virtual_screen_rect.right ||
- clip->top > virtual_screen_rect.top ||
- clip->bottom < virtual_screen_rect.bottom))
+ if (grab_pointer && (clip->left > virtual_screen_rect.left ||
+ clip->right < virtual_screen_rect.right ||
+ clip->top > virtual_screen_rect.top ||
+ clip->bottom < virtual_screen_rect.bottom))
{
- if (GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId())
- return TRUE; /* don't clip in the desktop process */
+ DWORD tid, pid;
+ HWND foreground = GetForegroundWindow();
- if (grab_pointer && grab_clipping_window( clip )) return TRUE;
+ /* forward request to the foreground window if it's in a different thread */
+ tid = GetWindowThreadProcessId( foreground, &pid );
+ if (tid && tid != GetCurrentThreadId() && pid == GetCurrentProcessId())
+ {
+ TRACE( "forwarding clip request to %p\n", foreground );
+ if (SendMessageW( foreground, WM_X11DRV_CLIP_CURSOR, 0, 0 )) return TRUE;
+ }
+ else if (grab_clipping_window( clip )) return TRUE;
}
ungrab_clipping_window();
More information about the wine-cvs
mailing list