[5/6] user32: Set capture on the owner of popup menus.

Vincent Povirk madewokherd at gmail.com
Thu Mar 6 17:08:00 CST 2014


The inability to set capture on a hidden window are specific to X, so
this moves the work-around to the X driver.
-------------- next part --------------
From 29c66b65886c6329f00b2baadf8c6cb09d02b8e6 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Thu, 6 Mar 2014 15:30:46 -0600
Subject: [PATCH 5/6] user32: Set capture on the owner of popup menus.

---
 dlls/user32/menu.c        |  5 ++---
 dlls/user32/tests/msg.c   |  2 +-
 dlls/winex11.drv/window.c | 21 ++++++++++++++++++++-
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 8bb508d..9b80a2b 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -3032,9 +3032,8 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
 
     if (wFlags & TF_ENDMENU) fEndMenu = TRUE;
 
-    /* owner may not be visible when tracking a popup, so use the menu itself */
-    capture_win = (wFlags & TPM_POPUPMENU) ? menu->hWnd : mt.hOwnerWnd;
-    set_capture_window( capture_win, GUI_INMENUMODE, NULL );
+    capture_win = mt.hOwnerWnd;
+    set_capture_window( capture_win, GUI_INMENUMODE | ((wFlags & TPM_POPUPMENU) ? GUI_POPUPMENUMODE : 0), NULL );
 
     __TRY while (!fEndMenu)
     {
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 9c1320d..56fa2b8 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -14334,7 +14334,7 @@ static void test_TrackPopupMenu(void)
     flush_events();
     flush_sequence();
     ret = TrackPopupMenu(hpopupmenu, 0, 100,100, 0, hwnd, NULL);
-    ok_sequence(WmTrackPopupMenu, "TrackPopupMenu", TRUE);
+    ok_sequence(WmTrackPopupMenu, "TrackPopupMenu", FALSE);
     ok(ret == 1, "TrackPopupMenu failed with error %i\n", GetLastError());
 
     DestroyMenu(hpopupmenu);
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 4da361a..d47624f 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2057,6 +2057,19 @@ BOOL CDECL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
 }
 
 
+BOOL CALLBACK find_popup_menu_window(HWND hwnd, LPARAM lparam)
+{
+    HWND *result = (HWND*)lparam;
+
+    if (GetClassLongW(hwnd, GCW_ATOM) == MAKEINTATOM(32768))
+    {
+        *result = hwnd;
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
 /***********************************************************************
  *		SetCapture  (X11DRV.@)
  */
@@ -2069,7 +2082,13 @@ void CDECL X11DRV_SetCapture( HWND hwnd, UINT flags )
 
     if (hwnd)
     {
-        Window grab_win = X11DRV_get_whole_window( GetAncestor( hwnd, GA_ROOT ) );
+        Window grab_win;
+
+        if (flags & GUI_POPUPMENUMODE)
+            /* owner may not be visible when tracking a popup, so use the menu itself */
+            EnumThreadWindows(GetCurrentThreadId(), find_popup_menu_window, (LPARAM)&hwnd);
+
+        grab_win = X11DRV_get_whole_window( GetAncestor( hwnd, GA_ROOT ) );
 
         if (!grab_win) return;
         XFlush( gdi_display );
-- 
1.8.3.2



More information about the wine-patches mailing list