Bug 583976. Part 1 - Add focus manager support for focus activation/deactivation in remote content. r=enn,smaug

This commit is contained in:
Felipe Gomes 2011-06-17 17:08:32 -07:00
parent 527cbc1e43
commit 0a988c309a
9 changed files with 95 additions and 8 deletions

View File

@ -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.
*/

View File

@ -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,

View File

@ -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<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(aContent);
if (!loaderOwner)
return nsnull;
nsRefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
if (!frameLoader)
return nsnull;
PBrowserParent* remoteBrowser = frameLoader->GetRemoteBrowser();
TabParent* remote = static_cast<TabParent*>(remoteBrowser);
return remote;
}
void
nsFocusManager::GetLastDocShell(nsIDocShellTreeItem* aItem,
nsIDocShellTreeItem** aResult)

View File

@ -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.
*/

View File

@ -241,6 +241,8 @@ child:
*/
Activate();
Deactivate();
/**
* @see nsIDOMWindowUtils sendMouseEvent.
*/

View File

@ -556,6 +556,13 @@ TabChild::RecvActivate()
return true;
}
bool TabChild::RecvDeactivate()
{
nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(mWebNav);
browser->Deactivate();
return true;
}
bool
TabChild::RecvMouseEvent(const nsString& aType,
const float& aX,

View File

@ -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,

View File

@ -219,6 +219,12 @@ TabParent::Activate()
unused << SendActivate();
}
void
TabParent::Deactivate()
{
unused << SendDeactivate();
}
NS_IMETHODIMP
TabParent::Init(nsIDOMWindow *window)
{

View File

@ -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);