[PATCH 2/2] user32: Process internal messages before changing active window.

Rémi Bernon rbernon at codeweavers.com
Wed Jan 22 11:38:07 CST 2020


This makes set_active_window calls process the pending internal
WM_WINE_SETACTIVEWINDOW messages first.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/user32/focus.c        | 21 +++++++++++++--------
 dlls/user32/message.c      |  2 +-
 dlls/user32/tests/win.c    |  1 -
 dlls/user32/user_private.h |  1 +
 4 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/dlls/user32/focus.c b/dlls/user32/focus.c
index f1c883167ed..f2f972ef1a9 100644
--- a/dlls/user32/focus.c
+++ b/dlls/user32/focus.c
@@ -74,13 +74,18 @@ static HWND set_focus_window( HWND hwnd )
 /*******************************************************************
  *		set_active_window
  */
-static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
+BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus, BOOL sent )
 {
-    HWND previous = GetActiveWindow();
+    MSG msg;
+    HWND previous;
     BOOL ret;
     DWORD old_thread, new_thread;
     CBTACTIVATESTRUCT cbt;
 
+    /* process pending WM_WINE_SETACTIVEWINDOW messages first */
+    if (!sent) PeekMessageW( &msg, 0, 0, 0, QS_SENDMESSAGE );
+
+    previous = GetActiveWindow();
     if (previous == hwnd)
     {
         if (prev) *prev = hwnd;
@@ -200,14 +205,14 @@ static BOOL set_foreground_window( HWND hwnd, BOOL mouse )
     if (ret && previous != hwnd)
     {
         if (send_msg_old)  /* old window belongs to other thread */
-            SendNotifyMessageW( previous, WM_WINE_SETACTIVEWINDOW, 0, 0 );
+            SendNotifyMessageW( previous, WM_WINE_SETACTIVEWINDOW, 0, mouse );
         else if (send_msg_new)  /* old window belongs to us but new one to other thread */
-            ret = set_active_window( 0, NULL, mouse, TRUE );
+            ret = set_active_window( 0, NULL, mouse, TRUE, FALSE );
 
         if (send_msg_new)  /* new window belongs to other thread */
-            SendNotifyMessageW( hwnd, WM_WINE_SETACTIVEWINDOW, (WPARAM)hwnd, 0 );
+            SendNotifyMessageW( hwnd, WM_WINE_SETACTIVEWINDOW, (WPARAM)hwnd, mouse );
         else  /* new window belongs to us */
-            ret = set_active_window( hwnd, NULL, mouse, TRUE );
+            ret = set_active_window( hwnd, NULL, mouse, TRUE, FALSE );
     }
     return ret;
 }
@@ -249,7 +254,7 @@ HWND WINAPI SetActiveWindow( HWND hwnd )
             return GetActiveWindow();  /* Windows doesn't seem to return an error here */
     }
 
-    if (!set_active_window( hwnd, &prev, FALSE, TRUE )) return 0;
+    if (!set_active_window( hwnd, &prev, FALSE, TRUE, FALSE )) return 0;
     return prev;
 }
 
@@ -296,7 +301,7 @@ HWND WINAPI SetFocus( HWND hwnd )
         /* activate hwndTop if needed. */
         if (hwndTop != GetActiveWindow())
         {
-            if (!set_active_window( hwndTop, NULL, FALSE, FALSE )) return 0;
+            if (!set_active_window( hwndTop, NULL, FALSE, FALSE, FALSE )) return 0;
             if (!IsWindow( hwnd )) return 0;  /* Abort if window destroyed */
 
             /* Do not change focus if the window is no longer active */
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 1336865112a..84de851085b 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -1874,7 +1874,7 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR
         return WIN_SetStyle(hwnd, wparam, lparam);
     case WM_WINE_SETACTIVEWINDOW:
         if (!wparam && GetForegroundWindow() == hwnd) return 0;
-        return (LRESULT)SetActiveWindow( (HWND)wparam );
+        return (LRESULT)set_active_window( (HWND)wparam, NULL, lparam, TRUE, TRUE );
     case WM_WINE_KEYBOARD_LL_HOOK:
     case WM_WINE_MOUSE_LL_HOOK:
     {
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 38fcada570c..de31de84617 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -3271,7 +3271,6 @@ static DWORD WINAPI create_window_thread(void *param)
     SetForegroundWindow(p->other_window);
     check_active_state(p->other_window, p->other_window, p->other_window);
     while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
-    todo_wine
     check_active_state(p->other_window, p->other_window, p->other_window);
 
     res = WaitForSingleObject(p->test_finished, INFINITE);
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 7e294558ef1..115503eb38d 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -231,6 +231,7 @@ struct tagWND;
 
 extern void CLIPBOARD_ReleaseOwner( HWND hwnd ) DECLSPEC_HIDDEN;
 extern BOOL FOCUS_MouseActivate( HWND hwnd ) DECLSPEC_HIDDEN;
+extern BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus, BOOL sent ) DECLSPEC_HIDDEN;
 extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) DECLSPEC_HIDDEN;
 extern void free_dce( struct dce *dce, HWND hwnd ) DECLSPEC_HIDDEN;
 extern void invalidate_dce( struct tagWND *win, const RECT *rect ) DECLSPEC_HIDDEN;
-- 
2.25.0




More information about the wine-devel mailing list