Bug 1210408 - make nsMaiInterfaceAction work with proxies, r=tbsaunde

--HG--
extra : rebase_source : a24bf6bcded4eed0d7d7a5bf8e3a008cd299f6ae
This commit is contained in:
Olli Pettay 2015-10-06 22:14:18 +03:00
Родитель d06b6030f6
Коммит 010075bd3f
8 изменённых файлов: 112 добавлений и 54 удалений

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

@ -1570,3 +1570,50 @@ AccessibleWrap::FireAtkShowHideEvent(AccEvent* aEvent,
return NS_OK;
}
// static
void
AccessibleWrap::GetKeyBinding(Accessible* aAccessible, nsAString& aResult)
{
// Return all key bindings including access key and keyboard shortcut.
// Get access key.
nsAutoString keyBindingsStr;
KeyBinding keyBinding = aAccessible->AccessKey();
if (!keyBinding.IsEmpty()) {
keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
Accessible* parent = aAccessible->Parent();
roles::Role role = parent ? parent->Role() : roles::NOTHING;
if (role == roles::PARENT_MENUITEM || role == roles::MENUITEM ||
role == roles::RADIO_MENU_ITEM || role == roles::CHECK_MENU_ITEM) {
// It is submenu, expose keyboard shortcuts from menu hierarchy like
// "s;<Alt>f:s"
nsAutoString keysInHierarchyStr = keyBindingsStr;
do {
KeyBinding parentKeyBinding = parent->AccessKey();
if (!parentKeyBinding.IsEmpty()) {
nsAutoString str;
parentKeyBinding.ToString(str, KeyBinding::eAtkFormat);
str.Append(':');
keysInHierarchyStr.Insert(str, 0);
}
} while ((parent = parent->Parent()) && parent->Role() != roles::MENUBAR);
keyBindingsStr.Append(';');
keyBindingsStr.Append(keysInHierarchyStr);
}
} else {
// No access key, add ';' to point this.
keyBindingsStr.Append(';');
}
// Get keyboard shortcut.
keyBindingsStr.Append(';');
keyBinding = aAccessible->KeyboardShortcut();
if (!keyBinding.IsEmpty()) {
keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
}
aResult = keyBindingsStr;
}

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

@ -69,6 +69,7 @@ public:
return returnedString.get();
}
static void GetKeyBinding(Accessible* aAccessible, nsAString& aResult);
protected:
nsresult FireAtkStateChangeEvent(AccEvent* aEvent, AtkObject *aObject);

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

