Bug 1880594 - Make PresShell::EventHandler dispatch mouse events as a default action of eTouchEnd if it's dispatched without APZ r=smaug
The mouse events for `eTouchEnd` is currently dispatched by `APZCCallbackHelper` [1] and currently we don't support async event dispatching in WPT (bug 1773393). Therefore, tests of Pointer Events for touch won't work. This blocks our further work to improve Pointer Events. Therefore, `PresShell::EventHandler` should have a fallback path for it. 1. https://searchfox.org/mozilla-central/rev/a7809ff8b0a6d98e6df3183d3ca99c77ef2f983e/gfx/layers/apz/util/APZCCallbackHelper.cpp#553,562-567 Differential Revision: https://phabricator.services.mozilla.com/D202376
This commit is contained in:
@@ -9,11 +9,13 @@
|
||||
#include "mozilla/PresShell.h"
|
||||
|
||||
#include "Units.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/AncestorIterator.h"
|
||||
#include "mozilla/dom/FontFaceSet.h"
|
||||
#include "mozilla/dom/ElementBinding.h"
|
||||
#include "mozilla/dom/LargestContentfulPaint.h"
|
||||
#include "mozilla/dom/MouseEventBinding.h"
|
||||
#include "mozilla/dom/PerformanceMainThread.h"
|
||||
#include "mozilla/dom/HTMLAreaElement.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
@@ -45,6 +47,7 @@
|
||||
#include "mozilla/StaticPrefs_font.h"
|
||||
#include "mozilla/StaticPrefs_image.h"
|
||||
#include "mozilla/StaticPrefs_layout.h"
|
||||
#include "mozilla/StaticPrefs_test.h"
|
||||
#include "mozilla/StaticPrefs_toolkit.h"
|
||||
#include "mozilla/Try.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
@@ -7267,7 +7270,17 @@ nsresult PresShell::EventHandler::HandleEventUsingCoordinates(
|
||||
nsresult rv = eventHandler.HandleEventWithCurrentEventInfo(
|
||||
aGUIEvent, aEventStatus, true,
|
||||
MOZ_KnownLive(eventTargetData.mOverrideClickTarget));
|
||||
return rv;
|
||||
if (NS_FAILED(rv) ||
|
||||
MOZ_UNLIKELY(eventTargetData.mPresShell->IsDestroying())) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aGUIEvent->mMessage == eTouchEnd) {
|
||||
MaybeSynthesizeCompatMouseEventsForTouchEnd(aGUIEvent->AsTouchEvent(),
|
||||
aEventStatus);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool PresShell::EventHandler::MaybeFlushPendingNotifications(
|
||||
@@ -7586,6 +7599,60 @@ bool PresShell::EventHandler::MaybeHandleEventWithAccessibleCaret(
|
||||
return true;
|
||||
}
|
||||
|
||||
void PresShell::EventHandler::MaybeSynthesizeCompatMouseEventsForTouchEnd(
|
||||
const WidgetTouchEvent* aTouchEndEvent,
|
||||
const nsEventStatus* aStatus) const {
|
||||
MOZ_ASSERT(aTouchEndEvent->mMessage == eTouchEnd);
|
||||
|
||||
// If the eTouchEnd event is dispatched via APZ, APZCCallbackHelper dispatches
|
||||
// a set of mouse events with better handling. Therefore, we don't need to
|
||||
// handle that here.
|
||||
if (!aTouchEndEvent->mFlags.mIsSynthesizedForTests ||
|
||||
StaticPrefs::test_events_async_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the tap was consumed or 2 or more touches occurred, we don't need the
|
||||
// compatibility mouse events.
|
||||
if (*aStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
!TouchManager::IsSingleTapEndToDoDefault(aTouchEndEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!aTouchEndEvent->mWidget)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = aTouchEndEvent->mWidget;
|
||||
|
||||
// NOTE: I think that we don't need to implement a double click here becase
|
||||
// WebDriver does not support a way to synthesize a double click and Chrome
|
||||
// does not fire "dblclick" even if doing `pointerDown().pointerUp()` twice.
|
||||
// FIXME: Currently we don't support long tap.
|
||||
RefPtr<PresShell> presShell = mPresShell;
|
||||
for (const EventMessage message : {eMouseMove, eMouseDown, eMouseUp}) {
|
||||
if (MOZ_UNLIKELY(presShell->IsDestroying())) {
|
||||
break;
|
||||
}
|
||||
nsIFrame* frameForPresShell = GetNearestFrameContainingPresShell(presShell);
|
||||
if (!frameForPresShell) {
|
||||
break;
|
||||
}
|
||||
WidgetMouseEvent event(true, message, widget, WidgetMouseEvent::eReal,
|
||||
WidgetMouseEvent::eNormal);
|
||||
event.mRefPoint = aTouchEndEvent->mTouches[0]->mRefPoint;
|
||||
event.mButton = MouseButton::ePrimary;
|
||||
event.mButtons = message == eMouseDown ? MouseButtonsFlag::ePrimaryFlag
|
||||
: MouseButtonsFlag::eNoButtons;
|
||||
event.mInputSource = MouseEvent_Binding::MOZ_SOURCE_TOUCH;
|
||||
event.mClickCount = message == eMouseMove ? 0 : 1;
|
||||
event.mModifiers = aTouchEndEvent->mModifiers;
|
||||
event.convertToPointer = false;
|
||||
nsEventStatus mouseEventStatus = nsEventStatus_eIgnore;
|
||||
presShell->HandleEvent(frameForPresShell, &event, false, &mouseEventStatus);
|
||||
}
|
||||
}
|
||||
|
||||
bool PresShell::EventHandler::MaybeDiscardEvent(WidgetGUIEvent* aGUIEvent) {
|
||||
MOZ_ASSERT(aGUIEvent);
|
||||
|
||||
@@ -8360,7 +8427,7 @@ nsresult PresShell::EventHandler::HandleEventWithCurrentEventInfo(
|
||||
manager->TryToFlushPendingNotificationsToIME();
|
||||
}
|
||||
|
||||
FinalizeHandlingEvent(aEvent);
|
||||
FinalizeHandlingEvent(aEvent, aEventStatus);
|
||||
|
||||
RecordEventHandlingResponsePerformance(aEvent);
|
||||
|
||||
@@ -8512,7 +8579,8 @@ bool PresShell::EventHandler::PrepareToDispatchEvent(
|
||||
}
|
||||
}
|
||||
|
||||
void PresShell::EventHandler::FinalizeHandlingEvent(WidgetEvent* aEvent) {
|
||||
void PresShell::EventHandler::FinalizeHandlingEvent(
|
||||
WidgetEvent* aEvent, const nsEventStatus* aStatus) {
|
||||
switch (aEvent->mMessage) {
|
||||
case eKeyPress:
|
||||
case eKeyDown:
|
||||
@@ -8562,6 +8630,16 @@ void PresShell::EventHandler::FinalizeHandlingEvent(WidgetEvent* aEvent) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
case eTouchStart:
|
||||
case eTouchMove:
|
||||
case eTouchEnd:
|
||||
case eTouchCancel:
|
||||
case eTouchPointerCancel:
|
||||
case eMouseLongTap:
|
||||
case eContextMenu: {
|
||||
mPresShell->mTouchManager.PostHandleEvent(aEvent, aStatus);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user