Bug 1598299 part 1: Make atk_component_ref_accessible_at_point return the deepest child instead of the direct child. r=yzen

This changes the ATK code to use AccessibleOrProxy::ChildAtPoint, since that already handles walking into OuterDocAccessibles appropriately.
Previously, atk_component_ref_accessible_at_point didn't work at all on OuterDocAccessibles.
Also, for ProxyAccessibles, we no longer adjust the coordinates for ATK_XY_WINDOW in the content process, as this depends on stuff that doesn't exist cross-platform and thus can't be used with AccessibleOrProxy.
Instead, we now handle this in the parent process before making the IPC call.

Differential Revision: https://phabricator.services.mozilla.com/D67986

--HG--
extra : moz-landing-system : lando
This commit is contained in:
James Teh 2020-03-26 15:27:45 +00:00
Родитель db0ef6b876
Коммит ef9d9e1d06
1 изменённых файлов: 40 добавлений и 32 удалений

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

@ -12,7 +12,9 @@
#include "nsCoreUtils.h"
#include "nsMai.h"
#include "mozilla/Likely.h"
#include "mozilla/a11y/DocAccessibleParent.h"
#include "mozilla/a11y/ProxyAccessible.h"
#include "mozilla/dom/BrowserParent.h"
using namespace mozilla::a11y;
@ -86,45 +88,51 @@ static gboolean scrollToPointCB(AtkComponent* aComponent, AtkCoordType coords,
AtkObject* refAccessibleAtPointHelper(AtkObject* aAtkObj, gint aX, gint aY,
AtkCoordType aCoordType) {
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
if (accWrap) {
if (accWrap->IsDefunct() || nsAccUtils::MustPrune(accWrap)) {
AccessibleOrProxy acc = GetInternalObj(aAtkObj);
if (acc.IsNull()) {
// This might be an ATK Socket.
acc = GetAccessibleWrap(aAtkObj);
if (acc.IsNull()) {
return nullptr;
}
// Accessible::ChildAtPoint(x,y) is in screen pixels.
if (aCoordType == ATK_XY_WINDOW) {
nsIntPoint winCoords =
nsCoreUtils::GetScreenCoordsForWindow(accWrap->GetNode());
aX += winCoords.x;
aY += winCoords.y;
}
Accessible* accAtPoint =
accWrap->ChildAtPoint(aX, aY, Accessible::eDirectChild);
if (!accAtPoint) {
return nullptr;
}
AtkObject* atkObj = AccessibleWrap::GetAtkObject(accAtPoint);
if (atkObj) {
g_object_ref(atkObj);
}
return atkObj;
}
if (acc.IsAccessible() && acc.AsAccessible()->IsDefunct()) {
return nullptr;
}
if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
ProxyAccessible* result =
proxy->AccessibleAtPoint(aX, aY, aCoordType == ATK_XY_WINDOW);
AtkObject* atkObj = result ? GetWrapperFor(result) : nullptr;
if (atkObj) {
g_object_ref(atkObj);
// AccessibleOrProxy::ChildAtPoint(x,y) is in screen pixels.
if (aCoordType == ATK_XY_WINDOW) {
nsINode* node = nullptr;
if (acc.IsAccessible()) {
node = acc.AsAccessible()->GetNode();
} else {
// Use the XUL browser embedding this remote document.
auto browser = static_cast<mozilla::dom::BrowserParent*>(
acc.AsProxy()->Document()->Manager());
node = browser->GetOwnerElement();
}
return atkObj;
MOZ_ASSERT(node);
nsIntPoint winCoords = nsCoreUtils::GetScreenCoordsForWindow(node);
aX += winCoords.x;
aY += winCoords.y;
}
return nullptr;
AccessibleOrProxy accAtPoint =
acc.ChildAtPoint(aX, aY, Accessible::eDeepestChild);
if (accAtPoint.IsNull()) {
return nullptr;
}
roles::Role role = accAtPoint.Role();
if (role == roles::TEXT_LEAF || role == roles::STATICTEXT) {
// We don't include text leaf nodes in the ATK tree, so return the parent.
accAtPoint = accAtPoint.Parent();
MOZ_ASSERT(!accAtPoint.IsNull(), "Text leaf should always have a parent");
}
AtkObject* atkObj = GetWrapperFor(accAtPoint);
if (atkObj) {
g_object_ref(atkObj);
}
return atkObj;
}
void getExtentsHelper(AtkObject* aAtkObj, gint* aX, gint* aY, gint* aWidth,