diff --git a/mozilla/dom/public/base/nsIFocusController.h b/mozilla/dom/public/base/nsIFocusController.h index 8dfa78a5f64..b8b930a833d 100644 --- a/mozilla/dom/public/base/nsIFocusController.h +++ b/mozilla/dom/public/base/nsIFocusController.h @@ -52,9 +52,9 @@ class nsIController; class nsIControllers; class nsAString; -// {da47ea2a-5e9a-4281-9b5b-a08c0e6b1fa5} +// {f9004db3-5272-4a8c-8b19-70a4adb8f8b6} #define NS_IFOCUSCONTROLLER_IID \ -{ 0xda47ea2a, 0x5e9a, 0x4281, { 0x9b, 0x5b, 0xa0, 0x8c, 0x0e, 0x6b, 0x1f, 0xa5 } } +{ 0xf9004db3, 0x5272, 0x4a8c, { 0x8b, 0x19, 0x70, 0xa4, 0xad, 0xb8, 0xf8, 0xb6 } } class nsIFocusController : public nsISupports { public: @@ -85,6 +85,7 @@ public: NS_IMETHOD GetControllers(nsIControllers** aResult)=0; NS_IMETHOD MoveFocus(PRBool aForward, nsIDOMElement* aElt)=0; + NS_IMETHOD RewindFocusState()=0; NS_IMETHOD ResetElementFocus() = 0; }; diff --git a/mozilla/dom/src/base/nsFocusController.cpp b/mozilla/dom/src/base/nsFocusController.cpp index 03fff642bbd..442b7c37ad2 100644 --- a/mozilla/dom/src/base/nsFocusController.cpp +++ b/mozilla/dom/src/base/nsFocusController.cpp @@ -142,6 +142,11 @@ nsFocusController::GetFocusedWindow(nsIDOMWindowInternal** aWindow) NS_IMETHODIMP nsFocusController::SetFocusedElement(nsIDOMElement* aElement) { + if (mCurrentElement) + mPreviousElement = mCurrentElement; + else if (aElement) + mPreviousElement = aElement; + mNeedUpdateCommands = mNeedUpdateCommands || mCurrentElement != aElement; mCurrentElement = aElement; @@ -154,6 +159,15 @@ nsFocusController::SetFocusedElement(nsIDOMElement* aElement) return NS_OK; } +NS_IMETHODIMP +nsFocusController::RewindFocusState() +{ + mCurrentElement = mPreviousElement; + mCurrentWindow = mPreviousWindow; + + return NS_OK; +} + NS_IMETHODIMP nsFocusController::SetFocusedWindow(nsIDOMWindowInternal* aWindow) { @@ -172,6 +186,12 @@ nsFocusController::SetFocusedWindow(nsIDOMWindowInternal* aWindow) basewin->SetFocus(); } + if (mCurrentWindow) { + mPreviousWindow = mCurrentWindow; + } else if (win) { + mPreviousWindow = win; + } + mNeedUpdateCommands = mNeedUpdateCommands || mCurrentWindow != win; mCurrentWindow = win; @@ -345,8 +365,10 @@ nsFocusController::Focus(nsIDOMEvent* aEvent) nsCOMPtr windowDoc; mCurrentWindow->GetDocument(getter_AddRefs(windowDoc)); if (ownerDoc != windowDoc) - mCurrentElement = nsnull; + mCurrentElement = mPreviousElement = nsnull; } + else + mPreviousElement = nsnull; if (!mCurrentElement) { UpdateCommands(); @@ -538,7 +560,7 @@ nsFocusController::SetActive(PRBool aActive) NS_IMETHODIMP nsFocusController::ResetElementFocus() { - mCurrentElement = nsnull; + mCurrentElement = mPreviousElement = nsnull; return NS_OK; } diff --git a/mozilla/dom/src/base/nsFocusController.h b/mozilla/dom/src/base/nsFocusController.h index 0b1f0b47eeb..7488945cfe5 100644 --- a/mozilla/dom/src/base/nsFocusController.h +++ b/mozilla/dom/src/base/nsFocusController.h @@ -94,6 +94,7 @@ public: NS_IMETHOD GetControllers(nsIControllers** aResult); NS_IMETHOD MoveFocus(PRBool aForward, nsIDOMElement* aElt); + NS_IMETHOD RewindFocusState(); NS_IMETHOD ResetElementFocus(); @@ -117,7 +118,9 @@ public: // Members protected: nsCOMPtr mCurrentElement; // [OWNER] + nsCOMPtr mPreviousElement; // [OWNER] nsCOMPtr mCurrentWindow; // [OWNER] + nsCOMPtr mPreviousWindow; // [OWNER] nsCOMPtr mPopupNode; // [OWNER] nsCOMPtr mPopupEvent; diff --git a/mozilla/widget/src/windows/nsWindow.cpp b/mozilla/widget/src/windows/nsWindow.cpp index 98f904e5168..dcc3f3a10f8 100644 --- a/mozilla/widget/src/windows/nsWindow.cpp +++ b/mozilla/widget/src/windows/nsWindow.cpp @@ -3832,6 +3832,8 @@ void nsWindow::ConstrainZLevel(HWND *aAfter) // Process all nsWindows messages // //------------------------------------------------------------------------- +static PRBool gJustGotDeactivate = PR_FALSE; +static PRBool gJustGotActivate = PR_FALSE; #ifdef NS_DEBUG @@ -4305,6 +4307,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT PRBool result = PR_FALSE; // call the default nsWindow proc static PRBool getWheelInfo = PR_TRUE; *aRetValue = 0; + PRBool isMozWindowTakingFocus = PR_TRUE; nsPaletteInfo palInfo; // Uncomment this to see all windows messages @@ -4864,15 +4867,17 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT PRInt32 fActive = LOWORD(wParam); if (WA_INACTIVE == fActive) { + gJustGotDeactivate = PR_TRUE; if (mIsTopWidgetWindow) mLastKeyboardLayout = gKeyboardLayout; } else { + gJustGotActivate = PR_TRUE; nsMouseEvent event(PR_TRUE, NS_MOUSE_ACTIVATE, this, nsMouseEvent::eReal); InitEvent(event); event.acceptActivation = PR_TRUE; - + PRBool result = DispatchWindowEvent(&event); NS_RELEASE(event.widget); @@ -4884,13 +4889,6 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT if (gSwitchKeyboardLayout && mLastKeyboardLayout) ActivateKeyboardLayout(mLastKeyboardLayout, 0); } - - // XXX We want DefWindowProc processing when switching between Mozilla - // windows. Otherwise, we might receive a WM_ACTIVATE without a - // following WM_SETFOCUS. Leverage on an undocumented finding where - // lParam is always NULL when switching between windows of different - // processes. - result = (HWND)lParam == NULL; } break; @@ -4963,29 +4961,20 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT ImmSetOpenStatus(hC, FALSE); } #endif - { - nsWindow* topWindow = GetNSWindowPtr(::GetAncestor(mWnd, GA_ROOT)); - - if ((HWND)wParam == NULL || - (topWindow && topWindow->mWnd != ::GetAncestor((HWND)wParam, GA_ROOT))) { - result = DispatchFocus(NS_DEACTIVATE, PR_FALSE); - } - else { - PRBool isMozWindowTakingFocus = PR_TRUE; - WCHAR className[kMaxClassNameLength]; - - ::GetClassNameW((HWND)wParam, className, kMaxClassNameLength); - if (wcscmp(className, kWClassNameUI) && - wcscmp(className, kWClassNameContent) && - wcscmp(className, kWClassNameContentFrame) && - wcscmp(className, kWClassNameDialog) && - wcscmp(className, kWClassNameGeneral)) { - isMozWindowTakingFocus = PR_FALSE; - } - - result = DispatchFocus(NS_LOSTFOCUS, isMozWindowTakingFocus); - } + WCHAR className[kMaxClassNameLength]; + ::GetClassNameW((HWND)wParam, className, kMaxClassNameLength); + if (wcscmp(className, kWClassNameUI) && + wcscmp(className, kWClassNameContent) && + wcscmp(className, kWClassNameContentFrame) && + wcscmp(className, kWClassNameDialog) && + wcscmp(className, kWClassNameGeneral)) { + isMozWindowTakingFocus = PR_FALSE; } + if (gJustGotDeactivate) { + gJustGotDeactivate = PR_FALSE; + result = DispatchFocus(NS_DEACTIVATE, isMozWindowTakingFocus); + } + result = DispatchFocus(NS_LOSTFOCUS, isMozWindowTakingFocus); break; case WM_WINDOWPOSCHANGED: @@ -5083,6 +5072,26 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT InitEvent(event); result = DispatchWindowEvent(&event); + + if (pl.showCmd == SW_SHOWMINIMIZED) { + // Deactivate + WCHAR className[kMaxClassNameLength]; + ::GetClassNameW((HWND)wParam, className, kMaxClassNameLength); + if (wcscmp(className, kWClassNameUI) && + wcscmp(className, kWClassNameContent) && + wcscmp(className, kWClassNameContentFrame) && + wcscmp(className, kWClassNameDialog) && + wcscmp(className, kWClassNameGeneral)) { + isMozWindowTakingFocus = PR_FALSE; + } + gJustGotDeactivate = PR_FALSE; + result = DispatchFocus(NS_DEACTIVATE, isMozWindowTakingFocus); + } else if (pl.showCmd == SW_SHOWNORMAL){ + // Make sure we're active + result = DispatchFocus(NS_GOTFOCUS, PR_TRUE); + result = DispatchFocus(NS_ACTIVATE, PR_TRUE); + } + NS_RELEASE(event.widget); } } diff --git a/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp b/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp index a822c4910b8..d102b43ebc5 100644 --- a/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp +++ b/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp @@ -353,6 +353,21 @@ nsWebShellWindow::HandleEvent(nsGUIEvent *aEvent) // the state and pass the event on to the OS. The day is coming // when we'll handle the event here, and the return result will // then need to be different. +#ifdef XP_WIN + // This is a nasty hack to get around the fact that win32 sends the kill focus + // event in a different sequence than the deactivate depending on if you're + // minimizing the window vs. just clicking in a different window to cause + // the deactivation. Bug #82534 + if(modeEvent->mSizeMode == nsSizeMode_Minimized) { + nsCOMPtr privateDOMWindow = do_GetInterface(docShell); + if(privateDOMWindow) { + nsIFocusController *focusController = + privateDOMWindow->GetRootFocusController(); + if (focusController) + focusController->RewindFocusState(); + } + } +#endif break; } case NS_OS_TOOLBAR: {