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;
AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
*aUniqueID = - reinterpret_cast<intptr_t>(acc->UniqueID());
*aUniqueID = AccessibleWrap::GetChildIDFor(acc);
return S_OK;
A11Y_TRYBLOCK_END

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

@ -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<DocAccessibleWrap*>(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<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
@ -1307,6 +1352,25 @@ AccessibleWrap::NativeAccessible(Accessible* aAccessible)
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*
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<uint32_t>(aVarChild.lVal));
#else
document->GetAccessibleByUniqueIDInSubtree(uniqueID);
#endif
// If it is a document then just return an accessible.
if (IsDoc())

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

@ -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,

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

@ -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<nsUint32HashKey, AccessibleWrap*> mIDToAccessibleMap;
#endif
};
} // namespace a11y