[PATCH v3] winex11.drv: Destroy old clipping message window if it has been replaced

RĂ©mi Bernon rbernon at codeweavers.com
Wed Aug 7 04:18:55 CDT 2019


When the same thread repeatedly calls ClipCursor, a message window is
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, then to the previous clipping thread in order for it to destroy
its clip_hwnd. But as the clipping thread is the same, and because
x11drv_thread_data->clip_hwnd has been overwritten, it does not satisfy
the "hwnd == data->clip_hwnd" condition and the window leaked.

This was causing exhaustion of user handles, and ultimately, failures to
create new clipping message windows, which then in turn makes the
pointer grab be lost.

This change makes sure that any dangling clipping message window is
properly destroyed.

Note: Implementing this by avoiding the re-creation of clipping message
window leads to a race condition when ClipCursor rect is reset then
restored: the desktop process sends reset notification which may be
processed after the clipping rect has already been restored.
---
 dlls/winex11.drv/mouse.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index f737a306a56..bb07e289a2d 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -499,6 +499,14 @@ LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd )
         GetClipCursor( &clip );
         X11DRV_ClipCursor( &clip );
     }
+    else if (hwnd)
+    {
+        /* This is a notification send by the desktop window to an old
+         * dangling clip window.
+         */
+        TRACE( "destroying old clip hwnd %p\n", hwnd );
+        DestroyWindow( hwnd );
+    }
     return 0;
 }
 
-- 
2.20.1




More information about the wine-devel mailing list