Bug 1822004: On Android, use RemoteAccessible (CtW) hit testing instead of a DOM event. r=eeejay
This unifies hit testing across all platforms. It also removes one of the few remaining uses of virtual cursor change events. Differential Revision: https://phabricator.services.mozilla.com/D192641
This commit is contained in:
@@ -173,19 +173,29 @@ bool AccessibleWrap::PivotTo(int32_t aGranularity, bool aForward,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccessibleWrap::ExploreByTouch(float aX, float aY) {
|
Accessible* AccessibleWrap::ExploreByTouch(Accessible* aAccessible, float aX,
|
||||||
a11y::Pivot pivot(RootAccessible());
|
float aY) {
|
||||||
TraversalRule rule;
|
Accessible* root;
|
||||||
|
if (LocalAccessible* local = aAccessible->AsLocal()) {
|
||||||
Accessible* maybeResult = pivot.AtPoint(aX, aY, rule);
|
root = local->RootAccessible();
|
||||||
LocalAccessible* result = maybeResult ? maybeResult->AsLocal() : nullptr;
|
} else {
|
||||||
|
// If this is a RemoteAccessible, provide the top level
|
||||||
if (result && result != this) {
|
// remote doc as the pivot root for thread safety reasons.
|
||||||
RefPtr<AccEvent> event =
|
DocAccessibleParent* doc = aAccessible->AsRemote()->Document();
|
||||||
new AccVCChangeEvent(result->Document(), this, result,
|
while (doc && !doc->IsTopLevel()) {
|
||||||
nsIAccessiblePivot::REASON_POINT, eFromUserInput);
|
doc = doc->ParentDoc();
|
||||||
nsEventShell::FireEvent(event);
|
|
||||||
}
|
}
|
||||||
|
MOZ_ASSERT(doc, "Failed to get top level DocAccessibleParent");
|
||||||
|
root = doc;
|
||||||
|
}
|
||||||
|
a11y::Pivot pivot(root);
|
||||||
|
TraversalRule rule(java::SessionAccessibility::HTML_GRANULARITY_DEFAULT,
|
||||||
|
aAccessible->IsLocal());
|
||||||
|
Accessible* result = pivot.AtPoint(aX, aY, rule);
|
||||||
|
if (result == aAccessible) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TextLeafPoint ToTextLeafPoint(Accessible* aAccessible, int32_t aOffset) {
|
static TextLeafPoint ToTextLeafPoint(Accessible* aAccessible, int32_t aOffset) {
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ class AccessibleWrap : public LocalAccessible {
|
|||||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||||
virtual bool PivotTo(int32_t aGranularity, bool aForward, bool aInclusive);
|
virtual bool PivotTo(int32_t aGranularity, bool aForward, bool aInclusive);
|
||||||
|
|
||||||
void ExploreByTouch(float aX, float aY);
|
static Accessible* ExploreByTouch(Accessible* aAccessible, float aX,
|
||||||
|
float aY);
|
||||||
|
|
||||||
static uint32_t GetFlags(role aRole, uint64_t aState, uint8_t aActionCount);
|
static uint32_t GetFlags(role aRole, uint64_t aState, uint8_t aActionCount);
|
||||||
|
|
||||||
|
|||||||
@@ -186,11 +186,7 @@ void a11y::PlatformVirtualCursorChangeEvent(Accessible* aTarget,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aReason == nsIAccessiblePivot::REASON_POINT) {
|
|
||||||
sessionAcc->SendHoverEnterEvent(aNewPosition);
|
|
||||||
} else {
|
|
||||||
sessionAcc->SendAccessibilityFocusedEvent(aNewPosition);
|
sessionAcc->SendAccessibilityFocusedEvent(aNewPosition);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void a11y::PlatformScrollingEvent(Accessible* aTarget, uint32_t aEventType,
|
void a11y::PlatformScrollingEvent(Accessible* aTarget, uint32_t aEventType,
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
/* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "RootAccessibleWrap.h"
|
|
||||||
|
|
||||||
#include "LocalAccessible-inl.h"
|
|
||||||
|
|
||||||
#include "DocAccessibleParent.h"
|
|
||||||
#include "DocAccessible-inl.h"
|
|
||||||
#include "SessionAccessibility.h"
|
|
||||||
#include "mozilla/PresShell.h"
|
|
||||||
#include "mozilla/dom/EventTarget.h"
|
|
||||||
#include "mozilla/dom/Event.h"
|
|
||||||
#include "mozilla/dom/MouseEvent.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
|
||||||
using namespace mozilla::a11y;
|
|
||||||
using namespace mozilla::dom;
|
|
||||||
|
|
||||||
RootAccessibleWrap::RootAccessibleWrap(dom::Document* aDoc,
|
|
||||||
PresShell* aPresShell)
|
|
||||||
: RootAccessible(aDoc, aPresShell) {}
|
|
||||||
|
|
||||||
RootAccessibleWrap::~RootAccessibleWrap() {}
|
|
||||||
|
|
||||||
nsresult RootAccessibleWrap::AddEventListeners() {
|
|
||||||
nsPIDOMWindowOuter* window = mDocumentNode->GetWindow();
|
|
||||||
nsCOMPtr<EventTarget> nstarget = window ? window->GetParentTarget() : nullptr;
|
|
||||||
|
|
||||||
if (nstarget) {
|
|
||||||
nstarget->AddEventListener(u"MozMouseExploreByTouch"_ns, this, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return RootAccessible::AddEventListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult RootAccessibleWrap::RemoveEventListeners() {
|
|
||||||
nsPIDOMWindowOuter* window = mDocumentNode->GetWindow();
|
|
||||||
nsCOMPtr<EventTarget> nstarget = window ? window->GetParentTarget() : nullptr;
|
|
||||||
if (nstarget) {
|
|
||||||
nstarget->RemoveEventListener(u"MozMouseExploreByTouch"_ns, this, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return RootAccessible::RemoveEventListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// nsIDOMEventListener
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
RootAccessibleWrap::HandleEvent(Event* aDOMEvent) {
|
|
||||||
WidgetMouseEvent* widgetEvent = aDOMEvent->WidgetEventPtr()->AsMouseEvent();
|
|
||||||
if (widgetEvent && widgetEvent->mMessage == eMouseExploreByTouch) {
|
|
||||||
if (HasShutdown()) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MouseEvent* mouseEvent = aDOMEvent->AsMouseEvent()) {
|
|
||||||
LayoutDeviceIntPoint point = mouseEvent->ScreenPointLayoutDevicePix();
|
|
||||||
ExploreByTouch(point.x, point.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RootAccessible::HandleEvent(aDOMEvent);
|
|
||||||
}
|
|
||||||
@@ -14,22 +14,7 @@ class PresShell;
|
|||||||
|
|
||||||
namespace a11y {
|
namespace a11y {
|
||||||
|
|
||||||
/**
|
using RootAccessibleWrap = RootAccessible;
|
||||||
* Android specific functionality for the node at a root of the accessibility
|
|
||||||
* tree: see the RootAccessible superclass for further details.
|
|
||||||
*/
|
|
||||||
class RootAccessibleWrap : public RootAccessible {
|
|
||||||
public:
|
|
||||||
RootAccessibleWrap(dom::Document* aDocument, PresShell* aPresShell);
|
|
||||||
virtual ~RootAccessibleWrap();
|
|
||||||
|
|
||||||
// nsIDOMEventListener
|
|
||||||
NS_DECL_NSIDOMEVENTLISTENER
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual nsresult AddEventListeners() override;
|
|
||||||
virtual nsresult RemoveEventListeners() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace a11y
|
} // namespace a11y
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "AccAttributes.h"
|
#include "AccAttributes.h"
|
||||||
#include "AccessibilityEvent.h"
|
#include "AccessibilityEvent.h"
|
||||||
|
#include "DocAccessibleWrap.h"
|
||||||
#include "JavaBuiltins.h"
|
#include "JavaBuiltins.h"
|
||||||
#include "RootAccessibleWrap.h"
|
|
||||||
#include "nsAccessibilityService.h"
|
#include "nsAccessibilityService.h"
|
||||||
#include "nsAccUtils.h"
|
#include "nsAccUtils.h"
|
||||||
#include "nsViewManager.h"
|
#include "nsViewManager.h"
|
||||||
@@ -192,15 +192,30 @@ bool SessionAccessibility::Pivot(int32_t aID, int32_t aGranularity,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SessionAccessibility::ExploreByTouch(int32_t aID, float aX, float aY) {
|
void SessionAccessibility::ExploreByTouch(int32_t aID, float aX, float aY) {
|
||||||
auto gvAccessor(mWindow.Access());
|
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
|
||||||
if (gvAccessor) {
|
MonitorAutoLock mal(nsAccessibilityService::GetAndroidMonitor());
|
||||||
if (nsWindow* gkWindow = gvAccessor->GetNsWindow()) {
|
RefPtr<SessionAccessibility> self(this);
|
||||||
WidgetMouseEvent hittest(true, eMouseExploreByTouch, gkWindow,
|
if (Accessible* origin = GetAccessibleByID(aID)) {
|
||||||
WidgetMouseEvent::eReal);
|
if (origin->IsLocal()) {
|
||||||
hittest.mRefPoint = LayoutDeviceIntPoint::Floor(aX, aY);
|
nsAppShell::PostEvent([this, self, aID, aX, aY] {
|
||||||
hittest.mInputSource = dom::MouseEvent_Binding::MOZ_SOURCE_TOUCH;
|
MonitorAutoLock mal(nsAccessibilityService::GetAndroidMonitor());
|
||||||
hittest.mFlags.mOnlyChromeDispatch = true;
|
if (Accessible* origin = GetAccessibleByID(aID)) {
|
||||||
gkWindow->DispatchInputEvent(&hittest);
|
if (Accessible* result =
|
||||||
|
AccessibleWrap::ExploreByTouch(origin, aX, aY)) {
|
||||||
|
SendHoverEnterEvent(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (Accessible* result = AccessibleWrap::ExploreByTouch(origin, aX, aY)) {
|
||||||
|
int32_t resultID = AccessibleWrap::GetVirtualViewID(result);
|
||||||
|
nsAppShell::PostEvent([this, self, resultID] {
|
||||||
|
MonitorAutoLock mal(nsAccessibilityService::GetAndroidMonitor());
|
||||||
|
if (Accessible* result = GetAccessibleByID(resultID)) {
|
||||||
|
SendHoverEnterEvent(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,17 +11,11 @@
|
|||||||
#include "nsAppShell.h"
|
#include "nsAppShell.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsWindow.h"
|
#include "nsWindow.h"
|
||||||
#include "AccessibleWrap.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace a11y {
|
namespace a11y {
|
||||||
|
|
||||||
class AccessibleWrap;
|
|
||||||
class AccAttributes;
|
|
||||||
class Accessible;
|
class Accessible;
|
||||||
class RemoteAccessible;
|
|
||||||
class RootAccessibleWrap;
|
|
||||||
class BatchData;
|
|
||||||
|
|
||||||
class SessionAccessibility final
|
class SessionAccessibility final
|
||||||
: public java::SessionAccessibility::NativeProvider::Natives<
|
: public java::SessionAccessibility::NativeProvider::Natives<
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ SOURCES += [
|
|||||||
"AccessibleWrap.cpp",
|
"AccessibleWrap.cpp",
|
||||||
"DocAccessibleWrap.cpp",
|
"DocAccessibleWrap.cpp",
|
||||||
"Platform.cpp",
|
"Platform.cpp",
|
||||||
"RootAccessibleWrap.cpp",
|
|
||||||
"SessionAccessibility.cpp",
|
"SessionAccessibility.cpp",
|
||||||
"TraversalRule.cpp",
|
"TraversalRule.cpp",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ interface nsIAccessiblePivot : nsISupports
|
|||||||
const PivotMoveReason REASON_PREV = 2;
|
const PivotMoveReason REASON_PREV = 2;
|
||||||
const PivotMoveReason REASON_FIRST = 3;
|
const PivotMoveReason REASON_FIRST = 3;
|
||||||
const PivotMoveReason REASON_LAST = 4;
|
const PivotMoveReason REASON_LAST = 4;
|
||||||
const PivotMoveReason REASON_POINT = 5;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move pivot to next object, from current position or given anchor,
|
* Move pivot to next object, from current position or given anchor,
|
||||||
|
|||||||
Reference in New Issue
Block a user