@ -10,7 +10,7 @@
#include "nsMai.h"
#include "Role.h"
#include "mozilla/Likely.h"
#include "ProxyAccessible.h"
#include "nsString.h"
using namespace mozilla::a11y;
@ -21,86 +21,69 @@ static gboolean
doActionCB(AtkAction *aAction, gint aActionIndex)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
return accWrap && accWrap->DoAction(aActionIndex);
if (accWrap) {
return accWrap->DoAction(aActionIndex);
}
ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction));
return proxy && proxy->DoAction(aActionIndex);
}
static gint
getActionCountCB(AtkAction *aAction)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
return accWrap ? accWrap->ActionCount() : 0;
if (accWrap) {
return accWrap->ActionCount();
}
ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction));
return proxy ? proxy->ActionCount() : 0;
}
static const gchar*
getActionDescriptionCB(AtkAction *aAction, gint aActionIndex)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
if (!accWrap)
return nullptr;
nsAutoString description;
accWrap->ActionDescriptionAt(aActionIndex, description);
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
if (accWrap) {
accWrap->ActionDescriptionAt(aActionIndex, description);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction))) {
proxy->ActionDescriptionAt(aActionIndex, description);
} else {
return nullptr;
}
return AccessibleWrap::ReturnString(description);
}
static const gchar*
getActionNameCB(AtkAction *aAction, gint aActionIndex)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
if (!accWrap)
return nullptr;
nsAutoString autoStr;
accWrap->ActionNameAt(aActionIndex, autoStr);
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
if (accWrap) {
accWrap->ActionNameAt(aActionIndex, autoStr);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction))) {
proxy->ActionNameAt(aActionIndex, autoStr);
} else {
return nullptr;
}
return AccessibleWrap::ReturnString(autoStr);
}
static const gchar*
getKeyBindingCB(AtkAction *aAction, gint aActionIndex)
{
AccessibleWrap* acc = GetAccessibleWrap(ATK_OBJECT(aAction));
if (!acc)
return nullptr;
// Return all key bindings including access key and keyboard shortcut.
nsAutoString keyBindingsStr;
// Get access key.
KeyBinding keyBinding = acc->AccessKey();
if (!keyBinding.IsEmpty()) {
keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
Accessible* parent = acc->Parent();
roles::Role role = parent ? parent->Role() : roles::NOTHING;
if (role == roles::PARENT_MENUITEM || role == roles::MENUITEM ||
role == roles::RADIO_MENU_ITEM || role == roles::CHECK_MENU_ITEM) {
// It is submenu, expose keyboard shortcuts from menu hierarchy like
// "s;<Alt>f:s"
nsAutoString keysInHierarchyStr = keyBindingsStr;
do {
KeyBinding parentKeyBinding = parent->AccessKey();
if (!parentKeyBinding.IsEmpty()) {
nsAutoString str;
parentKeyBinding.ToString(str, KeyBinding::eAtkFormat);
str.Append(':');
keysInHierarchyStr.Insert(str, 0);
}
} while ((parent = parent->Parent()) && parent->Role() != roles::MENUBAR);
keyBindingsStr.Append(';');
keyBindingsStr.Append(keysInHierarchyStr);
}
AccessibleWrap* acc = GetAccessibleWrap(ATK_OBJECT(aAction));
if (acc) {
AccessibleWrap::GetKeyBinding(acc, keyBindingsStr);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aAction))) {
proxy->AtkKeyBinding(keyBindingsStr);
} else {
// No access key, add ';' to point this.
keyBindingsStr.Append(';');
}
// Get keyboard shortcut.
keyBindingsStr.Append(';');
keyBinding = acc->KeyboardShortcut();
if (!keyBinding.IsEmpty()) {
keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
return nullptr;
}
return AccessibleWrap::ReturnString(keyBindingsStr);

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

@ -17,6 +17,9 @@
#include "nsIPersistentProperties2.h"
#include "nsISimpleEnumerator.h"
#include "nsAccUtils.h"
#ifdef MOZ_ACCESSIBILITY_ATK
#include "AccessibleWrap.h"
#endif
namespace mozilla {
namespace a11y {
@ -1655,6 +1658,19 @@ DocAccessibleChild::RecvKeyboardShortcut(const uint64_t& aID,
return true;
}
bool
DocAccessibleChild::RecvAtkKeyBinding(const uint64_t& aID,
nsString* aResult)
{
#ifdef MOZ_ACCESSIBILITY_ATK
Accessible* acc = IdToAccessible(aID);
if (acc) {
AccessibleWrap::GetKeyBinding(acc, *aResult);
}
#endif
return true;
}
bool
DocAccessibleChild::RecvCurValue(const uint64_t& aID,
double* aValue)

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

@ -416,6 +416,9 @@ public:
uint32_t* aKey,
uint32_t* aModifierMask) override;
virtual bool RecvAtkKeyBinding(const uint64_t& aID,
nsString* aResult) override;
virtual bool RecvCurValue(const uint64_t& aID,
double* aValue) override;

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

@ -218,6 +218,7 @@ child:
prio(high) sync ActionNameAt(uint64_t aID, uint8_t aIndex) returns(nsString aName);
prio(high) sync AccessKey(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
prio(high) sync KeyboardShortcut(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
prio(high) sync AtkKeyBinding(uint64_t aID) returns(nsString aResult);
prio(high) sync CurValue(uint64_t aID) returns(double aValue);
prio(high) sync SetCurValue(uint64_t aID, double aValue) returns(bool aRetVal);

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

@ -934,6 +934,12 @@ ProxyAccessible::KeyboardShortcut()
return KeyBinding(key, modifierMask);
}
void
ProxyAccessible::AtkKeyBinding(nsString& aBinding)
{
unused << mDoc->SendAtkKeyBinding(mID, &aBinding);
}
double
ProxyAccessible::CurValue()
{

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

@ -313,6 +313,7 @@ public:
void ActionNameAt(uint8_t aIndex, nsString& aName);
KeyBinding AccessKey();
KeyBinding KeyboardShortcut();
void AtkKeyBinding(nsString& aBinding);
double CurValue();
bool SetCurValue(double aValue);