Rémi Bernon : winex11.drv: Destroy old clipping message window if it has been replaced.

Alexandre Julliard julliard at winehq.org
Tue Sep 17 16:22:50 CDT 2019


Module: wine
Branch: master
Commit: 12c09051b48507cf8bb37d500719661d0c6ad9f0
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=12c09051b48507cf8bb37d500719661d0c6ad9f0

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Mon Sep 16 10:00:18 2019 +0200

winex11.drv: Destroy old clipping message window if it has been replaced.

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.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winex11.drv/mouse.c  | 12 ++++++++++--
 dlls/winex11.drv/window.c |  2 +-
 dlls/winex11.drv/x11drv.h |  2 +-
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 8d1dc5e35d..15e5c04a41 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -502,7 +502,7 @@ BOOL CDECL X11DRV_ClipCursor( const RECT *clip );
  *
  * Notification function called upon receiving a WM_X11DRV_CLIP_CURSOR.
  */
-LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd )
+LRESULT clip_cursor_notify( HWND hwnd, HWND prev_clip_hwnd, HWND new_clip_hwnd )
 {
     struct x11drv_thread_data *data = x11drv_init_thread_data();
 
@@ -513,7 +513,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) TRACE( "clip hwnd changed from %p to %p\n", prev, new_clip_hwnd );
-        if (prev) SendNotifyMessageW( prev, WM_X11DRV_CLIP_CURSOR, 0, 0 );
+        if (prev) SendNotifyMessageW( prev, WM_X11DRV_CLIP_CURSOR, (WPARAM)prev, 0 );
     }
     else if (hwnd == data->clip_hwnd)  /* this is a notification that clipping has been reset */
     {
@@ -530,6 +530,14 @@ LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd )
         GetClipCursor( &clip );
         X11DRV_ClipCursor( &clip );
     }
+    else if (prev_clip_hwnd)
+    {
+        /* This is a notification send by the desktop window to an old
+         * dangling clip window.
+         */
+        TRACE( "destroying old clip hwnd %p\n", prev_clip_hwnd );
+        DestroyWindow( prev_clip_hwnd );
+    }
     return 0;
 }
 
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index c97cc6a9e0..e1f1d30170 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2737,7 +2737,7 @@ LRESULT CDECL X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
             set_window_cursor( x11drv_thread_data()->clip_window, (HCURSOR)lp );
         return 0;
     case WM_X11DRV_CLIP_CURSOR:
-        return clip_cursor_notify( hwnd, (HWND)lp );
+        return clip_cursor_notify( hwnd, (HWND)wp, (HWND)lp );
     default:
         FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp );
         return 0;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index d4e476facb..9ac83e57b1 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -621,7 +621,7 @@ extern void X11DRV_InitClipboard(void) DECLSPEC_HIDDEN;
 extern void CDECL X11DRV_SetFocus( HWND hwnd ) DECLSPEC_HIDDEN;
 extern void set_window_cursor( Window window, HCURSOR handle ) DECLSPEC_HIDDEN;
 extern void sync_window_cursor( Window window ) DECLSPEC_HIDDEN;
-extern LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd ) DECLSPEC_HIDDEN;
+extern LRESULT clip_cursor_notify( HWND hwnd, HWND prev_clip_hwnd, HWND new_clip_hwnd ) DECLSPEC_HIDDEN;
 extern void ungrab_clipping_window(void) DECLSPEC_HIDDEN;
 extern void reset_clipping_window(void) DECLSPEC_HIDDEN;
 extern void retry_grab_clipping_window(void) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list