Bug 671550 - provide correct parent HWND for content process window, r=jones.chris.g, davidb

This commit is contained in:
Alexander Surkov 2011-07-22 09:49:35 +09:00
parent f3aa7b2e37
commit 9a67bf5488
13 changed files with 96 additions and 26 deletions

View File

@ -206,6 +206,19 @@ private:
printf("document type: [failed]"); \
}
#define NS_LOG_ACCDOC_DOCSHELLTREE(aDocument) \
if (aDocument->IsActive()) { \
nsCOMPtr<nsISupports> container = aDocument->GetContainer(); \
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container)); \
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem; \
treeItem->GetParent(getter_AddRefs(parentTreeItem)); \
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; \
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); \
printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;", \
parentTreeItem, rootTreeItem, \
(nsCoreUtils::IsTabDocument(aDocument) ? "yes" : "no")); \
}
#define NS_LOG_ACCDOC_SHELLSTATE(aDocument) \
nsCAutoString docShellBusy; \
nsCOMPtr<nsISupports> container = aDocument->GetContainer(); \
@ -352,6 +365,8 @@ private:
printf("; "); \
NS_LOG_ACCDOC_TYPE(aDocument) \
printf("\n "); \
NS_LOG_ACCDOC_DOCSHELLTREE(aDocument) \
printf("\n "); \
NS_LOG_ACCDOC_DOCSTATES(aDocument) \
printf("\n "); \
NS_LOG_ACCDOC_DOCPRESSHELL(aDocument) \

View File

