diff --git a/content/base/public/nsIFrameLoader.idl b/content/base/public/nsIFrameLoader.idl index 0d1bc55a182..db6f49a9def 100644 --- a/content/base/public/nsIFrameLoader.idl +++ b/content/base/public/nsIFrameLoader.idl @@ -141,7 +141,7 @@ interface nsIContentViewManager : nsISupports readonly attribute nsIContentView rootContentView; }; -[scriptable, uuid(13c512d6-fba0-402a-9244-fe7941c43965)] +[scriptable, uuid(12905a29-4246-475a-81d4-fc389197df02)] interface nsIFrameLoader : nsISupports { /** @@ -187,6 +187,12 @@ interface nsIFrameLoader : nsISupports */ void activateRemoteFrame(); + /** + * Deactivate remote frame. + * Throws an exception with non-remote frames. + */ + void deactivateRemoteFrame(); + /** * @see nsIDOMWindowUtils sendMouseEvent. */ diff --git a/content/base/src/nsFrameLoader.cpp b/content/base/src/nsFrameLoader.cpp index 08218d521f5..7ab32bfe550 100644 --- a/content/base/src/nsFrameLoader.cpp +++ b/content/base/src/nsFrameLoader.cpp @@ -1771,6 +1771,15 @@ nsFrameLoader::ActivateRemoteFrame() { return NS_ERROR_UNEXPECTED; } +NS_IMETHODIMP +nsFrameLoader::DeactivateRemoteFrame() { + if (mRemoteBrowser) { + mRemoteBrowser->Deactivate(); + return NS_OK; + } + return NS_ERROR_UNEXPECTED; +} + NS_IMETHODIMP nsFrameLoader::SendCrossProcessMouseEvent(const nsAString& aType, float aX, diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index f57189c8fb9..2023b84732c 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -34,6 +34,8 @@ * * ***** END LICENSE BLOCK ***** */ +#include "mozilla/dom/TabParent.h" + #include "nsFocusManager.h" #include "nsIInterfaceRequestor.h" @@ -1531,14 +1533,14 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear, NotifyFocusStateChange(content, shouldShowFocusRing, PR_FALSE); } - // if an object/plug-in is being blurred, move the system focus to the - // parent window, otherwise events will still get fired at the plugin. + // if an object/plug-in/remote browser is being blurred, move the system focus + // to the parent window, otherwise events will still get fired at the plugin. // But don't do this if we are blurring due to the window being lowered, // otherwise, the parent window can get raised again. - if (mActiveWindow && aAdjustWidgets) { + if (mActiveWindow) { nsIFrame* contentFrame = content->GetPrimaryFrame(); nsIObjectFrame* objectFrame = do_QueryFrame(contentFrame); - if (objectFrame) { + if (aAdjustWidgets && objectFrame) { // note that the presshell's widget is being retrieved here, not the one // for the object frame. nsIViewManager* vm = presShell->GetViewManager(); @@ -1549,6 +1551,15 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear, widget->SetFocus(PR_FALSE); } } + + // if the object being blurred is a remote browser, deactivate remote content + TabParent* remote = GetRemoteForContent(content); + if (remote) { + remote->Deactivate(); + #ifdef DEBUG_FOCUS + printf("*Remote browser deactivated\n"); + #endif + } } } @@ -1746,12 +1757,21 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow, NotifyFocusStateChange(aContent, aWindow->ShouldShowFocusRing(), PR_TRUE); - // if this is an object/plug-in, focus the plugin's widget. Note that we might + // if this is an object/plug-in/remote browser, focus its widget. Note that we might // no longer be in the same document, due to the events we fired above when // aIsNewDocument. - if (aAdjustWidgets && presShell->GetDocument() == aContent->GetDocument()) { - if (objectFrameWidget) + if (presShell->GetDocument() == aContent->GetDocument()) { + if (aAdjustWidgets && objectFrameWidget) objectFrameWidget->SetFocus(PR_FALSE); + + // if the object being focused is a remote browser, activate remote content + TabParent* remote = GetRemoteForContent(aContent); + if (remote) { + remote->Activate(); +#ifdef DEBUG_FOCUS + printf("*Remote browser activated\n"); +#endif + } } PRUint32 reason = GetFocusMoveReason(aFlags); @@ -2948,6 +2968,28 @@ nsFocusManager::GetRootForFocus(nsPIDOMWindow* aWindow, return rootElement; } +TabParent* +nsFocusManager::GetRemoteForContent(nsIContent* aContent) { + if (!aContent || + aContent->Tag() != nsGkAtoms::browser || + !aContent->IsXUL() || + !aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::Remote, + nsGkAtoms::_true, eIgnoreCase)) + return nsnull; + + nsCOMPtr loaderOwner = do_QueryInterface(aContent); + if (!loaderOwner) + return nsnull; + + nsRefPtr frameLoader = loaderOwner->GetFrameLoader(); + if (!frameLoader) + return nsnull; + + PBrowserParent* remoteBrowser = frameLoader->GetRemoteBrowser(); + TabParent* remote = static_cast(remoteBrowser); + return remote; +} + void nsFocusManager::GetLastDocShell(nsIDocShellTreeItem* aItem, nsIDocShellTreeItem** aResult) diff --git a/dom/base/nsFocusManager.h b/dom/base/nsFocusManager.h index 737187b9540..5aa0c718075 100644 --- a/dom/base/nsFocusManager.h +++ b/dom/base/nsFocusManager.h @@ -49,6 +49,13 @@ class nsIDocShellTreeItem; class nsPIDOMWindow; + +namespace mozilla { +namespace dom { + class TabParent; +} +} + struct nsDelayedBlurOrFocusEvent; /** @@ -424,6 +431,12 @@ protected: PRBool aIsForDocNavigation, PRBool aCheckVisibility); + /** + * Get the TabParent associated with aContent if it is a remote browser, + * or null in all other cases. + */ + mozilla::dom::TabParent* GetRemoteForContent(nsIContent* aContent); + /** * Get the last docshell child of aItem and return it in aResult. */ diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 0be8db40034..abcb2c7b9f2 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -241,6 +241,8 @@ child: */ Activate(); + Deactivate(); + /** * @see nsIDOMWindowUtils sendMouseEvent. */ diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 140e2adc6b6..d414468672d 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -556,6 +556,13 @@ TabChild::RecvActivate() return true; } +bool TabChild::RecvDeactivate() +{ + nsCOMPtr browser = do_QueryInterface(mWebNav); + browser->Deactivate(); + return true; +} + bool TabChild::RecvMouseEvent(const nsString& aType, const float& aX, diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index f840dcd6608..dc6462db358 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -180,6 +180,7 @@ public: virtual bool RecvShow(const nsIntSize& size); virtual bool RecvMove(const nsIntSize& size); virtual bool RecvActivate(); + virtual bool RecvDeactivate(); virtual bool RecvMouseEvent(const nsString& aType, const float& aX, const float& aY, diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 1cddde7eba9..e6bd3bb0b4f 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -219,6 +219,12 @@ TabParent::Activate() unused << SendActivate(); } +void +TabParent::Deactivate() +{ + unused << SendDeactivate(); +} + NS_IMETHODIMP TabParent::Init(nsIDOMWindow *window) { diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 4d130d07048..5671acd4a30 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -127,6 +127,7 @@ public: void Show(const nsIntSize& size); void Move(const nsIntSize& size); void Activate(); + void Deactivate(); void SendMouseEvent(const nsAString& aType, float aX, float aY, PRInt32 aButton, PRInt32 aClickCount, PRInt32 aModifiers, PRBool aIgnoreRootScrollFrame);