diff --git a/browser/base/content/test/general/browser_windowactivation.js b/browser/base/content/test/general/browser_windowactivation.js index 481d80818d51..08bb02dd7a21 100644 --- a/browser/base/content/test/general/browser_windowactivation.js +++ b/browser/base/content/test/general/browser_windowactivation.js @@ -11,6 +11,10 @@ let browser1, browser2; function test() { waitForExplicitFinish(); + waitForFocus(reallyRunTests); +} + +function reallyRunTests() { let tab1 = gBrowser.addTab(); let tab2 = gBrowser.addTab(); diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index 3e028ae197c1..54a9c460b523 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -38,6 +38,7 @@ #include "nsBindingManager.h" #include "nsStyleCoord.h" #include "SelectionCarets.h" +#include "TabChild.h" #include "mozilla/ContentEvents.h" #include "mozilla/dom/Element.h" @@ -174,7 +175,6 @@ static const char* kObservedPrefs[] = { }; nsFocusManager::nsFocusManager() - : mParentFocusType(ParentFocusType_Ignore) { } nsFocusManager::~nsFocusManager() @@ -712,7 +712,7 @@ nsFocusManager::WindowRaised(nsIDOMWindow* aWindow) // If this is a parent or single process window, send the activate event. // Events for child process windows will be sent when ParentActivated // is called. - if (mParentFocusType == ParentFocusType_Ignore) { + if (XRE_GetProcessType() == GeckoProcessType_Default) { ActivateOrDeactivate(window, true); } @@ -777,7 +777,7 @@ nsFocusManager::WindowLowered(nsIDOMWindow* aWindow) // If this is a parent or single process window, send the deactivate event. // Events for child process windows will be sent when ParentActivated // is called. - if (mParentFocusType == ParentFocusType_Ignore) { + if (XRE_GetProcessType() == GeckoProcessType_Default) { ActivateOrDeactivate(window, false); } @@ -889,6 +889,11 @@ nsFocusManager::WindowShown(nsIDOMWindow* aWindow, bool aNeedsFocus) } #endif + if (nsCOMPtr child = do_GetInterface(window->GetDocShell())) { + bool active = static_cast(child.get())->ParentIsActive(); + ActivateOrDeactivate(window, active); + } + if (mFocusedWindow != window) return NS_OK; @@ -906,10 +911,6 @@ nsFocusManager::WindowShown(nsIDOMWindow* aWindow, bool aNeedsFocus) EnsureCurrentWidgetFocused(); } - if (mParentFocusType == ParentFocusType_Active) { - ActivateOrDeactivate(window, true); - } - return NS_OK; } @@ -1077,7 +1078,6 @@ nsFocusManager::ParentActivated(nsIDOMWindow* aWindow, bool aActive) window = window->GetOuterWindow(); - mParentFocusType = aActive ? ParentFocusType_Active : ParentFocusType_Inactive; ActivateOrDeactivate(window, aActive); return NS_OK; } diff --git a/dom/base/nsFocusManager.h b/dom/base/nsFocusManager.h index 476440157606..e14e4a7447ca 100644 --- a/dom/base/nsFocusManager.h +++ b/dom/base/nsFocusManager.h @@ -26,12 +26,6 @@ class nsIMessageBroadcaster; struct nsDelayedBlurOrFocusEvent; -enum ParentFocusType { - ParentFocusType_Ignore, // Parent or single process window or unknown - ParentFocusType_Active, // Child process window in active parent - ParentFocusType_Inactive, // Child process window in inactive parent -}; - /** * The focus manager keeps track of where the focus is, that is, the node * which receives key events. @@ -97,11 +91,6 @@ public: */ void UpdateCaretForCaretBrowsingMode(); - bool IsParentActivated() - { - return mParentFocusType == ParentFocusType_Active; - } - /** * Returns the content node that would be focused if aWindow was in an * active window. This will traverse down the frame hierarchy, starting at @@ -549,9 +538,6 @@ private: // moving focus. nsCOMPtr mMouseButtonEventHandlingDocument; - // Indicates a child process that is in an active window. - ParentFocusType mParentFocusType; - static bool sTestMode; // the single focus manager diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index 77fdeac2990e..2105442c3c46 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -53,7 +53,8 @@ #include "nsISHistory.h" #include "nsNullPrincipal.h" #include "nsIScriptError.h" - +#include "nsGlobalWindow.h" +#include "nsPIWindowRoot.h" #include "nsLayoutUtils.h" #include "nsView.h" @@ -898,7 +899,17 @@ nsFrameLoader::ShowRemoteFrame(const nsIntSize& size, return false; } - mRemoteBrowser->Show(size); + nsPIDOMWindow* win = mOwnerContent->OwnerDoc()->GetWindow(); + bool parentIsActive = false; + if (win) { + nsCOMPtr windowRoot = + static_cast(win)->GetTopWindowRoot(); + if (windowRoot) { + nsPIDOMWindow* topWin = windowRoot->GetWindow(); + parentIsActive = topWin && topWin->IsActive(); + } + } + mRemoteBrowser->Show(size, parentIsActive); mRemoteBrowserShown = true; EnsureMessageManager(); diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index e6e62406b7ea..4cb01457a918 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1227,12 +1227,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) if (sWindowsById) { sWindowsById->Put(mWindowID, this); } - - // Ensure that the current active state is initialized for child process windows. - nsFocusManager* fm = nsFocusManager::GetFocusManager(); - if (fm) { - mIsActive = fm->IsParentActivated(); - } } #ifdef DEBUG diff --git a/dom/base/nsWindowRoot.cpp b/dom/base/nsWindowRoot.cpp index e4c811991458..c8fa76ed991e 100644 --- a/dom/base/nsWindowRoot.cpp +++ b/dom/base/nsWindowRoot.cpp @@ -34,6 +34,7 @@ using namespace mozilla::dom; nsWindowRoot::nsWindowRoot(nsPIDOMWindow* aWindow) { mWindow = aWindow; + MOZ_ASSERT(mWindow->IsOuterWindow()); } nsWindowRoot::~nsWindowRoot() diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index ed10a436a606..4721f7db6571 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -468,7 +468,8 @@ child: ScrollingBehavior scrolling, TextureFactoryIdentifier textureFactoryIdentifier, uint64_t layersId, - nullable PRenderFrame renderFrame); + nullable PRenderFrame renderFrame, + bool parentIsActive); LoadURL(nsCString uri); diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index fd587203205d..186272362de0 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -880,6 +880,7 @@ TabChild::TabChild(nsIContentChild* aManager, , mDPI(0) , mDefaultScale(0) , mIPCOpen(true) + , mParentIsActive(false) { if (!sActiveDurationMsSet) { Preferences::AddIntVarCache(&sActiveDurationMs, @@ -1889,7 +1890,8 @@ TabChild::DoFakeShow(const ScrollingBehavior& aScrolling, PRenderFrameChild* aRenderFrame) { ShowInfo info(EmptyString(), false, false, 0, 0); - RecvShow(nsIntSize(0, 0), info, aScrolling, aTextureFactoryIdentifier, aLayersId, aRenderFrame); + RecvShow(nsIntSize(0, 0), info, aScrolling, aTextureFactoryIdentifier, + aLayersId, aRenderFrame, mParentIsActive); mDidFakeShow = true; } @@ -1991,12 +1993,14 @@ TabChild::RecvShow(const nsIntSize& aSize, const ScrollingBehavior& aScrolling, const TextureFactoryIdentifier& aTextureFactoryIdentifier, const uint64_t& aLayersId, - PRenderFrameChild* aRenderFrame) + PRenderFrameChild* aRenderFrame, + const bool& aParentIsActive) { MOZ_ASSERT((!mDidFakeShow && aRenderFrame) || (mDidFakeShow && !aRenderFrame)); if (mDidFakeShow) { ApplyShowInfo(aInfo); + RecvParentActivated(aParentIsActive); return true; } @@ -2022,6 +2026,7 @@ TabChild::RecvShow(const nsIntSize& aSize, bool res = InitTabChildGlobal(); ApplyShowInfo(aInfo); + RecvParentActivated(aParentIsActive); return res; } @@ -2272,6 +2277,8 @@ bool TabChild::RecvDeactivate() bool TabChild::RecvParentActivated(const bool& aActivated) { + mParentIsActive = aActivated; + nsFocusManager* fm = nsFocusManager::GetFocusManager(); NS_ENSURE_TRUE(fm, true); diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index d0a7b2beacb5..9bf664cea6f3 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -321,7 +321,8 @@ public: const ScrollingBehavior& aScrolling, const TextureFactoryIdentifier& aTextureFactoryIdentifier, const uint64_t& aLayersId, - PRenderFrameChild* aRenderFrame) MOZ_OVERRIDE; + PRenderFrameChild* aRenderFrame, + const bool& aParentIsActive) MOZ_OVERRIDE; virtual bool RecvUpdateDimensions(const nsIntRect& rect, const nsIntSize& size, const ScreenOrientation& orientation, @@ -500,6 +501,11 @@ public: bool IPCOpen() { return mIPCOpen; } + bool ParentIsActive() + { + return mParentIsActive; + } + protected: virtual ~TabChild(); @@ -665,6 +671,7 @@ private: float mDPI; double mDefaultScale; bool mIPCOpen; + bool mParentIsActive; DISALLOW_EVIL_CONSTRUCTORS(TabChild); }; diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 7167fdb83089..8fe360e9c5f6 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -763,7 +763,7 @@ TabParent::LoadURL(nsIURI* aURI) } void -TabParent::Show(const nsIntSize& size) +TabParent::Show(const nsIntSize& size, bool aParentIsActive) { // sigh mShown = true; @@ -809,7 +809,8 @@ TabParent::Show(const nsIntSize& size) info = ShowInfo(name, allowFullscreen, isPrivate, mDPI, mDefaultScale.scale); } - unused << SendShow(size, info, scrolling, textureFactoryIdentifier, layersId, renderFrame); + unused << SendShow(size, info, scrolling, textureFactoryIdentifier, + layersId, renderFrame, aParentIsActive); } bool diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 54f499ad1b19..55b69835ad51 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -235,7 +235,7 @@ public: // XXX/cjones: it's not clear what we gain by hiding these // message-sending functions under a layer of indirection and // eating the return values - void Show(const nsIntSize& size); + void Show(const nsIntSize& size, bool aParentIsActive); void UpdateDimensions(const nsIntRect& rect, const nsIntSize& size, const nsIntPoint& chromeDisp); void UpdateFrame(const layers::FrameMetrics& aFrameMetrics);