bug 1074917 - teach atk to get states from proxies r=surkov, davidb, mrbkap

We need to implement things like
https://developer.gnome.org/atk/unstable/AtkObject.html#atk-object-ref-state-set
and the same basic thing on windows.  That API is fundamentally sync,
but the information necessary to implement it is only available in the
child process.  That seems to leave us with two options, either we can
use sync ipc or we can use async ipc but spin a nested event loop.  If
we were to spin nested event loops we'd have to be careful to make sure
a11y didn't do anything until the nested event loop was done, and then
a11y would have to deal with whatever changed.  I'm not sure that will
work, and since the system is probably waiting for the accessibility
information anyway I don't think we get much out of spinning the event
loop.  So I think its somewhat less bad to use sync ipc here.
This commit is contained in:
Trevor Saunders 2014-09-23 04:35:33 -04:00
parent 1ca74b7577
commit 91ca545f51
6 changed files with 46 additions and 11 deletions

View File

@ -892,19 +892,18 @@ TranslateStates(uint64_t aState, AtkStateSet* aStateSet)
AtkStateSet *
refStateSetCB(AtkObject *aAtkObj)
{
AtkStateSet *state_set = nullptr;
state_set = ATK_OBJECT_CLASS(parent_class)->ref_state_set(aAtkObj);
AtkStateSet *state_set = nullptr;
state_set = ATK_OBJECT_CLASS(parent_class)->ref_state_set(aAtkObj);
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
if (!accWrap) {
TranslateStates(states::DEFUNCT, state_set);
return state_set;
}
// Map states
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
if (accWrap)
TranslateStates(accWrap->State(), state_set);
else if (ProxyAccessible* proxy = GetProxy(aAtkObj))
TranslateStates(proxy->State(), state_set);
else
TranslateStates(states::DEFUNCT, state_set);
return state_set;
return state_set;
}
static void

View File

@ -36,5 +36,19 @@ DocAccessibleChild::ShowEvent(AccShowEvent* aShowEvent)
SerializeTree(aShowEvent->GetAccessible(), data.NewTree());
SendShowEvent(data);
}
bool
DocAccessibleChild::RecvState(const uint64_t& aID, uint64_t* aState)
{
Accessible* acc = mDoc->GetAccessibleByUniqueID((void*)aID);
if (!acc) {
*aState = states::DEFUNCT;
return true;
}
*aState = acc->State();
return true;
}
}
}

View File

@ -33,6 +33,11 @@ public:
void ShowEvent(AccShowEvent* aShowEvent);
/*
* Return the state for the accessible with given ID.
*/
virtual bool RecvState(const uint64_t& aID, uint64_t* aState) MOZ_OVERRIDE;
private:
DocAccessible* mDoc;
};

View File

@ -24,7 +24,7 @@ struct ShowEventData
AccessibleData[] NewTree;
};
protocol PDocAccessible
prio(normal upto high) sync protocol PDocAccessible
{
manager PContent;
@ -38,6 +38,9 @@ parent:
Event(uint32_t type);
ShowEvent(ShowEventData data);
HideEvent(uint64_t aRootID);
child:
prio(high) sync State(uint64_t aID) returns(uint64_t states);
};
}

View File

@ -6,6 +6,7 @@
#include "ProxyAccessible.h"
#include "DocAccessibleParent.h"
#include "mozilla/unused.h"
#include "mozilla/a11y/Platform.h"
namespace mozilla {
@ -38,5 +39,13 @@ ProxyAccessible::SetChildDoc(DocAccessibleParent* aParent)
mOuterDoc = false;
}
}
uint64_t
ProxyAccessible::State() const
{
uint64_t state = 0;
unused << mDoc->SendState(mID, &state);
return state;
}
}
}

View File

@ -54,6 +54,11 @@ public:
*/
role Role() const { return mRole; }
/*
* Return the states for the proxied accessible.
*/
uint64_t State() const;
/**
* Allow the platform to store a pointers worth of data on us.
*/