[Win32SS]
[reactos.git] / reactos / win32ss / user / ntuser / focus.c
index e62f0ab..82d64df 100644 (file)
@@ -2,7 +2,7 @@
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS Win32k subsystem
  * PURPOSE:          Focus functions
- * FILE:             subsystems/win32/win32k/ntuser/focus.c
+ * FILE:             win32ss/user/ntuser/focus.c
  * PROGRAMER:        ReactOS Team
  */
 
@@ -62,11 +62,11 @@ co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd)
       if (co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0)) //(LPARAM)hWnd))
       {
          co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE,
-                    MAKEWPARAM(WA_INACTIVE, WndPrev->style & WS_MINIMIZE),
+                    MAKEWPARAM(WA_INACTIVE, (WndPrev->style & WS_MINIMIZE) != 0),
                     (LPARAM)hWnd);
 
          if (WndPrev)
-            WndPrev->state &= ~WNDS_ACTIVEFRAME;
+            WndPrev->state &= ~(WNDS_ACTIVEFRAME|WNDS_HASCAPTION);
       }
       else
       {
@@ -165,7 +165,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO
                 }
                 phwndCurrent++;
             }
-            ExFreePool(phwndTopLevel);
+            ExFreePoolWithTag(phwndTopLevel, USERTAG_WINDOWLIST);
           }
       }
       ////
@@ -248,7 +248,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO
 
       co_IntSendMessage( UserHMGetHandle(Window),
                          WM_ACTIVATE,
-                         MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, Window->style & WS_MINIMIZE),
+                         MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, (Window->style & WS_MINIMIZE) != 0),
                         (LPARAM)(WindowPrev ? UserHMGetHandle(WindowPrev) : 0));
 
       if (Window->spwndParent == UserGetDesktopWindow() &&
@@ -337,10 +337,16 @@ FindRemoveAsyncMsg(PWND Wnd, WPARAM wParam)
           Message->Msg.hwnd == UserHMGetHandle(Wnd) &&
           Message->Msg.wParam == wParam)
       {
-         ERR("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd, !!wParam);
+         WARN("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd, !!wParam);
          RemoveEntryList(&Message->ListEntry); // Purge the entry.
          ClearMsgBitsMask(pti, Message->QS_Flags);
-         ExFreePoolWithTag(Message, TAG_USRMSG);
+         InsertTailList(&usmList, &Message->ListEntry);
+         /* Notify the sender. */
+         if (Message->pkCompletionEvent != NULL)
+         {
+            KeSetEvent(Message->pkCompletionEvent, IO_NO_INCREMENT, FALSE);
+         }
+         FreeUserMessage(Message);
       }
    }
 }
@@ -416,7 +422,7 @@ CanForceFG(PPROCESSINFO ppi)
 static
 BOOL FASTCALL
 co_IntSetForegroundAndFocusWindow(
-    _In_ PWND Wnd,
+    _In_opt_ PWND Wnd,
     _In_ BOOL MouseActivate)
 {
    HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
@@ -529,7 +535,9 @@ co_IntSetForegroundAndFocusWindow(
    else
    {
        //ERR("Activate Not same PQ and WQ and Wnd.\n");
-       co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
+       //// CORE-10785 fix hang, ROSTESTS-208 allows test to run.
+       ////  co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
+       co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
        Ret = TRUE;
    }
    return Ret && fgRet;
@@ -700,7 +708,7 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async)
    }
 
    // FIXME: Used in the menu loop!!!
-   //ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
+   ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
 
    //ERR("co_IntSetActiveWindow Exit\n");
    if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED;
@@ -717,6 +725,8 @@ co_IntMouseActivateWindow(PWND Wnd)
 BOOL FASTCALL
 UserSetActiveWindow(PWND Wnd)
 {
+  PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+
   if (Wnd) // Must have a window!
   {
      if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
@@ -734,7 +744,34 @@ UserSetActiveWindow(PWND Wnd)
      SetActiveWindow(0);
      check_wnd_state(0, 0, 0, 0); <-- This should pass if ShowWindow does it's job!!! As of 10/28/2012 it does!
 
+     Now Handle wines Msg.c test_SetActiveWindow( 0 )...
   */
+  TRACE("USAW: Previous active window\n");
+  if (  gpqForegroundPrev &&
+        gpqForegroundPrev->spwndActivePrev &&
+       (gpqForegroundPrev->spwndActivePrev->style & (WS_VISIBLE|WS_DISABLED)) == WS_VISIBLE  &&
+      !(gpqForegroundPrev->spwndActivePrev->state2 & WNDS2_BOTTOMMOST) &&
+       (Wnd = VerifyWnd(gpqForegroundPrev->spwndActivePrev)) != NULL )
+  {
+     TRACE("USAW:PAW hwnd %p\n",Wnd?Wnd->head.h:NULL);
+     return co_IntSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
+  }
+
+  // Activate anyone but the active window.
+  if ( pti->MessageQueue->spwndActive &&
+      (Wnd = VerifyWnd(pti->MessageQueue->spwndActive)) != NULL )
+  {
+      ERR("USAW:AOWM hwnd %p\n",Wnd?Wnd->head.h:NULL);
+      if (!ActivateOtherWindowMin(Wnd))
+      {
+         // Okay, now go find someone else to play with!
+         ERR("USAW: Going to WPAOW\n");
+         co_WinPosActivateOtherWindow(Wnd);
+      }
+      return TRUE;
+  }
+
+  TRACE("USAW: Nothing\n");
   return FALSE;
 }
 
@@ -776,6 +813,7 @@ co_UserSetFocus(PWND Window)
       {
          if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0;
          if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
+         if (pwndTop->spwndParent == NULL) break;
       }
       ////
       if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev))
@@ -899,7 +937,7 @@ co_UserSetCapture(HWND hWnd)
    {
       if (Window->head.pti->MessageQueue != ThreadQueue)
       {
-         ERR("Window Thread dos not match Current!\n");
+         ERR("Window Thread does not match Current!\n");
          return NULL;
       }
    }
@@ -916,7 +954,11 @@ co_UserSetCapture(HWND hWnd)
    if (Window)
       IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
 
-   if (hWndPrev && hWndPrev != hWnd)
+   //
+   // Only send the message if we have a previous Window!
+   // Fix msg_menu tracking popup menu and win test_capture_4!!!!
+   //
+   if (hWndPrev)
    {
       if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED;