diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index 3183a33c6a6..5eb4fc8ab4b 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -1500,28 +1500,17 @@ NS_IMETHODIMP nsWindow::SetSizeMode(PRInt32 aMode) { case nsSizeMode_Maximized : mode = SW_MAXIMIZE; break; + case nsSizeMode_Minimized : + // Using SW_SHOWMINIMIZED prevents the working set from being trimmed but + // keeps the window active in the tray. So after the window is minimized, + // windows will fire WM_WINDOWPOSCHANGED (OnWindowPosChanged) at which point + // we will do some additional processing to get the active window set right. + // If sTrimOnMinimize is set, we let windows handle minimization normally + // using SW_MINIMIZE. mode = sTrimOnMinimize ? SW_MINIMIZE : SW_SHOWMINIMIZED; - if (!sTrimOnMinimize) { - // Find the next window that is enabled, visible, and not minimized. - HWND hwndBelow = ::GetNextWindow(mWnd, GW_HWNDNEXT); - while (hwndBelow && (!::IsWindowEnabled(hwndBelow) || !::IsWindowVisible(hwndBelow) || - ::IsIconic(hwndBelow))) { - hwndBelow = ::GetNextWindow(hwndBelow, GW_HWNDNEXT); - } - - // Push ourselves to the bottom of the stack, then activate the - // next window. - ::SetWindowPos(mWnd, HWND_BOTTOM, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - if (hwndBelow) - ::SetForegroundWindow(hwndBelow); - - // Play the minimize sound while we're here, since that is also - // forgotten when we use SW_SHOWMINIMIZED. - ::PlaySoundW(L"Minimize", nsnull, SND_ALIAS | SND_NODEFAULT | SND_ASYNC); - } break; + default : mode = SW_RESTORE; } @@ -4831,7 +4820,7 @@ BOOL nsWindow::OnInputLangChange(HKL aHKL) return PR_FALSE; // always pass to child window } -#if !defined(WINCE) +#if !defined(WINCE) // implemented in nsWindowCE.cpp void nsWindow::OnWindowPosChanged(WINDOWPOS *wp, PRBool& result) { if (wp == nsnull) @@ -4878,6 +4867,14 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS *wp, PRBool& result) // to window docking. (bug 489258) mSizeMode = event.mSizeMode; + // If !sTrimOnMinimize, we minimize windows using SW_SHOWMINIMIZED (See + // SetSizeMode for internal calls, and WM_SYSCOMMAND for external). This + // prevents the working set from being trimmed but keeps the window active. + // After the window is minimized, we need to do some touch up work on the + // active window. (bugs 76831 & 499816) + if (!sTrimOnMinimize && nsSizeMode_Minimized == event.mSizeMode) + ActivateOtherWindowHelper(mWnd); + #ifdef WINSTATE_DEBUG_OUTPUT switch (mSizeMode) { case nsSizeMode_Normal: @@ -4974,6 +4971,28 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS *wp, PRBool& result) result = OnResize(rect); } } + +// static +void nsWindow::ActivateOtherWindowHelper(HWND aWnd) +{ + // Find the next window that is enabled, visible, and not minimized. + HWND hwndBelow = ::GetNextWindow(aWnd, GW_HWNDNEXT); + while (hwndBelow && (!::IsWindowEnabled(hwndBelow) || !::IsWindowVisible(hwndBelow) || + ::IsIconic(hwndBelow))) { + hwndBelow = ::GetNextWindow(hwndBelow, GW_HWNDNEXT); + } + + // Push ourselves to the bottom of the stack, then activate the + // next window. + ::SetWindowPos(aWnd, HWND_BOTTOM, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); + if (hwndBelow) + ::SetForegroundWindow(hwndBelow); + + // Play the minimize sound while we're here, since that is also + // forgotten when we use SW_SHOWMINIMIZED. + ::PlaySoundW(L"Minimize", nsnull, SND_ALIAS | SND_NODEFAULT | SND_ASYNC); +} #endif // !defined(WINCE) #if !defined(WINCE) diff --git a/widget/src/windows/nsWindow.h b/widget/src/windows/nsWindow.h index aa4c8f4017b..2b03c202cc0 100644 --- a/widget/src/windows/nsWindow.h +++ b/widget/src/windows/nsWindow.h @@ -394,7 +394,9 @@ protected: PRBool aIntersectWithExisting); nsCOMPtr GetRegionToPaint(PRBool aForceFullRepaint, PAINTSTRUCT ps, HDC aDC); - +#if !defined(WINCE) + static void ActivateOtherWindowHelper(HWND aWnd); +#endif #ifdef ACCESSIBILITY static STDMETHODIMP_(LRESULT) LresultFromObject(REFIID riid, WPARAM wParam, LPUNKNOWN pAcc); #endif // ACCESSIBILITY