Bug 522533 - Sort out focus handling in Electrolysis

--HG--
extra : rebase_source : 8b91e5c9a55bb7c2809352c5e297be77399141dd
This commit is contained in:
Olli Pettay 2009-11-05 20:14:22 +02:00
parent 42127b055e
commit ca88319903
10 changed files with 278 additions and 19 deletions

View File

@ -43,7 +43,7 @@ interface nsIDocShell;
interface nsIURI;
interface nsIFrame;
[scriptable, uuid(fe5f43b1-6b9d-4639-be08-03f0de1a22f9)]
[scriptable, uuid(897af00a-c907-4311-88dc-f9d12f05b110)]
interface nsIFrameLoader : nsISupports
{
/**
@ -82,6 +82,12 @@ interface nsIFrameLoader : nsISupports
* @param aIFrame The nsIFrame for the content node that owns this frameloader
*/
[noscript] void updatePositionAndSize(in nsIFrame aIFrame);
/**
* Activate remote frame.
* Throws an exception with non-remote frames.
*/
void activateRemoteFrame();
};
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);

View File

@ -993,6 +993,11 @@ nsFrameLoader::Destroy()
mOwnerContent = nsnull;
}
#ifdef MOZ_IPC
if (mChildProcess) {
mChildProcess->SetOwnerElement(nsnull);
}
#endif
// Let the tree owner know we're gone.
if (mIsTopLevelContent) {
@ -1439,6 +1444,10 @@ nsFrameLoader::TryNewProcess()
}
mChildProcess = ContentProcessParent::GetSingleton()->CreateTab();
if (mChildProcess) {
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
mChildProcess->SetOwnerElement(element);
}
return true;
}
#endif
@ -1450,3 +1459,14 @@ nsFrameLoader::GetChildProcess()
return mChildProcess;
}
#endif
NS_IMETHODIMP
nsFrameLoader::ActivateRemoteFrame() {
#ifdef MOZ_IPC
if (mChildProcess) {
mChildProcess->Activate();
return NS_OK;
}
#endif
return NS_ERROR_UNEXPECTED;
}

View File

@ -80,18 +80,20 @@ ContentProcessChild::Init(MessageLoop* aIOLoop,
PIFrameEmbeddingChild*
ContentProcessChild::AllocPIFrameEmbedding()
{
PIFrameEmbeddingChild* iframe = new TabChild();
if (iframe && mIFrames.AppendElement(iframe)) {
return iframe;
}
delete iframe;
return nsnull;
nsRefPtr<TabChild> iframe = new TabChild();
NS_ENSURE_TRUE(iframe && NS_SUCCEEDED(iframe->Init()) &&
mIFrames.AppendElement(iframe),
nsnull);
return iframe.forget().get();
}
bool
ContentProcessChild::DeallocPIFrameEmbedding(PIFrameEmbeddingChild* iframe)
{
mIFrames.RemoveElement(iframe);
if (mIFrames.RemoveElement(iframe)) {
TabChild* child = static_cast<TabChild*>(iframe);
NS_RELEASE(child);
}
return true;
}

View File

@ -77,7 +77,7 @@ public:
private:
static ContentProcessChild* sSingleton;
nsTArray<nsAutoPtr<PIFrameEmbeddingChild> > mIFrames;
nsTArray<PIFrameEmbeddingChild* > mIFrames;
nsTArray<nsAutoPtr<PTestShellChild> > mTestShells;
PRBool mQuit;

View File

@ -52,6 +52,13 @@ async protocol PIFrameEmbedding
manager PContentProcess;
manages PDocumentRenderer;
parent:
/**
* When child sends this message, parent should move focus to
* the next or previous focusable element.
*/
moveFocus(bool forward);
child:
createWidget(MagicWindowHandle parentWidget);
destroyWidget();
@ -63,6 +70,11 @@ child:
PRUint32 width,
PRUint32 height);
/**
* Sending an activate message moves focus to the child.
*/
activate();
PDocumentRenderer(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h, nsString bgcolor, PRUint32 flags, bool flush);
parent:

