bug 606080 - on windows give accessibles a unique 32 bit id r=surkov

This commit is contained in:
Trevor Saunders 2015-04-14 12:45:43 -04:00
Родитель a2bc5996ae
Коммит b66382e2ff
4 изменённых файлов: 102 добавлений и 8 удалений

Просмотреть файл

@ -495,7 +495,7 @@ ia2Accessible::get_uniqueID(long* aUniqueID)
return E_INVALIDARG; return E_INVALIDARG;
AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
*aUniqueID = - reinterpret_cast<intptr_t>(acc->UniqueID()); *aUniqueID = AccessibleWrap::GetChildIDFor(acc);
return S_OK; return S_OK;
A11Y_TRYBLOCK_END A11Y_TRYBLOCK_END

Просмотреть файл

@ -56,16 +56,48 @@ const uint32_t USE_ROLE_STRING = 0;
static gAccessibles = 0; static gAccessibles = 0;
#endif #endif
#ifdef _WIN64
IDSet AccessibleWrap::sIDGen;
static const uint32_t kNoID = 0;
#endif
static const int32_t kIEnumVariantDisconnected = -1; static const int32_t kIEnumVariantDisconnected = -1;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// AccessibleWrap // 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; ITypeInfo* AccessibleWrap::gTypeInfo = nullptr;
NS_IMPL_ISUPPORTS_INHERITED0(AccessibleWrap, Accessible) NS_IMPL_ISUPPORTS_INHERITED0(AccessibleWrap, Accessible)
void
AccessibleWrap::Shutdown()
{
#ifdef _WIN64
if (mID != kNoID)
static_cast<DocAccessibleWrap*>(mDoc)->RemoveID(mID);
#endif
Accessible::Shutdown();
}
//----------------------------------------------------- //-----------------------------------------------------
// IUnknown interface methods - see iunknown.h for documentation // 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 // so that the 3rd party application can call back and get the IAccessible
// the event occurred on. // the event occurred on.
// Yes, this means we're only compatibible with 32 bit #ifdef _WIN64
// MSAA is only available for 32 bit windows, so it's okay if (!aAccessible || !aAccessible->Document())
// XXX: bug 606080 return 0;
return aAccessible ? - NS_PTR_TO_INT32(aAccessible->UniqueID()) : 0;
uint32_t* id = & static_cast<AccessibleWrap*>(aAccessible)->mID;
if (*id != kNoID)
return *id;
*id = sIDGen.GetID();
DocAccessibleWrap* doc =
static_cast<DocAccessibleWrap*>(aAccessible->Document());
doc->AddID(*id, static_cast<AccessibleWrap*>(aAccessible));
return *id;
#else
return - reinterpret_cast<intptr_t>(aAccessible);
#endif
} }
HWND HWND
@ -1307,6 +1352,25 @@ AccessibleWrap::NativeAccessible(Accessible* aAccessible)
return static_cast<IDispatch*>(msaaAccessible); return static_cast<IDispatch*>(msaaAccessible);
} }
#ifdef _WIN64
static Accessible*
GetAccessibleInSubtree(DocAccessible* aDoc, uint32_t aID)
{
Accessible* child = static_cast<DocAccessibleWrap*>(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* Accessible*
AccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild) AccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild)
{ {
@ -1342,7 +1406,11 @@ AccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild)
DocAccessible* document = Document(); DocAccessible* document = Document();
Accessible* child = Accessible* child =
#ifdef _WIN64
GetAccessibleInSubtree(document, static_cast<uint32_t>(aVarChild.lVal));
#else
document->GetAccessibleByUniqueIDInSubtree(uniqueID); document->GetAccessibleByUniqueIDInSubtree(uniqueID);
#endif
// If it is a document then just return an accessible. // If it is a document then just return an accessible.
if (IsDoc()) if (IsDoc())

Просмотреть файл

@ -15,6 +15,7 @@
#include "ia2AccessibleHyperlink.h" #include "ia2AccessibleHyperlink.h"
#include "ia2AccessibleValue.h" #include "ia2AccessibleValue.h"
#include "mozilla/a11y/ProxyAccessible.h" #include "mozilla/a11y/ProxyAccessible.h"
#include "mozilla/a11y/IDSet.h"
#ifdef __GNUC__ #ifdef __GNUC__
// Inheriting from both XPCOM and MSCOM interfaces causes a lot of warnings // Inheriting from both XPCOM and MSCOM interfaces causes a lot of warnings
@ -33,8 +34,7 @@ class AccessibleWrap : public Accessible,
public ia2AccessibleValue public ia2AccessibleValue
{ {
public: // construction, destruction public: // construction, destruction
AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) : AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc);
Accessible(aContent, aDoc) { }
// nsISupports // nsISupports
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
@ -152,6 +152,7 @@ public: // construction, destruction
// Accessible // Accessible
virtual nsresult HandleAccEvent(AccEvent* aEvent); virtual nsresult HandleAccEvent(AccEvent* aEvent);
virtual void Shutdown() override;
// Helper methods // Helper methods
static int32_t GetChildIDFor(Accessible* aAccessible); static int32_t GetChildIDFor(Accessible* aAccessible);
@ -176,7 +177,11 @@ public: // construction, destruction
static IDispatch* NativeAccessible(Accessible* aAccessible); static IDispatch* NativeAccessible(Accessible* aAccessible);
protected: protected:
virtual ~AccessibleWrap() { } virtual ~AccessibleWrap();
#ifdef _WIN64
uint32_t mID;
#endif
/** /**
* Creates ITypeInfo for LIBID_Accessibility if it's needed and returns it. * Creates ITypeInfo for LIBID_Accessibility if it's needed and returns it.
@ -185,6 +190,9 @@ protected:
static ITypeInfo* gTypeInfo; static ITypeInfo* gTypeInfo;
#ifdef _WIN64
static IDSet sIDGen;
#endif
enum navRelations { enum navRelations {
NAVRELATION_CONTROLLED_BY = 0x1000, NAVRELATION_CONTROLLED_BY = 0x1000,

Просмотреть файл

@ -34,12 +34,30 @@ public:
// DocAccessible // DocAccessible
virtual void* GetNativeWindow() const; 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: protected:
// DocAccessible // DocAccessible
virtual void DoInitialUpdate(); virtual void DoInitialUpdate();
protected: protected:
void* mHWND; void* mHWND;
/*
* This provides a mapping from 32 bit id to accessible objects.
*/
#ifdef _WIN64
nsDataHashtable<nsUint32HashKey, AccessibleWrap*> mIDToAccessibleMap;
#endif
}; };
} // namespace a11y } // namespace a11y