[PATCH v2] winex11.drv: Avoid re-creating the clipping message window if it already exists
Rémi Bernon
rbernon at codeweavers.com
Wed Jul 31 07:57:52 CDT 2019
When the same thread repeatedly calls ClipCursor, a message window was
created for every call, then stored in x11drv_thread_data->clip_hwnd.
The WM_X11DRV_CLIP_CURSOR notification is then sent to the desktop
window, targetting the previous clipping thread in order for it to
destroy its clip_hwnd. But as x11drv_thread_data->clip_hwnd has been
overwritten, it does not satisfy the "hwnd == data->clip_hwnd" condition
and the previous clip_hwnd is leaked.
This leads to exhaustion of user handles, and ultimately, failures to
create new clipping message windows, which then in turn makes the
pointer grab be lost.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
Resending with Signed-off-by.
dlls/winex11.drv/mouse.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index f737a306a56..3ab6bf5a1ec 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -388,7 +388,8 @@ static BOOL grab_clipping_window( const RECT *clip )
if (!data) return FALSE;
if (!(clip_window = init_clip_window())) return TRUE;
- if (!(msg_hwnd = CreateWindowW( messageW, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0,
+ if (!data->clip_hwnd &&
+ !(msg_hwnd = CreateWindowW( messageW, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0,
GetModuleHandleW(0), NULL )))
return TRUE;
@@ -398,12 +399,12 @@ static BOOL grab_clipping_window( const RECT *clip )
if (data->xi2_state != xi_enabled)
{
WARN( "XInput2 not supported, refusing to clip to %s\n", wine_dbgstr_rect(clip) );
- DestroyWindow( msg_hwnd );
+ if (msg_hwnd) DestroyWindow( msg_hwnd );
ClipCursor( NULL );
return TRUE;
}
- TRACE( "clipping to %s win %lx\n", wine_dbgstr_rect(clip), clip_window );
+ TRACE( "clipping to %s win %p/%lx\n", wine_dbgstr_rect(clip), data->clip_hwnd ? data->clip_hwnd : msg_hwnd, clip_window );
if (!data->clip_hwnd) XUnmapWindow( data->display, clip_window );
pos = virtual_screen_to_root( clip->left, clip->top );
@@ -424,14 +425,19 @@ static BOOL grab_clipping_window( const RECT *clip )
if (!clipping_cursor)
{
disable_xinput2();
- DestroyWindow( msg_hwnd );
+ if (msg_hwnd) DestroyWindow( msg_hwnd );
return FALSE;
}
clip_rect = *clip;
- if (!data->clip_hwnd) sync_window_cursor( clip_window );
- InterlockedExchangePointer( (void **)&cursor_window, msg_hwnd );
- data->clip_hwnd = msg_hwnd;
- SendMessageW( GetDesktopWindow(), WM_X11DRV_CLIP_CURSOR, 0, (LPARAM)msg_hwnd );
+
+ if (!data->clip_hwnd)
+ {
+ sync_window_cursor( clip_window );
+ data->clip_hwnd = msg_hwnd;
+ }
+
+ InterlockedExchangePointer( (void **)&cursor_window, data->clip_hwnd );
+ SendMessageW( GetDesktopWindow(), WM_X11DRV_CLIP_CURSOR, 0, (LPARAM)data->clip_hwnd );
return TRUE;
}
@@ -481,6 +487,7 @@ LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd )
HWND prev = clip_hwnd;
clip_hwnd = new_clip_hwnd;
+ if (prev == new_clip_hwnd) return 0;
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 );
}
--
2.20.1
More information about the wine-devel
mailing list