View File

@ -47,6 +47,11 @@
#include "nsThreadUtils.h"
#include "nsIInterfaceRequestorUtils.h"
#include "mozilla/ipc/DocumentRendererChild.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMWindowUtils.h"
#include "nsISupportsImpl.h"
#include "nsIWebBrowserFocus.h"
#ifdef MOZ_WIDGET_GTK2
#include <gdk/gdkx.h>
@ -58,19 +63,173 @@ using namespace mozilla::dom;
TabChild::TabChild()
{
printf("creating %d!\n", NS_IsMainThread());
}
nsresult
TabChild::Init()
{
#ifdef MOZ_WIDGET_GTK2
gtk_init(NULL, NULL);
gtk_init(NULL, NULL);
#endif
mWebNav = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
if (!mWebNav) {
NS_ERROR("Couldn't create a nsWebBrowser?");
return;
}
nsCOMPtr<nsIWebBrowser> webBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
if (!webBrowser) {
NS_ERROR("Couldn't create a nsWebBrowser?");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(mWebNav));
docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
webBrowser->SetContainerWindow(this);
mWebNav = do_QueryInterface(webBrowser);
NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?");
nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(mWebNav));
docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
return NS_OK;
}
NS_IMPL_ISUPPORTS5(TabChild, nsIWebBrowserChrome, nsIWebBrowserChrome2,
nsIEmbeddingSiteWindow, nsIEmbeddingSiteWindow2,
nsIWebBrowserChromeFocus)
NS_IMETHODIMP
TabChild::SetStatus(PRUint32 aStatusType, const PRUnichar* aStatus)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::GetWebBrowser(nsIWebBrowser** aWebBrowser)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::SetWebBrowser(nsIWebBrowser* aWebBrowser)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::GetChromeFlags(PRUint32* aChromeFlags)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::SetChromeFlags(PRUint32 aChromeFlags)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::DestroyBrowserWindow()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::ShowAsModal()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::IsWindowModal(PRBool* aRetVal)
{
*aRetVal = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
TabChild::ExitModalEventLoop(nsresult aStatus)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::SetStatusWithContext(PRUint32 aStatusType,
const nsAString& aStatusText,
nsISupports* aStatusContext)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::SetDimensions(PRUint32 aFlags, PRInt32 aX, PRInt32 aY,
PRInt32 aCx, PRInt32 aCy)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::GetDimensions(PRUint32 aFlags, PRInt32* aX,
PRInt32* aY, PRInt32* aCx, PRInt32* aCy)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::SetFocus()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::GetVisibility(PRBool* aVisibility)
{
*aVisibility = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
TabChild::SetVisibility(PRBool aVisibility)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::GetTitle(PRUnichar** aTitle)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::SetTitle(const PRUnichar* aTitle)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::GetSiteWindow(void** aSiteWindow)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::Blur()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TabChild::FocusNextElement()
{
SendmoveFocus(PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
TabChild::FocusPrevElement()
{
SendmoveFocus(PR_FALSE);
return NS_OK;
}
bool
@ -110,6 +269,10 @@ TabChild::RecvdestroyWidget()
TabChild::~TabChild()
{
nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(mWebNav);
if (webBrowser) {
webBrowser->SetContainerWindow(nsnull);
}
// TODObsmedberg: destroy the window!
}
@ -141,6 +304,14 @@ TabChild::Recvmove(const PRUint32& x,
return true;
}
bool
TabChild::Recvactivate()
{
nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(mWebNav);
browser->Activate();
return true;
}
mozilla::ipc::PDocumentRendererChild*
TabChild::AllocPDocumentRenderer(
const PRInt32& x,

View File

@ -42,15 +42,30 @@
#include "mozilla/dom/PIFrameEmbeddingChild.h"
#include "nsIWebNavigation.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsIWebBrowserChrome2.h"
#include "nsIEmbeddingSiteWindow2.h"
#include "nsIWebBrowserChromeFocus.h"
namespace mozilla {
namespace dom {
class TabChild : public PIFrameEmbeddingChild
class TabChild : public PIFrameEmbeddingChild,
public nsIWebBrowserChrome2,
public nsIEmbeddingSiteWindow2,
public nsIWebBrowserChromeFocus
{
public:
TabChild();
virtual ~TabChild();
nsresult Init();
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBBROWSERCHROME
NS_DECL_NSIWEBBROWSERCHROME2
NS_DECL_NSIEMBEDDINGSITEWINDOW
NS_DECL_NSIEMBEDDINGSITEWINDOW2
NS_DECL_NSIWEBBROWSERCHROMEFOCUS
virtual bool RecvcreateWidget(const MagicWindowHandle& parentWidget);
virtual bool RecvdestroyWidget();
@ -59,6 +74,7 @@ public:
const PRUint32& y,
const PRUint32& width,
const PRUint32& height);
virtual bool Recvactivate();
virtual mozilla::ipc::PDocumentRendererChild* AllocPDocumentRenderer(
const PRInt32& x,
const PRInt32& y,

View File

@ -42,6 +42,10 @@
#include "mozilla/ipc/DocumentRendererParent.h"
#include "nsIURI.h"
#include "nsFocusManager.h"
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h"
#include "nsIDOMElement.h"
using mozilla::ipc::BrowserProcessSubThread;
using mozilla::ipc::DocumentRendererParent;
@ -57,6 +61,20 @@ TabParent::~TabParent()
{
}
bool
TabParent::RecvmoveFocus(const bool& aForward)
{
nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
if (fm) {
nsCOMPtr<nsIDOMElement> dummy;
PRUint32 type = aForward ? nsIFocusManager::MOVEFOCUS_FORWARD
: nsIFocusManager::MOVEFOCUS_BACKWARD;
fm->MoveFocus(nsnull, mFrameElement, type, nsIFocusManager::FLAG_BYKEY,
getter_AddRefs(dummy));
}
return true;
}
void
TabParent::LoadURL(nsIURI* aURI)
{
@ -72,6 +90,12 @@ TabParent::Move(PRUint32 x, PRUint32 y, PRUint32 width, PRUint32 height)
Sendmove(x, y, width, height);
}
void
TabParent::Activate()
{
Sendactivate();
}
mozilla::ipc::PDocumentRendererParent*
TabParent::AllocPDocumentRenderer(const PRInt32& x,
const PRInt32& y, const PRInt32& w, const PRInt32& h, const nsString& bgcolor,

View File

@ -44,6 +44,7 @@
#include "mozilla/ipc/GeckoChildProcessHost.h"
class nsIURI;
class nsIDOMElement;
namespace mozilla {
namespace dom {
@ -53,9 +54,13 @@ class TabParent : public PIFrameEmbeddingParent
public:
TabParent();
virtual ~TabParent();
void SetOwnerElement(nsIDOMElement* aElement) { mFrameElement = aElement; }
virtual bool RecvmoveFocus(const bool& aForward);
void LoadURL(nsIURI* aURI);
void Move(PRUint32 x, PRUint32 y, PRUint32 width, PRUint32 height);
void Activate();
virtual mozilla::ipc::PDocumentRendererParent* AllocPDocumentRenderer(
const PRInt32& x,
@ -75,6 +80,8 @@ public:
const PRUint32& w,
const PRUint32& h,
const nsCString& data);
protected:
nsIDOMElement* mFrameElement;
};
} // namespace dom

View File

@ -22,5 +22,6 @@
<toolbarbutton onclick="restart()" label="Recover"/>
</toolbar>
<browser type="content" src="http://www.google.com/" flex="1" id="page" remote="true"/>
<browser type="content" src="http://www.google.com/" flex="1" id="page" remote="true"
onfocus="this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.activateRemoteFrame();"/>
</window>