@ -480,6 +480,26 @@ nsCoreUtils::IsContentDocument(nsIDocument *aDocument)
return (contentType == nsIDocShellTreeItem::typeContent);
}
bool
nsCoreUtils::IsTabDocument(nsIDocument* aDocumentNode)
{
nsCOMPtr<nsISupports> container = aDocumentNode->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
treeItem->GetParent(getter_AddRefs(parentTreeItem));
// Tab document running in own process doesn't have parent.
if (XRE_GetProcessType() == GeckoProcessType_Content)
return !parentTreeItem;
// Parent of docshell for tab document running in chrome process is root.
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
return parentTreeItem == rootTreeItem;
}
PRBool
nsCoreUtils::IsErrorPage(nsIDocument *aDocument)
{

View File

@ -233,6 +233,11 @@ public:
*/
static PRBool IsContentDocument(nsIDocument *aDocument);
/**
* Return true if the given document node is for tab document accessible.
*/
static bool IsTabDocument(nsIDocument* aDocumentNode);
/**
* Return true if the given document is an error page.
*/

View File

@ -107,6 +107,8 @@ EXPORTS = \
# we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
@ -114,5 +116,6 @@ LOCAL_INCLUDES += \
-I$(srcdir)/../base \
-I$(srcdir)/../html \
-I$(srcdir)/../xul \
-I$(srcdir)/../../../content/base/src \
-I$(srcdir)/../../../content/events/src \
$(NULL)

View File

@ -204,7 +204,7 @@ __try {
// accessibles.
if (!doc->ParentDocument() ||
nsWinUtils::IsWindowEmulationStarted() &&
nsWinUtils::IsTabDocument(doc->GetDocumentNode())) {
nsCoreUtils::IsTabDocument(doc->GetDocumentNode())) {
HWND hwnd = static_cast<HWND>(doc->GetNativeWindow());
if (hwnd && SUCCEEDED(AccessibleObjectFromWindow(hwnd, OBJID_WINDOW,
IID_IAccessible,

View File

@ -36,6 +36,8 @@
*
* ***** END LICENSE BLOCK ***** */
#include "mozilla/dom/TabChild.h"
#include "nsDocAccessibleWrap.h"
#include "ISimpleDOMDocument_i.c"
#include "nsIAccessibilityService.h"
@ -242,7 +244,7 @@ nsDocAccessibleWrap::Shutdown()
// Do window emulation specific shutdown if emulation was started.
if (nsWinUtils::IsWindowEmulationStarted()) {
// Destroy window created for root document.
if (nsWinUtils::IsTabDocument(mDocument)) {
if (nsCoreUtils::IsTabDocument(mDocument)) {
sHWNDCache.Remove(mHWND);
::DestroyWindow(static_cast<HWND>(mHWND));
}
@ -272,9 +274,19 @@ nsDocAccessibleWrap::NotifyOfInitialUpdate()
if (nsWinUtils::IsWindowEmulationStarted()) {
// Create window for tab document.
if (nsWinUtils::IsTabDocument(mDocument)) {
if (nsCoreUtils::IsTabDocument(mDocument)) {
mozilla::dom::TabChild* tabChild =
mozilla::dom::GetTabChildFrom(mDocument->GetShell());
nsRootAccessible* rootDocument = RootAccessible();
mozilla::WindowsHandle nativeData = nsnull;
if (tabChild)
tabChild->SendGetWidgetNativeData(&nativeData);
else
nativeData = reinterpret_cast<mozilla::WindowsHandle>(
rootDocument->GetNativeWindow());
PRBool isActive = PR_TRUE;
PRInt32 x = CW_USEDEFAULT, y = CW_USEDEFAULT, width = 0, height = 0;
if (nsWinUtils::IsWindowEmulationFor(kDolphinModuleHandle)) {
@ -289,7 +301,7 @@ nsDocAccessibleWrap::NotifyOfInitialUpdate()
docShell->GetIsActive(&isActive);
}
HWND parentWnd = static_cast<HWND>(rootDocument->GetNativeWindow());
HWND parentWnd = reinterpret_cast<HWND>(nativeData);
mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent, parentWnd,
x, y, width, height, isActive);

View File

@ -64,7 +64,7 @@ void
nsRootAccessibleWrap::DocumentActivated(nsDocAccessible* aDocument)
{
if (nsWinUtils::IsWindowEmulationFor(kDolphinModuleHandle) &&
nsWinUtils::IsTabDocument(aDocument->GetDocumentNode())) {
nsCoreUtils::IsTabDocument(aDocument->GetDocumentNode())) {
PRUint32 count = mChildDocuments.Length();
for (PRUint32 idx = 0; idx < count; idx++) {
nsDocAccessible* childDoc = mChildDocuments[idx];

View File

@ -181,18 +181,3 @@ nsWinUtils::IsWindowEmulationFor(LPCWSTR kModuleHandle)
::GetModuleHandleW(kWEModuleHandle) ||
::GetModuleHandleW(kDolphinModuleHandle);
}
bool
nsWinUtils::IsTabDocument(nsIDocument* aDocumentNode)
{
nsCOMPtr<nsISupports> container = aDocumentNode->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
treeItem->GetParent(getter_AddRefs(parentTreeItem));
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
return parentTreeItem == rootTreeItem;
}

View File

@ -104,11 +104,6 @@ public:
* Return true if window emulation is enabled.
*/
static bool IsWindowEmulationFor(LPCWSTR kModuleHandle);
/**
* Return true if the given document node is for tab document accessible.
*/
static bool IsTabDocument(nsIDocument* aDocumentNode);
};
#endif

View File

@ -62,6 +62,7 @@ using nsMouseEvent;
using nsMouseScrollEvent;
using nsKeyEvent;
using RemoteDOMEvent;
using mozilla::WindowsHandle;
namespace mozilla {
namespace dom {
@ -183,6 +184,11 @@ parent:
*/
sync GetDPI() returns (float value);
/**
* Return native data of root widget
*/
sync GetWidgetNativeData() returns (WindowsHandle value);
SetCursor(PRUint32 value);
PContentPermissionRequest(nsCString aType, URI uri);

View File

@ -68,6 +68,7 @@
#include "nsIPromptFactory.h"
#include "nsIContent.h"
#include "nsIWidget.h"
#include "nsIViewManager.h"
#include "mozilla/unused.h"
#include "nsDebug.h"
@ -612,6 +613,29 @@ TabParent::RecvGetDPI(float* aValue)
return true;
}
bool
TabParent::RecvGetWidgetNativeData(WindowsHandle* aValue)
{
nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
if (content) {
nsIDocument* document = content->GetOwnerDoc();
if (document) {
nsIPresShell* shell = document->GetShell();
if (shell) {
nsIViewManager* vm = shell->GetViewManager();
nsCOMPtr<nsIWidget> widget;
vm->GetRootWidget(getter_AddRefs(widget));
if (widget) {
*aValue = reinterpret_cast<WindowsHandle>(
widget->GetNativeData(NS_NATIVE_WINDOW));
return true;
}
}
}
}
return false;
}
bool
TabParent::ReceiveMessage(const nsString& aMessage,
PRBool aSync,

View File

@ -109,6 +109,7 @@ public:
virtual bool RecvSetIMEOpenState(const PRBool& aValue);
virtual bool RecvSetCursor(const PRUint32& aValue);
virtual bool RecvGetDPI(float* aValue);
virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue);
virtual PContentDialogParent* AllocPContentDialog(const PRUint32& aType,
const nsCString& aName,
const nsCString& aFeatures,

View File

@ -76,6 +76,10 @@ typedef gfxPattern::GraphicsFilter GraphicsFilterType;
typedef gfxASurface::gfxSurfaceType gfxSurfaceType;
typedef LayerManager::LayersBackend LayersBackend;
// This is a cross-platform approximation to HANDLE, which we expect
// to be typedef'd to void* or thereabouts.
typedef uintptr_t WindowsHandle;
// XXX there are out of place and might be generally useful. Could
// move to nscore.h or something.
struct void_t {