diff --git a/accessible/windows/ia2/ia2Accessible.cpp b/accessible/windows/ia2/ia2Accessible.cpp index 0a4eb5d41531..a18012649902 100644 --- a/accessible/windows/ia2/ia2Accessible.cpp +++ b/accessible/windows/ia2/ia2Accessible.cpp @@ -495,7 +495,7 @@ ia2Accessible::get_uniqueID(long* aUniqueID) return E_INVALIDARG; AccessibleWrap* acc = static_cast(this); - *aUniqueID = - reinterpret_cast(acc->UniqueID()); + *aUniqueID = AccessibleWrap::GetChildIDFor(acc); return S_OK; A11Y_TRYBLOCK_END diff --git a/accessible/windows/msaa/AccessibleWrap.cpp b/accessible/windows/msaa/AccessibleWrap.cpp index 05e4f958dcd5..bfacdfd1f217 100644 --- a/accessible/windows/msaa/AccessibleWrap.cpp +++ b/accessible/windows/msaa/AccessibleWrap.cpp @@ -56,16 +56,48 @@ const uint32_t USE_ROLE_STRING = 0; static gAccessibles = 0; #endif +#ifdef _WIN64 +IDSet AccessibleWrap::sIDGen; + +static const uint32_t kNoID = 0; +#endif + static const int32_t kIEnumVariantDisconnected = -1; //////////////////////////////////////////////////////////////////////////////// // AccessibleWrap //////////////////////////////////////////////////////////////////////////////// +AccessibleWrap::AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) : + Accessible(aContent, aDoc) +#ifdef _WIN64 + , mID(kNoID) +#endif +{ +} + +AccessibleWrap::~AccessibleWrap() +{ +#ifdef _WIN64 + if (mID != kNoID) + sIDGen.ReleaseID(mID); +#endif +} ITypeInfo* AccessibleWrap::gTypeInfo = nullptr; NS_IMPL_ISUPPORTS_INHERITED0(AccessibleWrap, Accessible) +void +AccessibleWrap::Shutdown() +{ +#ifdef _WIN64 + if (mID != kNoID) + static_cast(mDoc)->RemoveID(mID); +#endif + + Accessible::Shutdown(); +} + //----------------------------------------------------- // IUnknown interface methods - see iunknown.h for documentation //----------------------------------------------------- @@ -1254,10 +1286,23 @@ AccessibleWrap::GetChildIDFor(Accessible* aAccessible) // so that the 3rd party application can call back and get the IAccessible // the event occurred on. - // Yes, this means we're only compatibible with 32 bit - // MSAA is only available for 32 bit windows, so it's okay - // XXX: bug 606080 - return aAccessible ? - NS_PTR_TO_INT32(aAccessible->UniqueID()) : 0; +#ifdef _WIN64 + if (!aAccessible || !aAccessible->Document()) + return 0; + + uint32_t* id = & static_cast(aAccessible)->mID; + if (*id != kNoID) + return *id; + + *id = sIDGen.GetID(); + DocAccessibleWrap* doc = + static_cast(aAccessible->Document()); + doc->AddID(*id, static_cast(aAccessible)); + + return *id; +#else + return - reinterpret_cast(aAccessible); +#endif } HWND @@ -1307,6 +1352,25 @@ AccessibleWrap::NativeAccessible(Accessible* aAccessible) return static_cast(msaaAccessible); } +#ifdef _WIN64 +static Accessible* +GetAccessibleInSubtree(DocAccessible* aDoc, uint32_t aID) +{ + Accessible* child = static_cast(aDoc)->GetAccessibleByID(aID); + if (child) + return child; + + uint32_t childDocCount = aDoc->ChildDocumentCount(); + for (uint32_t i = 0; i < childDocCount; i++) { + child = GetAccessibleInSubtree(aDoc->GetChildDocumentAt(i), aID); + if (child) + return child; + } + + return nullptr; + } +#endif + Accessible* AccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild) { @@ -1342,7 +1406,11 @@ AccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild) DocAccessible* document = Document(); Accessible* child = +#ifdef _WIN64 + GetAccessibleInSubtree(document, static_cast(aVarChild.lVal)); +#else document->GetAccessibleByUniqueIDInSubtree(uniqueID); +#endif // If it is a document then just return an accessible. if (IsDoc()) diff --git a/accessible/windows/msaa/AccessibleWrap.h b/accessible/windows/msaa/AccessibleWrap.h index b32ede032c22..a3d730f927d8 100644 --- a/accessible/windows/msaa/AccessibleWrap.h +++ b/accessible/windows/msaa/AccessibleWrap.h @@ -15,6 +15,7 @@ #include "ia2AccessibleHyperlink.h" #include "ia2AccessibleValue.h" #include "mozilla/a11y/ProxyAccessible.h" +#include "mozilla/a11y/IDSet.h" #ifdef __GNUC__ // Inheriting from both XPCOM and MSCOM interfaces causes a lot of warnings @@ -33,8 +34,7 @@ class AccessibleWrap : public Accessible, public ia2AccessibleValue { public: // construction, destruction - AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) : - Accessible(aContent, aDoc) { } + AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc); // nsISupports NS_DECL_ISUPPORTS_INHERITED @@ -152,6 +152,7 @@ public: // construction, destruction // Accessible virtual nsresult HandleAccEvent(AccEvent* aEvent); + virtual void Shutdown() override; // Helper methods static int32_t GetChildIDFor(Accessible* aAccessible); @@ -176,7 +177,11 @@ public: // construction, destruction static IDispatch* NativeAccessible(Accessible* aAccessible); protected: - virtual ~AccessibleWrap() { } + virtual ~AccessibleWrap(); + +#ifdef _WIN64 + uint32_t mID; +#endif /** * Creates ITypeInfo for LIBID_Accessibility if it's needed and returns it. @@ -185,6 +190,9 @@ protected: static ITypeInfo* gTypeInfo; +#ifdef _WIN64 + static IDSet sIDGen; +#endif enum navRelations { NAVRELATION_CONTROLLED_BY = 0x1000, diff --git a/accessible/windows/msaa/DocAccessibleWrap.h b/accessible/windows/msaa/DocAccessibleWrap.h index 80f2f41ab856..18e58b0ab3a1 100644 --- a/accessible/windows/msaa/DocAccessibleWrap.h +++ b/accessible/windows/msaa/DocAccessibleWrap.h @@ -34,12 +34,30 @@ public: // DocAccessible virtual void* GetNativeWindow() const; + /** + * Manage the mapping from id to Accessible. + */ +#ifdef _WIN64 + void AddID(uint32_t aID, AccessibleWrap* aAcc) + { mIDToAccessibleMap.Put(aID, aAcc); } + void RemoveID(uint32_t aID) { mIDToAccessibleMap.Remove(aID); } + AccessibleWrap* GetAccessibleByID(uint32_t aID) const + { return mIDToAccessibleMap.Get(aID); } +#endif + protected: // DocAccessible virtual void DoInitialUpdate(); protected: void* mHWND; + + /* + * This provides a mapping from 32 bit id to accessible objects. + */ +#ifdef _WIN64 + nsDataHashtable mIDToAccessibleMap; +#endif }; } // namespace a11y