forked from mirrors/gecko-dev
Bug 1206711 - add support for HWND emulation for content top level docs on Windows. r=tbsaunde
MozReview-Commit-ID: GQ1LxCwtv3j
This commit is contained in:
parent
5650342313
commit
26f2c60483
11 changed files with 110 additions and 10 deletions
|
|
@ -12,6 +12,13 @@
|
|||
#include "nsAccUtils.h"
|
||||
#include "nsCoreUtils.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "AccessibleWrap.h"
|
||||
#include "Compatibility.h"
|
||||
#include "nsWinUtils.h"
|
||||
#include "RootAccessible.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
|
|
@ -525,7 +532,43 @@ DocAccessibleParent::SetCOMProxy(const RefPtr<IAccessible>& aCOMProxy)
|
|||
|
||||
IAccessibleHolder::COMPtrType ptr(rawNative);
|
||||
IAccessibleHolder holder(Move(ptr));
|
||||
Unused << SendParentCOMProxy(holder);
|
||||
|
||||
if (nsWinUtils::IsWindowEmulationStarted()) {
|
||||
RootAccessible* rootDocument = outerDoc->RootAccessible();
|
||||
MOZ_ASSERT(rootDocument);
|
||||
|
||||
bool isActive = true;
|
||||
nsIntRect rect(CW_USEDEFAULT, CW_USEDEFAULT, 0, 0);
|
||||
if (Compatibility::IsDolphin()) {
|
||||
rect = Bounds();
|
||||
nsIntRect rootRect = rootDocument->Bounds();
|
||||
rect.x = rootRect.x - rect.x;
|
||||
rect.y -= rootRect.y;
|
||||
tab->GetDocShellIsActive(&isActive);
|
||||
}
|
||||
|
||||
HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());
|
||||
HWND hWnd = nsWinUtils::CreateNativeWindow(kClassNameTabContent,
|
||||
parentWnd, rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
isActive);
|
||||
if (hWnd) {
|
||||
// Attach accessible document to the emulated native window
|
||||
::SetPropW(hWnd, kPropNameDocAccParent, (HANDLE)this);
|
||||
SetEmulatedWindowHandle(hWnd);
|
||||
}
|
||||
}
|
||||
Unused << SendParentCOMProxy(holder, reinterpret_cast<uintptr_t>(
|
||||
mEmulatedWindowHandle));
|
||||
}
|
||||
|
||||
void
|
||||
DocAccessibleParent::SetEmulatedWindowHandle(HWND aWindowHandle)
|
||||
{
|
||||
if (!aWindowHandle && mEmulatedWindowHandle && IsTopLevel()) {
|
||||
::DestroyWindow(mEmulatedWindowHandle);
|
||||
}
|
||||
mEmulatedWindowHandle = aWindowHandle;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ public:
|
|||
DocAccessibleParent() :
|
||||
ProxyAccessible(this), mParentDoc(nullptr),
|
||||
mTopLevel(false), mShutdown(false)
|
||||
#if defined(XP_WIN)
|
||||
, mEmulatedWindowHandle(nullptr)
|
||||
#endif // defined(XP_WIN)
|
||||
{ MOZ_COUNT_CTOR_INHERITED(DocAccessibleParent, ProxyAccessible); }
|
||||
~DocAccessibleParent()
|
||||
{
|
||||
|
|
@ -151,6 +154,13 @@ public:
|
|||
|
||||
virtual mozilla::ipc::IPCResult RecvGetWindowedPluginIAccessible(
|
||||
const WindowsHandle& aHwnd, IAccessibleHolder* aPluginCOMProxy) override;
|
||||
|
||||
/**
|
||||
* Set emulated native window handle for a document.
|
||||
* @param aWindowHandle emulated native window handle
|
||||
*/
|
||||
void SetEmulatedWindowHandle(HWND aWindowHandle);
|
||||
HWND GetEmulatedWindowHandle() const { return mEmulatedWindowHandle; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
|
@ -187,6 +197,11 @@ private:
|
|||
nsTArray<DocAccessibleParent*> mChildDocs;
|
||||
DocAccessibleParent* mParentDoc;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
// The handle associated with the emulated window that contains this document
|
||||
HWND mEmulatedWindowHandle;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conceptually this is a map from IDs to proxies, but we store the ID in the
|
||||
* proxy object so we can't use a real map.
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ static StaticAutoPtr<PlatformChild> sPlatformChild;
|
|||
|
||||
DocAccessibleChild::DocAccessibleChild(DocAccessible* aDoc)
|
||||
: DocAccessibleChildBase(aDoc)
|
||||
, mEmulatedWindowHandle(nullptr)
|
||||
, mIsRemoteConstructed(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(DocAccessibleChild, DocAccessibleChildBase);
|
||||
|
|
@ -45,11 +46,13 @@ DocAccessibleChild::Shutdown()
|
|||
}
|
||||
|
||||
ipc::IPCResult
|
||||
DocAccessibleChild::RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy)
|
||||
DocAccessibleChild::RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy,
|
||||
const WindowsHandle& aEmulatedWindowHandle)
|
||||
{
|
||||
MOZ_ASSERT(!mParentProxy && !aParentCOMProxy.IsNull());
|
||||
mParentProxy.reset(const_cast<IAccessibleHolder&>(aParentCOMProxy).Release());
|
||||
SetConstructedInParentProcess();
|
||||
mEmulatedWindowHandle = reinterpret_cast<HWND>(aEmulatedWindowHandle);
|
||||
|
||||
for (uint32_t i = 0, l = mDeferredEvents.Length(); i < l; ++i) {
|
||||
mDeferredEvents[i]->Dispatch();
|
||||
|
|
|
|||
|
|
@ -28,7 +28,10 @@ public:
|
|||
virtual void Shutdown() override;
|
||||
|
||||
virtual ipc::IPCResult
|
||||
RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy) override;
|
||||
RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy,
|
||||
const WindowsHandle& aEmulatedWindowHandle) override;
|
||||
|
||||
HWND GetEmulatedWindowHandle() const { return mEmulatedWindowHandle; }
|
||||
|
||||
IAccessible* GetParentIAccessible() const { return mParentProxy.get(); }
|
||||
|
||||
|
|
@ -310,6 +313,7 @@ private:
|
|||
bool mIsRemoteConstructed;
|
||||
mscom::ProxyUniquePtr<IAccessible> mParentProxy;
|
||||
nsTArray<UniquePtr<DeferredEvent>> mDeferredEvents;
|
||||
HWND mEmulatedWindowHandle;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ parent:
|
|||
returns (IAccessibleHolder aPluginCOMProxy);
|
||||
|
||||
child:
|
||||
async ParentCOMProxy(IAccessibleHolder aParentCOMProxy);
|
||||
async ParentCOMProxy(IAccessibleHolder aParentCOMProxy,
|
||||
WindowsHandle aEmulatedWindowHandle);
|
||||
|
||||
async __delete__();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -120,6 +120,11 @@ DocAccessibleWrap::GetNativeWindow() const
|
|||
{
|
||||
if (XRE_IsContentProcess()) {
|
||||
DocAccessibleChild* ipcDoc = IPCDoc();
|
||||
HWND hWnd = ipcDoc->GetEmulatedWindowHandle();
|
||||
if (hWnd) {
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
auto tab = static_cast<dom::TabChild*>(ipcDoc->Manager());
|
||||
MOZ_ASSERT(tab);
|
||||
return reinterpret_cast<HWND>(tab->GetNativeWindowHandle());
|
||||
|
|
|
|||
|
|
@ -85,6 +85,10 @@ a11y::ProxyDestroyed(ProxyAccessible* aProxy)
|
|||
if (!wrapper)
|
||||
return;
|
||||
|
||||
if (aProxy->IsDoc() && nsWinUtils::IsWindowEmulationStarted()) {
|
||||
aProxy->AsDoc()->SetEmulatedWindowHandle(nullptr);
|
||||
}
|
||||
|
||||
wrapper->Shutdown();
|
||||
aProxy->SetWrapper(0);
|
||||
wrapper->Release();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ EXPORTS.mozilla.a11y += [
|
|||
'HyperTextAccessibleWrap.h',
|
||||
'IDSet.h',
|
||||
'MsaaIdGenerator.h',
|
||||
'nsWinUtils.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "nsAccessibilityService.h"
|
||||
#include "nsCoreUtils.h"
|
||||
|
||||
#include "mozilla/a11y/DocAccessibleParent.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsIArray.h"
|
||||
|
|
@ -20,6 +21,7 @@
|
|||
#include "nsIDocShellTreeItem.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "ProxyWrappers.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
|
@ -153,18 +155,25 @@ WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
// for details).
|
||||
int32_t objId = static_cast<DWORD>(lParam);
|
||||
if (objId == OBJID_CLIENT) {
|
||||
IAccessible* msaaAccessible = nullptr;
|
||||
DocAccessible* document =
|
||||
reinterpret_cast<DocAccessible*>(::GetPropW(hWnd, kPropNameDocAcc));
|
||||
if (document) {
|
||||
IAccessible* msaaAccessible = nullptr;
|
||||
document->GetNativeInterface((void**)&msaaAccessible); // does an addref
|
||||
if (msaaAccessible) {
|
||||
LRESULT result = ::LresultFromObject(IID_IAccessible, wParam,
|
||||
msaaAccessible); // does an addref
|
||||
msaaAccessible->Release(); // release extra addref
|
||||
return result;
|
||||
} else {
|
||||
DocAccessibleParent* docParent = static_cast<DocAccessibleParent*>(
|
||||
::GetPropW(hWnd, kPropNameDocAccParent));
|
||||
if (docParent) {
|
||||
auto wrapper = WrapperFor(docParent);
|
||||
wrapper->GetNativeInterface((void**)&msaaAccessible); // does an addref
|
||||
}
|
||||
}
|
||||
if (msaaAccessible) {
|
||||
LRESULT result = ::LresultFromObject(IID_IAccessible, wParam,
|
||||
msaaAccessible); // does an addref
|
||||
msaaAccessible->Release(); // release extra addref
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class DocAccessible;
|
|||
const LPCWSTR kClassNameRoot = L"MozillaUIWindowClass";
|
||||
const LPCWSTR kClassNameTabContent = L"MozillaContentWindowClass";
|
||||
const LPCWSTR kPropNameDocAcc = L"MozDocAccessible";
|
||||
const LPCWSTR kPropNameDocAccParent = L"MozDocAccessibleParent";
|
||||
|
||||
class nsWinUtils
|
||||
{
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@
|
|||
|
||||
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
||||
#include "mozilla/a11y/AccessibleWrap.h"
|
||||
#include "mozilla/a11y/nsWinUtils.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
|
@ -269,6 +270,16 @@ TabParent::SetOwnerElement(Element* aElement)
|
|||
reinterpret_cast<uintptr_t>(widget->GetNativeData(NS_NATIVE_WINDOW));
|
||||
}
|
||||
Unused << SendUpdateNativeWindowHandle(newWindowHandle);
|
||||
a11y::DocAccessibleParent* doc = GetTopLevelDocAccessible();
|
||||
if (doc) {
|
||||
HWND hWnd = reinterpret_cast<HWND>(doc->GetEmulatedWindowHandle());
|
||||
if (hWnd) {
|
||||
HWND parentHwnd = reinterpret_cast<HWND>(newWindowHandle);
|
||||
if (parentHwnd != ::GetParent(hWnd)) {
|
||||
::SetParent(hWnd, parentHwnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -921,6 +932,9 @@ TabParent::RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc,
|
|||
MOZ_ASSERT(aDocCOMProxy.IsNull());
|
||||
if (added) {
|
||||
a11y::WrapperFor(doc)->SetID(aMsaaID);
|
||||
if (a11y::nsWinUtils::IsWindowEmulationStarted()) {
|
||||
doc->SetEmulatedWindowHandle(parentDoc->GetEmulatedWindowHandle());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!added) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue