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;
|
||||
}
|
||||
|
||||
void AccessibleWrap::ExploreByTouch(float aX, float aY) {
|
||||
a11y::Pivot pivot(RootAccessible());
|
||||
TraversalRule rule;
|
||||
|
||||
Accessible* maybeResult = pivot.AtPoint(aX, aY, rule);
|
||||
LocalAccessible* result = maybeResult ? maybeResult->AsLocal() : nullptr;
|
||||
|
||||
if (result && result != this) {
|
||||
RefPtr<AccEvent> event =
|
||||
new AccVCChangeEvent(result->Document(), this, result,
|
||||
nsIAccessiblePivot::REASON_POINT, eFromUserInput);
|
||||
nsEventShell::FireEvent(event);
|
||||
Accessible* AccessibleWrap::ExploreByTouch(Accessible* aAccessible, float aX,
|
||||
float aY) {
|
||||
Accessible* root;
|
||||
if (LocalAccessible* local = aAccessible->AsLocal()) {
|
||||
root = local->RootAccessible();
|
||||
} else {
|
||||
// If this is a RemoteAccessible, provide the top level
|
||||
// remote doc as the pivot root for thread safety reasons.
|
||||
DocAccessibleParent* doc = aAccessible->AsRemote()->Document();
|
||||
while (doc && !doc->IsTopLevel()) {
|
||||
doc = doc->ParentDoc();
|
||||
}
|
||||
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) {
|
||||
|
||||
@@ -30,7 +30,8 @@ class AccessibleWrap : public LocalAccessible {
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
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);
|
||||
|
||||
|
||||
@@ -186,12 +186,8 @@ void a11y::PlatformVirtualCursorChangeEvent(Accessible* aTarget,
|
||||
return;
|
||||
}
|
||||
|
||||
if (aReason == nsIAccessiblePivot::REASON_POINT) {
|
||||
sessionAcc->SendHoverEnterEvent(aNewPosition);
|
||||
} else {
|
||||
sessionAcc->SendAccessibilityFocusedEvent(aNewPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void a11y::PlatformScrollingEvent(Accessible* aTarget, uint32_t aEventType,
|
||||
uint32_t aScrollX, uint32_t aScrollY,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
using RootAccessibleWrap = RootAccessible;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "AccAttributes.h"
|
||||
#include "AccessibilityEvent.h"
|
||||
#include "DocAccessibleWrap.h"
|
||||
#include "JavaBuiltins.h"
|
||||
#include "RootAccessibleWrap.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsAccUtils.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) {
|
||||
auto gvAccessor(mWindow.Access());
|
||||
if (gvAccessor) {
|
||||
if (nsWindow* gkWindow = gvAccessor->GetNsWindow()) {
|
||||
WidgetMouseEvent hittest(true, eMouseExploreByTouch, gkWindow,
|
||||
WidgetMouseEvent::eReal);
|
||||
hittest.mRefPoint = LayoutDeviceIntPoint::Floor(aX, aY);
|
||||
hittest.mInputSource = dom::MouseEvent_Binding::MOZ_SOURCE_TOUCH;
|
||||
hittest.mFlags.mOnlyChromeDispatch = true;
|
||||
gkWindow->DispatchInputEvent(&hittest);
|
||||
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
|
||||
MonitorAutoLock mal(nsAccessibilityService::GetAndroidMonitor());
|
||||
RefPtr<SessionAccessibility> self(this);
|
||||
if (Accessible* origin = GetAccessibleByID(aID)) {
|
||||
if (origin->IsLocal()) {
|
||||
nsAppShell::PostEvent([this, self, aID, aX, aY] {
|
||||
MonitorAutoLock mal(nsAccessibilityService::GetAndroidMonitor());
|
||||
if (Accessible* origin = GetAccessibleByID(aID)) {
|
||||
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 "nsThreadUtils.h"
|
||||
#include "nsWindow.h"
|
||||
#include "AccessibleWrap.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class AccessibleWrap;
|
||||
class AccAttributes;
|
||||
class Accessible;
|
||||
class RemoteAccessible;
|
||||
class RootAccessibleWrap;
|
||||
class BatchData;
|
||||
|
||||
class SessionAccessibility final
|
||||
: public java::SessionAccessibility::NativeProvider::Natives<
|
||||
|
||||
@@ -14,7 +14,6 @@ SOURCES += [
|
||||
"AccessibleWrap.cpp",
|
||||
"DocAccessibleWrap.cpp",
|
||||
"Platform.cpp",
|
||||
"RootAccessibleWrap.cpp",
|
||||
"SessionAccessibility.cpp",
|
||||
"TraversalRule.cpp",
|
||||
]
|
||||
|
||||
@@ -26,7 +26,6 @@ interface nsIAccessiblePivot : nsISupports
|
||||
const PivotMoveReason REASON_PREV = 2;
|
||||
const PivotMoveReason REASON_FIRST = 3;
|
||||
const PivotMoveReason REASON_LAST = 4;
|
||||
const PivotMoveReason REASON_POINT = 5;
|
||||
|
||||
/**
|
||||
* Move pivot to next object, from current position or given anchor,
|
||||
|
||||
Reference in New Issue
Block a user