winex11: Grab the mouse in the thread that owns the foreground window if possible.
This commit is contained in:
parent
20e24bff70
commit
84f085fb91
|
@ -368,33 +368,6 @@ static HWND create_clipping_msg_window(void)
|
|||
return CreateWindowW( class_name, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, GetModuleHandleW(0), NULL );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 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
|
||||
*
|
||||
|
@ -402,11 +375,12 @@ LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd )
|
|||
*/
|
||||
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)
|
||||
|
@ -474,6 +448,42 @@ void ungrab_clipping_window(void)
|
|||
SendMessageW( GetDesktopWindow(), WM_X11DRV_CLIP_CURSOR, 0, 0 );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 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
|
||||
*
|
||||
|
@ -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 ||
|
||||
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();
|
||||
|
|
Loading…
Reference in New Issue