Revert "Bug 1550462 - part 3: Enable pointerrawupdate event r=smaug" for causing mochitest failures @ test_pointerrawupdate_event_count.html
This reverts commiteb27445e03. Revert "Bug 1550462 - part 2: Make `PresShell::HandleEvent` dispatch preceding `pointerrawupdate` event r=smaug,dom-core,edgar" This reverts commit502f22686c. Revert "Bug 1550462 - part 1: Define `pointerawupdate` event r=smaug" This reverts commit2b13850454.
This commit is contained in:
committed by
amarc@mozilla.com
parent
3ae4b28862
commit
46de26821c
@@ -1133,8 +1133,6 @@ void nsGlobalWindowInner::FreeInnerObjects() {
|
||||
}
|
||||
StartDying();
|
||||
|
||||
ClearHasPointerRawUpdateEventListeners();
|
||||
|
||||
if (mDoc && mDoc->GetWindowContext()) {
|
||||
// The document is about to lose its window, so this is a good time to send
|
||||
// our page use counters.
|
||||
@@ -7689,26 +7687,6 @@ TrustedTypePolicyFactory* nsGlobalWindowInner::TrustedTypes() {
|
||||
return mTrustedTypePolicyFactory;
|
||||
}
|
||||
|
||||
void nsPIDOMWindowInner::MaybeSetHasPointerRawUpdateEventListeners() {
|
||||
if (HasPointerRawUpdateEventListeners() || !IsSecureContext()) {
|
||||
return;
|
||||
}
|
||||
mMayHavePointerRawUpdateEventListener = true;
|
||||
if (BrowserChild* const browserChild = BrowserChild::GetFrom(this)) {
|
||||
browserChild->OnPointerRawUpdateEventListenerAdded(this);
|
||||
}
|
||||
}
|
||||
|
||||
void nsPIDOMWindowInner::ClearHasPointerRawUpdateEventListeners() {
|
||||
if (!HasPointerRawUpdateEventListeners()) {
|
||||
return;
|
||||
}
|
||||
mMayHavePointerRawUpdateEventListener = false;
|
||||
if (BrowserChild* const browserChild = BrowserChild::GetFrom(this)) {
|
||||
browserChild->OnPointerRawUpdateEventListenerRemoved(this);
|
||||
}
|
||||
}
|
||||
|
||||
nsIURI* nsPIDOMWindowInner::GetDocumentURI() const {
|
||||
return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
|
||||
}
|
||||
@@ -7799,7 +7777,29 @@ CloseWatcherManager* nsPIDOMWindowInner::EnsureCloseWatcherManager() {
|
||||
|
||||
nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
|
||||
WindowGlobalChild* aActor)
|
||||
: mOuterWindow(aOuterWindow), mWindowGlobalChild(aActor) {
|
||||
: mMutationBits(0),
|
||||
mIsDocumentLoaded(false),
|
||||
mIsHandlingResizeEvent(false),
|
||||
mMayHaveDOMActivateEventListeners(false),
|
||||
mMayHaveTouchEventListener(false),
|
||||
mMayHaveSelectionChangeEventListener(false),
|
||||
mMayHaveFormSelectEventListener(false),
|
||||
mMayHaveMouseEnterLeaveEventListener(false),
|
||||
mMayHavePointerEnterLeaveEventListener(false),
|
||||
mMayHaveTransitionEventListener(false),
|
||||
mMayHaveSMILTimeEventListener(false),
|
||||
mMayHaveBeforeInputEventListenerForTelemetry(false),
|
||||
mMutationObserverHasObservedNodeForTelemetry(false),
|
||||
mOuterWindow(aOuterWindow),
|
||||
mWindowID(0),
|
||||
mHasNotifiedGlobalCreated(false),
|
||||
mMarkedCCGeneration(0),
|
||||
mHasTriedToCacheTopInnerWindow(false),
|
||||
mNumOfIndexedDBDatabases(0),
|
||||
mNumOfOpenWebSockets(0),
|
||||
mEvent(nullptr),
|
||||
mWindowGlobalChild(aActor),
|
||||
mWasSuspendedByGroup(false) {
|
||||
MOZ_ASSERT(aOuterWindow);
|
||||
mBrowsingContext = aOuterWindow->GetBrowsingContext();
|
||||
|
||||
|
||||
@@ -3656,9 +3656,6 @@ already_AddRefed<nsINode> nsINode::CloneAndAdopt(
|
||||
if (elm->MayHavePointerEnterLeaveEventListener()) {
|
||||
window->SetHasPointerEnterLeaveEventListeners();
|
||||
}
|
||||
if (elm->MayHavePointerRawUpdateEventListener()) {
|
||||
window->MaybeSetHasPointerRawUpdateEventListeners();
|
||||
}
|
||||
if (elm->MayHaveSelectionChangeEventListener()) {
|
||||
window->SetHasSelectionChangeEventListeners();
|
||||
}
|
||||
|
||||
@@ -224,29 +224,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
mMayHavePointerEnterLeaveEventListener = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to check whether some node (this window, its document,
|
||||
* or content in that document) has a pointerrawupdate event listener.
|
||||
*/
|
||||
bool HasPointerRawUpdateEventListeners() const {
|
||||
return mMayHavePointerRawUpdateEventListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to indicate that some node (this window, its document,
|
||||
* or content in that document) has a pointerrawupdate event listener.
|
||||
* This may not accept that if the event is not available in this window.
|
||||
*/
|
||||
void MaybeSetHasPointerRawUpdateEventListeners();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Call this to clear whether some nodes has a pointerrawupdate event
|
||||
* listener.
|
||||
*/
|
||||
void ClearHasPointerRawUpdateEventListeners();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Call this to check whether some node (this window, its document,
|
||||
* or content in that document) has a transition* event listeners.
|
||||
@@ -672,25 +649,24 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
RefPtr<mozilla::dom::Navigator> mNavigator;
|
||||
|
||||
// These variables are only used on inner windows.
|
||||
uint32_t mMutationBits = 0;
|
||||
uint32_t mMutationBits;
|
||||
|
||||
uint32_t mActivePeerConnections = 0;
|
||||
|
||||
bool mIsDocumentLoaded = false;
|
||||
bool mIsHandlingResizeEvent = false;
|
||||
bool mMayHaveDOMActivateEventListeners = false;
|
||||
bool mMayHaveTouchEventListener = false;
|
||||
bool mMayHaveSelectionChangeEventListener = false;
|
||||
bool mMayHaveFormSelectEventListener = false;
|
||||
bool mMayHaveMouseEnterLeaveEventListener = false;
|
||||
bool mMayHavePointerEnterLeaveEventListener = false;
|
||||
bool mMayHavePointerRawUpdateEventListener = false;
|
||||
bool mMayHaveTransitionEventListener = false;
|
||||
bool mMayHaveSMILTimeEventListener = false;
|
||||
bool mIsDocumentLoaded;
|
||||
bool mIsHandlingResizeEvent;
|
||||
bool mMayHaveDOMActivateEventListeners;
|
||||
bool mMayHaveTouchEventListener;
|
||||
bool mMayHaveSelectionChangeEventListener;
|
||||
bool mMayHaveFormSelectEventListener;
|
||||
bool mMayHaveMouseEnterLeaveEventListener;
|
||||
bool mMayHavePointerEnterLeaveEventListener;
|
||||
bool mMayHaveTransitionEventListener;
|
||||
bool mMayHaveSMILTimeEventListener;
|
||||
// Only used for telemetry probes. This may be wrong if some nodes have
|
||||
// come from another document with `Document.adoptNode`.
|
||||
bool mMayHaveBeforeInputEventListenerForTelemetry = false;
|
||||
bool mMutationObserverHasObservedNodeForTelemetry = false;
|
||||
bool mMayHaveBeforeInputEventListenerForTelemetry;
|
||||
bool mMutationObserverHasObservedNodeForTelemetry;
|
||||
|
||||
// Our inner window's outer window.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> mOuterWindow;
|
||||
@@ -711,11 +687,11 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
|
||||
// A unique (as long as our 64-bit counter doesn't roll over) id for
|
||||
// this window.
|
||||
uint64_t mWindowID = 0;
|
||||
uint64_t mWindowID;
|
||||
|
||||
// Set to true once we've sent the (chrome|content)-document-global-created
|
||||
// notification.
|
||||
bool mHasNotifiedGlobalCreated = false;
|
||||
bool mHasNotifiedGlobalCreated;
|
||||
|
||||
// Whether when focused via an "unknown" focus method, we should show outlines
|
||||
// by default or not. The initial value of this is true (so as to show
|
||||
@@ -723,7 +699,7 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
// without any other user interaction).
|
||||
bool mUnknownFocusMethodShouldShowOutline = true;
|
||||
|
||||
uint32_t mMarkedCCGeneration = 0;
|
||||
uint32_t mMarkedCCGeneration;
|
||||
|
||||
// mTopInnerWindow is used for tab-wise check by timeout throttling. It could
|
||||
// be null.
|
||||
@@ -732,17 +708,17 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
// The evidence that we have tried to cache mTopInnerWindow only once from
|
||||
// SetNewDocument(). Note: We need this extra flag because mTopInnerWindow
|
||||
// could be null and we don't want it to be set multiple times.
|
||||
bool mHasTriedToCacheTopInnerWindow = false;
|
||||
bool mHasTriedToCacheTopInnerWindow;
|
||||
|
||||
// The number of active IndexedDB databases.
|
||||
uint32_t mNumOfIndexedDBDatabases = 0;
|
||||
uint32_t mNumOfIndexedDBDatabases;
|
||||
|
||||
// The number of open WebSockets.
|
||||
uint32_t mNumOfOpenWebSockets = 0;
|
||||
uint32_t mNumOfOpenWebSockets;
|
||||
|
||||
// The event dispatch code sets and unsets this while keeping
|
||||
// the event object alive.
|
||||
mozilla::dom::Event* mEvent = nullptr;
|
||||
mozilla::dom::Event* mEvent;
|
||||
|
||||
// The WindowGlobalChild actor for this window.
|
||||
//
|
||||
@@ -750,7 +726,7 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
// during SetNewDocument, and cleared during FreeInnerObjects.
|
||||
RefPtr<mozilla::dom::WindowGlobalChild> mWindowGlobalChild;
|
||||
|
||||
bool mWasSuspendedByGroup = false;
|
||||
bool mWasSuspendedByGroup;
|
||||
|
||||
/**
|
||||
* Count of the number of active LockRequest objects, including ones from
|
||||
|
||||
@@ -25,12 +25,8 @@
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/dom/AbortSignal.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/ChromeUtils.h"
|
||||
#include "mozilla/dom/EventCallbackDebuggerNotification.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
@@ -41,6 +37,9 @@
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/TouchEvent.h"
|
||||
#include "mozilla/dom/UserActivation.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/dom/ChromeUtils.h"
|
||||
|
||||
#include "EventListenerService.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@@ -146,7 +145,6 @@ EventListenerManagerBase::EventListenerManagerBase()
|
||||
mMayHaveTouchEventListener(false),
|
||||
mMayHaveMouseEnterLeaveEventListener(false),
|
||||
mMayHavePointerEnterLeaveEventListener(false),
|
||||
mMayHavePointerRawUpdateEventListener(false),
|
||||
mMayHaveSelectionChangeEventListener(false),
|
||||
mMayHaveFormSelectEventListener(false),
|
||||
mMayHaveTransitionEventListener(false),
|
||||
@@ -415,18 +413,6 @@ void EventListenerManager::AddEventListenerInternal(
|
||||
window->SetHasPointerEnterLeaveEventListeners();
|
||||
}
|
||||
break;
|
||||
case ePointerRawUpdate:
|
||||
if (!StaticPrefs::dom_event_pointer_rawupdate_enabled()) {
|
||||
break;
|
||||
}
|
||||
mMayHavePointerRawUpdateEventListener = true;
|
||||
if (nsPIDOMWindowInner* window = GetInnerWindowForTarget()) {
|
||||
NS_WARNING_ASSERTION(
|
||||
!nsContentUtils::IsChromeDoc(window->GetExtantDoc()),
|
||||
"Please do not use pointerrawupdate event in chrome.");
|
||||
window->MaybeSetHasPointerRawUpdateEventListeners();
|
||||
}
|
||||
break;
|
||||
case eGamepadButtonDown:
|
||||
case eGamepadButtonUp:
|
||||
case eGamepadAxisMove:
|
||||
@@ -876,15 +862,6 @@ void EventListenerManager::RemoveEventListenerInternal(
|
||||
DisableDevice(aUserType);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX Should we clear mMayHavePointerRawUpdateEventListener if the last
|
||||
// pointerrawupdate event listener is removed? If so, nsPIDOMWindowInner
|
||||
// needs to count how may event listener managers had some pointerrawupdate
|
||||
// event listener. If we've notified the window of having a pointerrawupdate
|
||||
// event listener, some behavior is changed because pointerrawupdate event
|
||||
// dispatcher needs to handle some things before dispatching an event to the
|
||||
// DOM. However, it is expected that web apps using `pointerrawupdate` don't
|
||||
// remove the event listeners.
|
||||
}
|
||||
|
||||
static bool IsDefaultPassiveWhenOnRoot(EventMessage aMessage) {
|
||||
@@ -1852,20 +1829,16 @@ bool EventListenerManager::HasNonPassiveListenersFor(
|
||||
// After dispatching wheel, legacy mouse scroll events are dispatched
|
||||
// and listeners on those can also default prevent the behavior.
|
||||
if (aEvent->mMessage == eWheel) {
|
||||
if (const auto& listeners =
|
||||
mListenerMap.GetListenersForType(nsGkAtoms::onDOMMouseScroll)) {
|
||||
if (const auto& listeners = mListenerMap.GetListenersForType(nsGkAtoms::onDOMMouseScroll)) {
|
||||
for (const Listener& listener : listeners->NonObservingRange()) {
|
||||
if (!listener.mFlags.mPassive &&
|
||||
ListenerCanHandle(&listener, aEvent)) {
|
||||
if (!listener.mFlags.mPassive && ListenerCanHandle(&listener, aEvent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (const auto& listeners = mListenerMap.GetListenersForType(
|
||||
nsGkAtoms::onMozMousePixelScroll)) {
|
||||
if (const auto& listeners = mListenerMap.GetListenersForType(nsGkAtoms::onMozMousePixelScroll)) {
|
||||
for (const Listener& listener : listeners->NonObservingRange()) {
|
||||
if (!listener.mFlags.mPassive &&
|
||||
ListenerCanHandle(&listener, aEvent)) {
|
||||
if (!listener.mFlags.mPassive && ListenerCanHandle(&listener, aEvent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,6 @@ class EventListenerManagerBase {
|
||||
uint16_t mMayHaveTouchEventListener : 1;
|
||||
uint16_t mMayHaveMouseEnterLeaveEventListener : 1;
|
||||
uint16_t mMayHavePointerEnterLeaveEventListener : 1;
|
||||
uint16_t mMayHavePointerRawUpdateEventListener : 1;
|
||||
uint16_t mMayHaveSelectionChangeEventListener : 1;
|
||||
uint16_t mMayHaveFormSelectEventListener : 1;
|
||||
uint16_t mMayHaveTransitionEventListener : 1;
|
||||
@@ -555,9 +554,6 @@ class EventListenerManager final : public EventListenerManagerBase {
|
||||
bool MayHavePointerEnterLeaveEventListener() const {
|
||||
return mMayHavePointerEnterLeaveEventListener;
|
||||
}
|
||||
bool MayHavePointerRawUpdateEventListener() const {
|
||||
return mMayHavePointerRawUpdateEventListener;
|
||||
}
|
||||
bool MayHaveSelectionChangeEventListener() const {
|
||||
return mMayHaveSelectionChangeEventListener;
|
||||
}
|
||||
|
||||
@@ -225,8 +225,6 @@ EVENT(pointerover, ePointerOver, EventNameType_All, ePointerEventClass)
|
||||
EVENT(pointerout, ePointerOut, EventNameType_All, ePointerEventClass)
|
||||
EVENT(pointerenter, ePointerEnter, EventNameType_All, ePointerEventClass)
|
||||
EVENT(pointerleave, ePointerLeave, EventNameType_All, ePointerEventClass)
|
||||
EVENT(pointerrawupdate, ePointerRawUpdate, EventNameType_All,
|
||||
ePointerEventClass)
|
||||
EVENT(gotpointercapture, ePointerGotCapture, EventNameType_All,
|
||||
ePointerEventClass)
|
||||
EVENT(lostpointercapture, ePointerLostCapture, EventNameType_All,
|
||||
|
||||
@@ -995,7 +995,6 @@ nsresult EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
if (touchEvent->mMessage == eTouchMove) {
|
||||
GenerateDragGesture(aPresContext, touchEvent);
|
||||
} else {
|
||||
MOZ_ASSERT(touchEvent->mMessage != eTouchRawUpdate);
|
||||
mInTouchDrag = false;
|
||||
StopTrackingDragGesture(true);
|
||||
}
|
||||
@@ -1143,8 +1142,7 @@ nsresult EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
[[fallthrough]];
|
||||
case eMouseMove:
|
||||
case ePointerMove:
|
||||
case ePointerRawUpdate: {
|
||||
case ePointerMove: {
|
||||
if (aEvent->mMessage == ePointerMove) {
|
||||
PointerEventHandler::UpdateActivePointerState(mouseEvent,
|
||||
aTargetContent);
|
||||
@@ -4368,22 +4366,20 @@ nsresult EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
// events after they have been processed. When determining if
|
||||
// a swipe should occur, we should not prefer the current wheel
|
||||
// transaction.
|
||||
nsIFrame* lastScrollFrame =
|
||||
WheelTransaction::GetScrollTargetFrame();
|
||||
nsIFrame* lastScrollFrame = WheelTransaction::GetScrollTargetFrame();
|
||||
bool wheelTransactionHandlesInput = false;
|
||||
if (lastScrollFrame) {
|
||||
ScrollContainerFrame* scrollContainerFrame =
|
||||
lastScrollFrame->GetScrollTargetFrame();
|
||||
ScrollContainerFrame* scrollContainerFrame = lastScrollFrame->GetScrollTargetFrame();
|
||||
if (scrollContainerFrame->IsRootScrollFrameOfDocument()) {
|
||||
// If the current wheel transaction target is the root scroll
|
||||
// frame and is not scrollable on the x-axis, all delta is
|
||||
// overflown and swipe-to-nav may occur.
|
||||
wheelTransactionHandlesInput = true;
|
||||
allDeltaOverflown = !WheelHandlingUtils::CanScrollOn(
|
||||
scrollContainerFrame, wheelEvent->mDeltaX, 0.0);
|
||||
} else if (WheelHandlingUtils::CanScrollOn(
|
||||
scrollContainerFrame, wheelEvent->mDeltaX,
|
||||
wheelEvent->mDeltaY)) {
|
||||
allDeltaOverflown = !WheelHandlingUtils::CanScrollOn(scrollContainerFrame,
|
||||
wheelEvent->mDeltaX, 0.0);
|
||||
} else if(WheelHandlingUtils::CanScrollOn(scrollContainerFrame,
|
||||
wheelEvent->mDeltaX,
|
||||
wheelEvent->mDeltaY)) {
|
||||
// If the current wheel transaction target is not the root
|
||||
// scroll frame, ensure that swipe to nav does not occur if
|
||||
// the scroll frame is scrollable on the x or y axis. If the
|
||||
@@ -5568,8 +5564,7 @@ void EventStateManager::GeneratePointerEnterExit(EventMessage aMessage,
|
||||
/* static */
|
||||
void EventStateManager::UpdateLastRefPointOfMouseEvent(
|
||||
WidgetMouseEvent* aMouseEvent) {
|
||||
if (aMouseEvent->mMessage != ePointerRawUpdate &&
|
||||
aMouseEvent->mMessage != eMouseMove &&
|
||||
if (aMouseEvent->mMessage != eMouseMove &&
|
||||
aMouseEvent->mMessage != ePointerMove) {
|
||||
return;
|
||||
}
|
||||
@@ -5602,8 +5597,7 @@ void EventStateManager::UpdateLastRefPointOfMouseEvent(
|
||||
void EventStateManager::ResetPointerToWindowCenterWhilePointerLocked(
|
||||
WidgetMouseEvent* aMouseEvent) {
|
||||
MOZ_ASSERT(PointerLockManager::IsLocked());
|
||||
if ((aMouseEvent->mMessage != ePointerRawUpdate &&
|
||||
aMouseEvent->mMessage != eMouseMove &&
|
||||
if ((aMouseEvent->mMessage != eMouseMove &&
|
||||
aMouseEvent->mMessage != ePointerMove) ||
|
||||
!aMouseEvent->mWidget) {
|
||||
return;
|
||||
@@ -5664,7 +5658,6 @@ void EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent) {
|
||||
switch (aMouseEvent->mMessage) {
|
||||
case eMouseMove:
|
||||
case ePointerMove:
|
||||
case ePointerRawUpdate:
|
||||
case ePointerDown:
|
||||
case ePointerGotCapture: {
|
||||
// Get the target content target (mousemove target == mouseover target)
|
||||
|
||||
@@ -385,9 +385,7 @@ void PointerEvent::GetCoalescedEvents(
|
||||
|
||||
void PointerEvent::EnsureFillingCoalescedEvents(
|
||||
WidgetPointerEvent& aWidgetEvent) {
|
||||
if (!aWidgetEvent.IsTrusted() ||
|
||||
(aWidgetEvent.mMessage != ePointerMove &&
|
||||
aWidgetEvent.mMessage != ePointerRawUpdate) ||
|
||||
if (!aWidgetEvent.IsTrusted() || aWidgetEvent.mMessage != ePointerMove ||
|
||||
!mCoalescedEvents.IsEmpty() ||
|
||||
(aWidgetEvent.mCoalescedWidgetEvents &&
|
||||
!aWidgetEvent.mCoalescedWidgetEvents->mEvents.IsEmpty()) ||
|
||||
|
||||
@@ -715,9 +715,7 @@ void PointerEventHandler::InitPointerEventFromTouch(
|
||||
WidgetPointerEvent& aPointerEvent, const WidgetTouchEvent& aTouchEvent,
|
||||
const mozilla::dom::Touch& aTouch) {
|
||||
// Use mButton/mButtons only when mButton got a value (from pen input)
|
||||
int16_t button = aTouchEvent.mMessage == eTouchRawUpdate ||
|
||||
aTouchEvent.mMessage == eTouchMove
|
||||
? MouseButton::eNotPressed
|
||||
int16_t button = aTouchEvent.mMessage == eTouchMove ? MouseButton::eNotPressed
|
||||
: aTouchEvent.mButton != MouseButton::eNotPressed
|
||||
? aTouchEvent.mButton
|
||||
: MouseButton::ePrimary;
|
||||
@@ -785,9 +783,6 @@ EventMessage PointerEventHandler::ToPointerEventMessage(
|
||||
MOZ_ASSERT(aMouseOrTouchEvent);
|
||||
|
||||
switch (aMouseOrTouchEvent->mMessage) {
|
||||
case eMouseRawUpdate:
|
||||
case eTouchRawUpdate:
|
||||
return ePointerRawUpdate;
|
||||
case eMouseMove:
|
||||
return ePointerMove;
|
||||
case eMouseUp:
|
||||
@@ -814,15 +809,6 @@ EventMessage PointerEventHandler::ToPointerEventMessage(
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool PointerEventHandler::NeedToDispatchPointerRawUpdate(
|
||||
const Document* aDocument) {
|
||||
const nsPIDOMWindowInner* const innerWindow =
|
||||
aDocument ? aDocument->GetInnerWindow() : nullptr;
|
||||
return innerWindow && innerWindow->HasPointerRawUpdateEventListeners() &&
|
||||
innerWindow->IsSecureContext();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void PointerEventHandler::DispatchPointerFromMouseOrTouch(
|
||||
PresShell* aShell, nsIFrame* aEventTargetFrame,
|
||||
@@ -852,8 +838,10 @@ void PointerEventHandler::DispatchPointerFromMouseOrTouch(
|
||||
}
|
||||
|
||||
// 1. If it is not mouse then it is likely will come as touch event
|
||||
// 2. We don't synthesize pointer events for synthesized mouse move
|
||||
if (!mouseEvent->convertToPointer || mouseEvent->IsSynthesized()) {
|
||||
// 2. We don't synthesize pointer events for those events that are not
|
||||
// dispatched to DOM.
|
||||
if (!mouseEvent->convertToPointer ||
|
||||
!aMouseOrTouchEvent->IsAllowedToDispatchDOMEvent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -861,30 +849,6 @@ void PointerEventHandler::DispatchPointerFromMouseOrTouch(
|
||||
if (pointerMessage == eVoidEvent) {
|
||||
return;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (pointerMessage == ePointerRawUpdate) {
|
||||
const nsIContent* const targetContent =
|
||||
aEventTargetContent ? aEventTargetContent
|
||||
: aEventTargetFrame->GetContent();
|
||||
NS_ASSERTION(targetContent, "Where do we want to try to dispatch?");
|
||||
if (targetContent) {
|
||||
NS_ASSERTION(
|
||||
targetContent->IsInComposedDoc(),
|
||||
nsPrintfCString("Do we want to dispatch ePointerRawUpdate onto "
|
||||
"disconnected content? (targetContent=%s)",
|
||||
ToString(*targetContent).c_str())
|
||||
.get());
|
||||
if (!NeedToDispatchPointerRawUpdate(targetContent->OwnerDoc())) {
|
||||
NS_ASSERTION(
|
||||
false,
|
||||
nsPrintfCString(
|
||||
"Did we fail to retarget the document? (targetContent=%s)",
|
||||
ToString(*targetContent).c_str())
|
||||
.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // #ifdef DEBUG
|
||||
WidgetPointerEvent event(*mouseEvent);
|
||||
InitPointerEventFromMouse(&event, mouseEvent, pointerMessage);
|
||||
event.convertToPointer = mouseEvent->convertToPointer = false;
|
||||
@@ -963,7 +927,7 @@ void PointerEventHandler::DispatchPointerFromMouseOrTouch(
|
||||
// all pointer events should be dispatched to the same target as their
|
||||
// corresponding touch events. Call PresShell::HandleEvent so that we do
|
||||
// hit test for pointer events.
|
||||
// FIXME: If aDontRetargetEvents is false and the event is fired on
|
||||
// FIXME: If aDontRetargetEvents is true and the event is fired on
|
||||
// different document, we cannot track the pointer event target when
|
||||
// it's removed from the tree.
|
||||
PreHandlePointerEventsPreventDefault(&event, aMouseOrTouchEvent);
|
||||
@@ -1028,15 +992,9 @@ void PointerEventHandler::NotifyDestroyPresContext(
|
||||
bool PointerEventHandler::IsDragAndDropEnabled(WidgetMouseEvent& aEvent) {
|
||||
// We shouldn't start a drag session if the event is synthesized one because
|
||||
// aEvent doesn't have enough information for initializing the ePointerCancel.
|
||||
if (aEvent.IsSynthesized()) {
|
||||
if (!aEvent.IsReal()) {
|
||||
return false;
|
||||
}
|
||||
// And we should not start with raw update events, which should be used only
|
||||
// for notifying web apps of the pointer state changes ASAP.
|
||||
if (aEvent.mMessage == ePointerRawUpdate) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(aEvent.mMessage != eMouseRawUpdate);
|
||||
#ifdef XP_WIN
|
||||
if (StaticPrefs::dom_w3c_pointer_events_dispatch_by_pointer_messages()) {
|
||||
// WM_POINTER does not support drag and drop, see bug 1692277
|
||||
|
||||
@@ -270,16 +270,14 @@ class PointerEventHandler final {
|
||||
const WidgetPointerEvent& aSourceEvent);
|
||||
|
||||
static bool ShouldGeneratePointerEventFromMouse(WidgetGUIEvent* aEvent) {
|
||||
return aEvent->mMessage == eMouseRawUpdate ||
|
||||
aEvent->mMessage == eMouseDown || aEvent->mMessage == eMouseUp ||
|
||||
return aEvent->mMessage == eMouseDown || aEvent->mMessage == eMouseUp ||
|
||||
(aEvent->mMessage == eMouseMove &&
|
||||
aEvent->AsMouseEvent()->IsReal()) ||
|
||||
aEvent->mMessage == eMouseExitFromWidget;
|
||||
}
|
||||
|
||||
static bool ShouldGeneratePointerEventFromTouch(WidgetGUIEvent* aEvent) {
|
||||
return aEvent->mMessage == eTouchRawUpdate ||
|
||||
aEvent->mMessage == eTouchStart || aEvent->mMessage == eTouchMove ||
|
||||
return aEvent->mMessage == eTouchStart || aEvent->mMessage == eTouchMove ||
|
||||
aEvent->mMessage == eTouchEnd || aEvent->mMessage == eTouchCancel ||
|
||||
aEvent->mMessage == eTouchPointerCancel;
|
||||
}
|
||||
@@ -292,18 +290,11 @@ class PointerEventHandler final {
|
||||
|
||||
static bool IsDragAndDropEnabled(WidgetMouseEvent& aEvent);
|
||||
|
||||
private:
|
||||
// Get proper pointer event message for a mouse or touch event.
|
||||
[[nodiscard]] static EventMessage ToPointerEventMessage(
|
||||
static EventMessage ToPointerEventMessage(
|
||||
const WidgetGUIEvent* aMouseOrTouchEvent);
|
||||
|
||||
/**
|
||||
* Return true if the window containing aDocument has had a
|
||||
* `pointerrawupdate` event listener.
|
||||
*/
|
||||
[[nodiscard]] static bool NeedToDispatchPointerRawUpdate(
|
||||
const dom::Document* aDocument);
|
||||
|
||||
private:
|
||||
// Set pointer capture of the specified pointer by the element.
|
||||
static void SetPointerCaptureById(uint32_t aPointerId,
|
||||
dom::Element* aElement);
|
||||
|
||||
@@ -100,20 +100,6 @@ skip-if = [
|
||||
|
||||
["test_pointermove_isPrimary_subsequent_pens.html"]
|
||||
|
||||
["test_pointerrawupdate_event_count.html"]
|
||||
scheme = "https"
|
||||
skip-if = ["os == 'android'"] # Bug 1312791
|
||||
|
||||
["test_pointerrawupdate_event_count_touch.html"]
|
||||
scheme = "https"
|
||||
skip-if = [
|
||||
"os == 'android'", # Bug 1312791
|
||||
"verify && os == 'win'", # Bug 1659744
|
||||
"win11_2009", # Bug 1781388
|
||||
"os == 'win' && os_version == '11.26100' && processor == 'x86_64' && opt", # Bug 1781388
|
||||
]
|
||||
support-files = ["!/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"]
|
||||
|
||||
["test_remove_frame_when_got_pointer_capture.html"]
|
||||
|
||||
["test_synthesized_touch.html"]
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Test for number of pointerrawupdate events</title>
|
||||
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="target0" style="width: 50px; height: 50px; background: green"></div>
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestCompleteLog();
|
||||
SimpleTest.waitForFocus(async () => {
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.event.pointer.rawupdate.enabled", true],
|
||||
["dom.events.coalesce.mousemove", true],
|
||||
["test.events.async.enabled", true],
|
||||
]});
|
||||
|
||||
const target0 = window.document.getElementById("target0");
|
||||
|
||||
// First for flushing pending events in the main process, we should synthesize
|
||||
// a simple click and wait for that.
|
||||
info("Waiting for a click for waiting for stable state...");
|
||||
await new Promise(resolve => {
|
||||
target0.addEventListener("click", resolve, {once: true});
|
||||
synthesizeMouseAtCenter(target0, {});
|
||||
});
|
||||
info("Got a click which must be synthesized by us!");
|
||||
|
||||
const utils = SpecialPowers.getDOMWindowUtils(window);
|
||||
utils.advanceTimeAndRefresh(0);
|
||||
await new Promise(resolve => SimpleTest.executeSoon(resolve));
|
||||
|
||||
function stringifyPointerEvent(event) {
|
||||
return `{ screenX: ${event.screenX}, screenY: ${
|
||||
event.screenY
|
||||
}, clientX: ${event.clientX}, clientY:${event.clientY}, buttons:${
|
||||
event.buttons
|
||||
} }`;
|
||||
}
|
||||
|
||||
const allEvents = [];
|
||||
const pointerRawUpdateEvents = [];
|
||||
function onPointerRawUpdate(event) {
|
||||
allEvents.push(event);
|
||||
pointerRawUpdateEvents.push(event);
|
||||
// Currently, we need to compute the coordinates of the coalesced events
|
||||
// while the host event is being dispatched. See bug 1960530.
|
||||
event.getCoalescedEvents();
|
||||
if (pointerRawUpdateEvents.length == 4) {
|
||||
utils.restoreNormalRefresh();
|
||||
}
|
||||
}
|
||||
target0.addEventListener("pointerrawupdate", onPointerRawUpdate);
|
||||
|
||||
const coalescedPointerMoveEvents = [];
|
||||
const waitForPointerMove = new Promise(function (resolve) {
|
||||
function onPointerMove(event) {
|
||||
allEvents.push(event);
|
||||
for (const coalescedEvent of event.getCoalescedEvents()) {
|
||||
coalescedPointerMoveEvents.push(coalescedEvent);
|
||||
}
|
||||
if (coalescedPointerMoveEvents.length == 4) {
|
||||
target0.removeEventListener("pointermove", onPointerMove);
|
||||
target0.removeEventListener("pointerrawupdate", onPointerRawUpdate);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
target0.addEventListener("pointermove", onPointerMove);
|
||||
});
|
||||
|
||||
info("Synthesizing mouse moves....");
|
||||
synthesizeMouse(target0, 5, 5, {type: "mousemove"});
|
||||
synthesizeMouse(target0, 10, 10, {type: "mousemove"});
|
||||
synthesizeMouse(target0, 15, 15, {type: "mousemove"});
|
||||
synthesizeMouse(target0, 20, 20, {type: "mousemove"});
|
||||
info("Waiting for 4 coalesced pointermove events...");
|
||||
await waitForPointerMove;
|
||||
|
||||
for (const event of allEvents) {
|
||||
info(`${event.type}: ${stringifyPointerEvent(event)}`);
|
||||
}
|
||||
|
||||
ok(!!pointerRawUpdateEvents.length, "At least one pointerrawupdate event should be fired");
|
||||
is(
|
||||
pointerRawUpdateEvents.length,
|
||||
coalescedPointerMoveEvents.length,
|
||||
`pointermove.getCoalescedEvents().length should be same as the number of preceding pointerrawupdate`
|
||||
);
|
||||
{
|
||||
let i = 0;
|
||||
for (const pointerRawUpdateEvent of pointerRawUpdateEvents) {
|
||||
const coalescedEvents = pointerRawUpdateEvent.getCoalescedEvents();
|
||||
is(
|
||||
coalescedEvents.length,
|
||||
1,
|
||||
`pointerrawupdate(${i}): should have only one coalesced event`
|
||||
);
|
||||
is(
|
||||
`${coalescedEvents[0].type}: ${stringifyPointerEvent(coalescedEvents[0])}`,
|
||||
`${pointerRawUpdateEvent.type}: ${stringifyPointerEvent(pointerRawUpdateEvent)}`,
|
||||
`pointerrawupdate(${i++}): the coalesced event should have same values as the host event`
|
||||
);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < Math.min(pointerRawUpdateEvents.length, coalescedPointerMoveEvents.length); i++) {
|
||||
is(
|
||||
stringifyPointerEvent(pointerRawUpdateEvents[i]),
|
||||
stringifyPointerEvent(coalescedPointerMoveEvents[i]),
|
||||
`pointerrawupdate(${i++}): should have same values as coalesced pointermove events`
|
||||
);
|
||||
}
|
||||
|
||||
info("Waiting for a click for waiting for stable state after the test...");
|
||||
await new Promise(resolve => {
|
||||
target0.addEventListener("click", resolve, {once: true});
|
||||
synthesizeMouseAtCenter(target0, {});
|
||||
});
|
||||
info("Got a click after the test!");
|
||||
utils.restoreNormalRefresh();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,125 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Test for number of pointerrawupdate events of touch</title>
|
||||
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="/tests/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="target0" style="margin: 50px; width: 50px; height: 50px; background: green"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestCompleteLog();
|
||||
|
||||
if (!window.opener) {
|
||||
// the utils function in apz can't not be used in remote iframe, so run the
|
||||
// test in a new tab.
|
||||
info("run tests in a new tab");
|
||||
window.open("test_pointerrawupdate_event_count_touch.html");
|
||||
} else {
|
||||
function runTests() {
|
||||
const target0 = window.document.getElementById("target0");
|
||||
const utils = SpecialPowers.getDOMWindowUtils(window);
|
||||
utils.advanceTimeAndRefresh(0);
|
||||
const allEvents = [];
|
||||
const pointerRawUpdateEvents = [];
|
||||
const coalescedPointerMoveEvents = [];
|
||||
|
||||
function stringifyPointerEvent(event) {
|
||||
return `{ screenX: ${event.screenX}, screenY: ${
|
||||
event.screenY
|
||||
}, clientX: ${event.clientX}, clientY:${event.clientY}, buttons:${
|
||||
event.buttons
|
||||
} }`;
|
||||
}
|
||||
|
||||
SimpleTest.executeSoon(async () => {
|
||||
function onPointerRawUpdate(event) {
|
||||
allEvents.push(event);
|
||||
pointerRawUpdateEvents.push(event);
|
||||
// Currently, we need to compute the coordinates of the coalesced events
|
||||
// while the host event is being dispatched. See bug 1960530.
|
||||
event.getCoalescedEvents();
|
||||
}
|
||||
target0.addEventListener("pointerrawupdate", onPointerRawUpdate);
|
||||
const waitForPointerMove = new Promise(resolve => {
|
||||
function onPointerMove(event) {
|
||||
allEvents.push(event);
|
||||
for (const coalescedEvent of event.getCoalescedEvents()) {
|
||||
coalescedPointerMoveEvents.push(coalescedEvent);
|
||||
}
|
||||
if (pointerRawUpdateEvents.length > 1) {
|
||||
target0.removeEventListener("pointermove", onPointerMove);
|
||||
target0.removeEventListener("pointerrawupdate", onPointerRawUpdate);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
target0.addEventListener("pointermove", onPointerMove);
|
||||
});
|
||||
|
||||
target0.addEventListener("pointerup", async event => {
|
||||
utils.restoreNormalRefresh();
|
||||
await waitForPointerMove;
|
||||
for (const event of allEvents) {
|
||||
info(`${event.type}: ${stringifyPointerEvent(event)}`);
|
||||
}
|
||||
opener.ok(!!pointerRawUpdateEvents.length, "At least one pointerrawupdate event should be fired");
|
||||
opener.is(
|
||||
pointerRawUpdateEvents.length,
|
||||
coalescedPointerMoveEvents.length,
|
||||
`pointermove.getCoalescedEvents().length should be same as the number of preceding pointerrawupdate`
|
||||
);
|
||||
{
|
||||
let i = 0;
|
||||
for (const pointerRawUpdateEvent of pointerRawUpdateEvents) {
|
||||
const coalescedEvents = pointerRawUpdateEvent.getCoalescedEvents();
|
||||
opener.is(
|
||||
coalescedEvents.length,
|
||||
1,
|
||||
`pointerrawupdate(${i}): should have only one coalesced event`
|
||||
);
|
||||
opener.is(
|
||||
`${coalescedEvents[0].type}: ${stringifyPointerEvent(coalescedEvents[0])}`,
|
||||
`${pointerRawUpdateEvent.type}: ${stringifyPointerEvent(pointerRawUpdateEvent)}`,
|
||||
`pointerrawupdate(${i++}): the coalesced event should have same values as the host event`
|
||||
);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < Math.min(pointerRawUpdateEvents.length, coalescedPointerMoveEvents.length); i++) {
|
||||
opener.is(
|
||||
stringifyPointerEvent(pointerRawUpdateEvents[i]),
|
||||
stringifyPointerEvent(coalescedPointerMoveEvents[i]),
|
||||
`pointerrawupdate(${i++}): should have same values as coalesced pointermove events`
|
||||
);
|
||||
}
|
||||
opener.SimpleTest.finish();
|
||||
window.close();
|
||||
}, { once: true });
|
||||
|
||||
let positions = [];
|
||||
for (let i = 10; i <= 40; i+=5) {
|
||||
positions.push([{ x: i, y: i }]);
|
||||
}
|
||||
|
||||
await synthesizeNativeTouchSequences(target0, positions);
|
||||
});
|
||||
}
|
||||
|
||||
SimpleTest.waitForFocus(() => {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.event.pointer.rawupdate.enabled", true],
|
||||
["dom.events.coalesce.touchmove", true],
|
||||
["dom.events.compress.touchmove", false],
|
||||
]}, runTests);
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4895,16 +4895,13 @@ void HTMLMediaElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
||||
// element, allowing media control exclusive consumption on these events,
|
||||
// and preventing the content from handling them.
|
||||
switch (aVisitor.mEvent->mMessage) {
|
||||
case eTouchRawUpdate:
|
||||
MOZ_FALLTHROUGH_ASSERT(
|
||||
"eTouchRawUpdate event shouldn't be dispatched into the DOM");
|
||||
case ePointerDown:
|
||||
case ePointerUp:
|
||||
case eTouchEnd:
|
||||
// Always prevent touchmove captured in video element from being handled by
|
||||
// content, since we always do that for touchstart.
|
||||
case eTouchMove:
|
||||
case eTouchEnd:
|
||||
case eTouchStart:
|
||||
case ePointerDown:
|
||||
case ePointerUp:
|
||||
case ePointerClick:
|
||||
case eMouseDoubleClick:
|
||||
case eMouseDown:
|
||||
@@ -4912,13 +4909,9 @@ void HTMLMediaElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
||||
aVisitor.mCanHandle = false;
|
||||
return;
|
||||
|
||||
// The *move events however are only consumed when the range input is being
|
||||
// The *move events however are only comsumed when the range input is being
|
||||
// dragged.
|
||||
case eMouseRawUpdate:
|
||||
MOZ_FALLTHROUGH_ASSERT(
|
||||
"eMouseRawUpdate event shouldn't be dispatched into the DOM");
|
||||
case ePointerMove:
|
||||
case ePointerRawUpdate:
|
||||
case eMouseMove: {
|
||||
nsINode* node =
|
||||
nsINode::FromEventTargetOrNull(aVisitor.mEvent->mOriginalTarget);
|
||||
|
||||
@@ -1489,7 +1489,7 @@ void BrowserChild::ProcessPendingCoalescedMouseDataAndDispatchEvents() {
|
||||
// mToBeDispatchedMouseData while dispatching an event.
|
||||
|
||||
// We may have some pending coalesced data while dispatch an event and reentry
|
||||
// the event loop. In that case we don't have chance to consume the remaining
|
||||
// the event loop. In that case we don't have chance to consume the remainding
|
||||
// pending data until we get new mouse events. Get some helps from
|
||||
// mCoalescedMouseEventFlusher to trigger it.
|
||||
mCoalescedMouseEventFlusher->StartObserver();
|
||||
@@ -1500,13 +1500,6 @@ void BrowserChild::ProcessPendingCoalescedMouseDataAndDispatchEvents() {
|
||||
|
||||
UniquePtr<WidgetMouseEvent> event = data->TakeCoalescedEvent();
|
||||
if (event) {
|
||||
// When the real mouse event receivers put the received event into the
|
||||
// queue, they should dispatch eMouseRawUpdate event immediately (if and
|
||||
// only if it's required). Therefore, unless the event is the last one
|
||||
// of the queue, the pending events should've been marked as "Do not
|
||||
// convert to "pointerrawupdate".
|
||||
MOZ_ASSERT_IF(mToBeDispatchedMouseData.GetSize() > 0,
|
||||
!event->convertToPointerRawUpdate);
|
||||
// Dispatch the pending events. Using HandleRealMouseButtonEvent
|
||||
// to bypass the coalesce handling in RecvRealMouseMoveEvent. Can't use
|
||||
// RecvRealMouseButtonEvent because we may also put some mouse events
|
||||
@@ -1563,20 +1556,11 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealMouseMoveEvent(
|
||||
CoalescedMouseData* data =
|
||||
mCoalescedMouseData.GetOrInsertNew(aEvent.pointerId);
|
||||
MOZ_ASSERT(data);
|
||||
if (data->CanCoalesce(aEvent, aGuid, aInputBlockId,
|
||||
mCoalescedMouseEventFlusher->GetRefreshDriver())) {
|
||||
// We don't need to dispatch aEvent immediately. However, we need to
|
||||
// dispatch eMouseRawUpdate immediately if there is a `pointerrawupdate`
|
||||
// event listener. Therefore, the cloned event in the queue shouldn't
|
||||
// cause eMouseRawUpdate later when it'll be dispatched.
|
||||
WidgetMouseEvent pendingMouseMoveEvent(aEvent);
|
||||
pendingMouseMoveEvent.convertToPointerRawUpdate = false;
|
||||
data->Coalesce(pendingMouseMoveEvent, aGuid, aInputBlockId);
|
||||
if (data->CanCoalesce(aEvent, aGuid, aInputBlockId)) {
|
||||
data->Coalesce(aEvent, aGuid, aInputBlockId);
|
||||
mCoalescedMouseEventFlusher->StartObserver();
|
||||
HandleMouseRawUpdateEvent(pendingMouseMoveEvent, aGuid, aInputBlockId);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
// Can't coalesce current mousemove event. Put the coalesced mousemove data
|
||||
// with the same pointer id to mToBeDispatchedMouseData, coalesce the
|
||||
// current one, and process all pending data in mToBeDispatchedMouseData.
|
||||
@@ -1591,50 +1575,17 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealMouseMoveEvent(
|
||||
mCoalescedMouseData
|
||||
.InsertOrUpdate(aEvent.pointerId, MakeUnique<CoalescedMouseData>())
|
||||
.get();
|
||||
// We don't want to dispatch aEvent immediately. However, we need to
|
||||
// dispatch eMouseRawUpdate immediately if there is a `pointerrawupdate`
|
||||
// event listener. Therefore, the cloned event in the queue shouldn't
|
||||
// cause eMouseRawUpdate later when it'll be dispatched.
|
||||
WidgetMouseEvent pendingMouseMoveEvent(aEvent);
|
||||
pendingMouseMoveEvent.convertToPointerRawUpdate = false;
|
||||
newData->Coalesce(pendingMouseMoveEvent, aGuid, aInputBlockId);
|
||||
newData->Coalesce(aEvent, aGuid, aInputBlockId);
|
||||
|
||||
// Dispatch all pending mouse events which does NOT include aEvent.
|
||||
// Dispatch all pending mouse events.
|
||||
ProcessPendingCoalescedMouseDataAndDispatchEvents();
|
||||
|
||||
mCoalescedMouseEventFlusher->StartObserver();
|
||||
// Finally, dispatch eMouseRawUpdate for aEvent right now.
|
||||
HandleMouseRawUpdateEvent(pendingMouseMoveEvent, aGuid, aInputBlockId);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (!RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId)) {
|
||||
} else if (!RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void BrowserChild::HandleMouseRawUpdateEvent(
|
||||
const WidgetMouseEvent& aPendingMouseEvent,
|
||||
const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId) {
|
||||
// If there is no window containing pointerrawupdate event listeners or the
|
||||
// event is a synthesized mousemove, we don't need to dispatch eMouseRawUpdate
|
||||
// event.
|
||||
if (!mPointerRawUpdateWindowCount || aPendingMouseEvent.IsSynthesized()) {
|
||||
return;
|
||||
}
|
||||
WidgetMouseEvent mouseRawUpdateEvent(aPendingMouseEvent);
|
||||
mouseRawUpdateEvent.mMessage = eMouseRawUpdate;
|
||||
mouseRawUpdateEvent.mCoalescedWidgetEvents = nullptr;
|
||||
mouseRawUpdateEvent.convertToPointer = true;
|
||||
// Nobody checks `convertToPointerRawUpdate` of eMouseRawUpdate event.
|
||||
// However, the name indicates that it would cause ePointerRawUpdate.
|
||||
// For avoiding to make the developers who watch the value with the debugger
|
||||
// confused, here sets it to `true`.
|
||||
mouseRawUpdateEvent.convertToPointerRawUpdate = true;
|
||||
HandleRealMouseButtonEvent(mouseRawUpdateEvent, aGuid, aInputBlockId);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserChild::RecvRealMouseMoveEventForTests(
|
||||
const WidgetMouseEvent& aEvent, const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) {
|
||||
@@ -1686,16 +1637,9 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealMouseButtonEvent(
|
||||
UniquePtr<CoalescedMouseData> dispatchData =
|
||||
MakeUnique<CoalescedMouseData>();
|
||||
|
||||
// We'll dispatch aEvent immediately via
|
||||
// ProcessPendingCoalescedMouseDataAndDispatchEvents().
|
||||
// Therefore, PresShell should convert it to eMouseRawUpdate when it starts
|
||||
// handling aEvent if and only if there is a `pointerrawupdate` event
|
||||
// listener. Therefore, let's assert the allowing flag to convert it to
|
||||
// eMouseRawUpdate here.
|
||||
MOZ_ASSERT(aEvent.convertToPointerRawUpdate);
|
||||
dispatchData->Coalesce(aEvent, aGuid, aInputBlockId);
|
||||
|
||||
mToBeDispatchedMouseData.Push(dispatchData.release());
|
||||
|
||||
ProcessPendingCoalescedMouseDataAndDispatchEvents();
|
||||
return IPC_OK();
|
||||
}
|
||||
@@ -1886,7 +1830,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealTouchEvent(
|
||||
ProcessPendingCoalescedTouchData();
|
||||
}
|
||||
|
||||
if (aEvent.mMessage != eTouchMove && aEvent.mMessage != eTouchRawUpdate) {
|
||||
if (aEvent.mMessage != eTouchMove) {
|
||||
sConsecutiveTouchMoveCount = 0;
|
||||
}
|
||||
}
|
||||
@@ -1949,88 +1893,33 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealTouchMoveEvent(
|
||||
++sConsecutiveTouchMoveCount;
|
||||
if (mCoalescedTouchMoveEventFlusher) {
|
||||
MOZ_ASSERT(aEvent.mMessage == eTouchMove);
|
||||
// NOTE: While dispatching eTouchMove or eTouchRawUpdate,
|
||||
// sConsecutiveTouchMoveCount may be changed by the event loop spun,
|
||||
// e.g., an event listener uses sync XHR or calling window.alert().
|
||||
const auto PostponeDispatchingTouchMove = [&]() {
|
||||
return sConsecutiveTouchMoveCount > 1;
|
||||
};
|
||||
if (mCoalescedTouchData.IsEmpty() ||
|
||||
mCoalescedTouchData.CanCoalesce(aEvent, aGuid, aInputBlockId,
|
||||
aApzResponse)) {
|
||||
if (PostponeDispatchingTouchMove()) {
|
||||
WidgetTouchEvent pendingTouchMoveEvent(
|
||||
aEvent, WidgetTouchEvent::CloneTouches::Yes);
|
||||
// We don't dispatch aEvent immediately here. However, we need to
|
||||
// dispatch eTouchRawUpdate immediately if and only if there is a
|
||||
// `pointerrawupdate` event listener. Therefore, the cloned event in
|
||||
// the queue and it shouldn't cause eTouchRawUpdate again.
|
||||
pendingTouchMoveEvent.SetConvertToPointerRawUpdate(false);
|
||||
mCoalescedTouchData.Coalesce(pendingTouchMoveEvent, aGuid,
|
||||
aInputBlockId, aApzResponse);
|
||||
MOZ_ASSERT(PostponeDispatchingTouchMove());
|
||||
mCoalescedTouchMoveEventFlusher->StartObserver();
|
||||
// Let's notify the web app of `pointerrawupdate` immediately if and
|
||||
// only if they listen to it.
|
||||
HandleTouchRawUpdateEvent(pendingTouchMoveEvent, aGuid, aInputBlockId,
|
||||
aApzResponse);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
// We'll dispatch aEvent via ProcessPendingCoalescedTouchData() below.
|
||||
// Therefore, the touches should cause eTouchRawUpdate event.
|
||||
MOZ_ASSERT(aEvent.CanConvertToPointerRawUpdate());
|
||||
mCoalescedTouchData.Coalesce(aEvent, aGuid, aInputBlockId,
|
||||
aApzResponse);
|
||||
MOZ_ASSERT(!PostponeDispatchingTouchMove());
|
||||
} else {
|
||||
UniquePtr<WidgetTouchEvent> touchMoveEvent =
|
||||
mCoalescedTouchData.TakeCoalescedEvent();
|
||||
MOZ_ASSERT(touchMoveEvent->mMessage == eTouchMove);
|
||||
|
||||
// Before dispatching touchMoveEvent, we need to put aEvent into the
|
||||
// queue for keeping the event order even if an event listener spins the
|
||||
// event loop and we'll receive another touch event. So, aEvent may be
|
||||
// dispatched while we're dispatching touchMoveEvent. Therefore, we need
|
||||
// to make it convertible to eTouchRawUpdate.
|
||||
MOZ_ASSERT(aEvent.CanConvertToPointerRawUpdate());
|
||||
mCoalescedTouchData.Coalesce(aEvent, aGuid, aInputBlockId,
|
||||
aApzResponse);
|
||||
MOZ_ASSERT(!PostponeDispatchingTouchMove());
|
||||
|
||||
// touchMoveEvent was stored by mCoalescedTouchData before receiving
|
||||
// aEvent. Therefore, the receiver should've already dispatched
|
||||
// eTouchRawUpdate for dispatching `pointerrawupdate` and let web apps
|
||||
// know the update immediately (with sacrificing the performance).
|
||||
// Therefore, we don't need to dispatch eTouchRawUpdate here before
|
||||
// dispatching the touchMoveEvent.
|
||||
MOZ_ASSERT(!touchMoveEvent->CanConvertToPointerRawUpdate());
|
||||
const uint32_t generation = mCoalescedTouchData.Generation();
|
||||
if (!RecvRealTouchEvent(*touchMoveEvent,
|
||||
mCoalescedTouchData.GetScrollableLayerGuid(),
|
||||
mCoalescedTouchData.GetInputBlockId(),
|
||||
mCoalescedTouchData.GetApzResponse())) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
// RecvRealTouchEvent() may have caused spinning the event loop and
|
||||
// changed sConsecutiveTouchMoveCount. So, we need to check it now.
|
||||
if (PostponeDispatchingTouchMove()) {
|
||||
mCoalescedTouchMoveEventFlusher->StartObserver();
|
||||
if (generation == mCoalescedTouchData.Generation()) {
|
||||
// Let's notify the web app of `pointerrawupdate` immediately if and
|
||||
// only if they listen to it. Additionally, we don't want to notify
|
||||
// eTouchRawUpdate when ProcessPendingCoalescedTouchData() is called
|
||||
// later.
|
||||
mCoalescedTouchData.NotifyTouchRawUpdateOfHandled(aEvent);
|
||||
HandleTouchRawUpdateEvent(aEvent, aGuid, aInputBlockId,
|
||||
aApzResponse);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
}
|
||||
// Flush the pending coalesced touch in order to avoid the first
|
||||
// touchmove be overridden by the second one, this contains aEvent.
|
||||
ProcessPendingCoalescedTouchData();
|
||||
|
||||
if (sConsecutiveTouchMoveCount > 1) {
|
||||
mCoalescedTouchMoveEventFlusher->StartObserver();
|
||||
} else {
|
||||
// Flush the pending coalesced touch in order to avoid the first
|
||||
// touchmove be overridden by the second one.
|
||||
ProcessPendingCoalescedTouchData();
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
}
|
||||
@@ -2041,30 +1930,6 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealTouchMoveEvent(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void BrowserChild::HandleTouchRawUpdateEvent(
|
||||
const WidgetTouchEvent& aPendingTouchEvent,
|
||||
const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse) {
|
||||
if (!mPointerRawUpdateWindowCount) {
|
||||
return; // There is no window containing pointerrawupdate event listeners
|
||||
}
|
||||
|
||||
WidgetTouchEvent touchRawUpdateEvent(aPendingTouchEvent,
|
||||
WidgetTouchEvent::CloneTouches::Yes);
|
||||
touchRawUpdateEvent.mMessage = eTouchRawUpdate;
|
||||
for (Touch* const touch : touchRawUpdateEvent.mTouches) {
|
||||
touch->mMessage = eTouchRawUpdate;
|
||||
touch->mCoalescedWidgetEvents = nullptr;
|
||||
touch->convertToPointer = true;
|
||||
// Although nobody checks `convertToPointerRawUpdate` of eTouchRawUpdate.
|
||||
// However, the name indicates it would cause ePointerRawUpdate or not, so,
|
||||
// for avoiding to make developers confused when they watch the value with
|
||||
// the debugger, we should set this to `true`.
|
||||
touch->convertToPointerRawUpdate = true;
|
||||
}
|
||||
RecvRealTouchEvent(touchRawUpdateEvent, aGuid, aInputBlockId, aApzResponse);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserChild::RecvNormalPriorityRealTouchMoveEvent(
|
||||
const WidgetTouchEvent& aEvent, const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId, const nsEventStatus& aApzResponse) {
|
||||
@@ -4169,27 +4034,6 @@ void BrowserChild::SetDragSession(nsIDragSession* aSession) {
|
||||
mDragSession = aSession;
|
||||
}
|
||||
|
||||
LazyLogModule gPointerRawUpdateEventListenersLog(
|
||||
"PointerRawUpdateEventListeners");
|
||||
|
||||
void BrowserChild::OnPointerRawUpdateEventListenerAdded(
|
||||
const nsPIDOMWindowInner* aWindow) {
|
||||
mPointerRawUpdateWindowCount++;
|
||||
MOZ_LOG(gPointerRawUpdateEventListenersLog, LogLevel::Info,
|
||||
("Added for %p (total: %u)", aWindow, mPointerRawUpdateWindowCount));
|
||||
}
|
||||
|
||||
void BrowserChild::OnPointerRawUpdateEventListenerRemoved(
|
||||
const nsPIDOMWindowInner* aWindow) {
|
||||
MOZ_ASSERT(mPointerRawUpdateWindowCount);
|
||||
if (MOZ_LIKELY(mPointerRawUpdateWindowCount)) {
|
||||
mPointerRawUpdateWindowCount--;
|
||||
}
|
||||
MOZ_LOG(gPointerRawUpdateEventListenersLog, LogLevel::Info,
|
||||
("Removed for %p (remaining: %u)", aWindow,
|
||||
mPointerRawUpdateWindowCount));
|
||||
}
|
||||
|
||||
BrowserChildMessageManager::BrowserChildMessageManager(
|
||||
BrowserChild* aBrowserChild)
|
||||
: ContentFrameMessageManager(new nsFrameMessageManager(aBrowserChild)),
|
||||
|
||||
@@ -46,7 +46,6 @@ class nsIHttpChannel;
|
||||
class nsIRequest;
|
||||
class nsISerialEventTarget;
|
||||
class nsIWebProgress;
|
||||
class nsPIDOMWindowInner;
|
||||
class nsWebBrowser;
|
||||
class nsDocShellLoadState;
|
||||
|
||||
@@ -641,36 +640,14 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
||||
// may reentry the event loop and access to the same hashtable. It's
|
||||
// called when dispatching some mouse events other than mousemove.
|
||||
void FlushAllCoalescedMouseData();
|
||||
|
||||
void ProcessPendingCoalescedMouseDataAndDispatchEvents();
|
||||
|
||||
void ProcessPendingCoalescedTouchData();
|
||||
|
||||
/**
|
||||
* Dispatch an eMouseRawUpdate event for dispatching ePointerRawUpdate event
|
||||
* into the DOM immediately when aPendingEvent will be dispatched later.
|
||||
* This does nothing if there is no window which has at least one
|
||||
* `pointerrawupdate` event listener.
|
||||
*/
|
||||
void HandleMouseRawUpdateEvent(const WidgetMouseEvent& aPendingMouseEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId);
|
||||
|
||||
void HandleRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId);
|
||||
|
||||
/**
|
||||
* Dispatch an eTouchRawUpdate event for dispatching ePointerRawUpdate event
|
||||
* into the DOM immediately when aPendingEvent will be dispatched later.
|
||||
* This does nothing if there is no window which has at least one
|
||||
* `pointerrawupdate` event listener.
|
||||
*/
|
||||
void HandleTouchRawUpdateEvent(const WidgetTouchEvent& aPendingTouchEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse);
|
||||
|
||||
void SetCancelContentJSEpoch(int32_t aEpoch) {
|
||||
mCancelContentJSEpoch = aEpoch;
|
||||
}
|
||||
@@ -735,13 +712,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
||||
mozilla::ipc::IPCResult RecvDispatchToDropTargetAndResumeEndDragSession(
|
||||
bool aShouldDrop);
|
||||
|
||||
void OnPointerRawUpdateEventListenerAdded(const nsPIDOMWindowInner* aWindow);
|
||||
void OnPointerRawUpdateEventListenerRemoved(
|
||||
const nsPIDOMWindowInner* aWindow);
|
||||
[[nodiscard]] bool HasPointerRawUpdateEventListeners() const {
|
||||
return !!mPointerRawUpdateWindowCount;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~BrowserChild();
|
||||
|
||||
@@ -853,8 +823,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
||||
Maybe<CodeNameIndex> mPreviousConsumedKeyDownCode;
|
||||
uint32_t mChromeFlags;
|
||||
uint32_t mMaxTouchPoints;
|
||||
// The number of windows which may have ePointerRawUpdate event listener.
|
||||
uint32_t mPointerRawUpdateWindowCount = 0;
|
||||
layers::LayersId mLayersId;
|
||||
CSSRect mUnscaledOuterRect;
|
||||
Maybe<bool> mLayersConnected;
|
||||
|
||||
@@ -24,21 +24,12 @@ class CoalescedInputData {
|
||||
|
||||
UniquePtr<InputEventType> mCoalescedInputEvent;
|
||||
ScrollableLayerGuid mGuid;
|
||||
uint64_t mInputBlockId = 0;
|
||||
uint32_t mGeneration = 0;
|
||||
|
||||
void AdvanceGeneration() {
|
||||
if (!IsEmpty()) {
|
||||
mGeneration++;
|
||||
}
|
||||
}
|
||||
uint64_t mInputBlockId;
|
||||
|
||||
public:
|
||||
CoalescedInputData() = default;
|
||||
CoalescedInputData() : mInputBlockId(0) {}
|
||||
|
||||
void RetrieveDataFrom(CoalescedInputData& aSource) {
|
||||
aSource.AdvanceGeneration();
|
||||
AdvanceGeneration();
|
||||
mCoalescedInputEvent = std::move(aSource.mCoalescedInputEvent);
|
||||
mGuid = aSource.mGuid;
|
||||
mInputBlockId = aSource.mInputBlockId;
|
||||
@@ -51,23 +42,12 @@ class CoalescedInputData {
|
||||
const uint64_t& aInputBlockId);
|
||||
|
||||
UniquePtr<InputEventType> TakeCoalescedEvent() {
|
||||
AdvanceGeneration();
|
||||
return std::move(mCoalescedInputEvent);
|
||||
}
|
||||
|
||||
ScrollableLayerGuid GetScrollableLayerGuid() { return mGuid; }
|
||||
|
||||
uint64_t GetInputBlockId() { return mInputBlockId; }
|
||||
|
||||
/**
|
||||
* The generation number of the latest state stored by the instance.
|
||||
* It'll be incremented when the coalesced event data is retrieved or taken.
|
||||
* So, this is useful to avoid handling same coalesced events twice when
|
||||
* a nested event loop may handle this.
|
||||
* NOTE: You should compare the value only with `==` or `!=`. Do not use
|
||||
* `<` nor `>` because the value may circulate to 0 from UINT32_MAX.
|
||||
*/
|
||||
[[nodiscard]] uint32_t Generation() const { return mGeneration; }
|
||||
};
|
||||
|
||||
class CoalescedInputFlusher : public nsARefreshObserver {
|
||||
@@ -81,17 +61,12 @@ class CoalescedInputFlusher : public nsARefreshObserver {
|
||||
void StartObserver();
|
||||
void RemoveObserver();
|
||||
|
||||
/**
|
||||
* Return a refresh driver which is proper one for BrowserChild.
|
||||
* Note that this is not a getter of mRefreshDriver.
|
||||
*/
|
||||
[[nodiscard]] nsRefreshDriver* GetRefreshDriver();
|
||||
|
||||
protected:
|
||||
virtual ~CoalescedInputFlusher();
|
||||
|
||||
nsRefreshDriver* GetRefreshDriver();
|
||||
|
||||
BrowserChild* mBrowserChild;
|
||||
// A refresh driver which this instance waits for the next refresh of.
|
||||
RefPtr<nsRefreshDriver> mRefreshDriver;
|
||||
};
|
||||
} // namespace mozilla::dom
|
||||
|
||||
@@ -58,29 +58,17 @@ void CoalescedMouseData::Coalesce(const WidgetMouseEvent& aEvent,
|
||||
|
||||
bool CoalescedMouseData::CanCoalesce(const WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsRefreshDriver* aRefreshDriver) {
|
||||
const uint64_t& aInputBlockId) {
|
||||
MOZ_ASSERT(aEvent.mMessage == eMouseMove);
|
||||
if (!mCoalescedInputEvent) {
|
||||
return true;
|
||||
}
|
||||
if (mCoalescedInputEvent->mFlags.mIsSynthesizedForTests !=
|
||||
aEvent.mFlags.mIsSynthesizedForTests ||
|
||||
mCoalescedInputEvent->mModifiers != aEvent.mModifiers ||
|
||||
mCoalescedInputEvent->mInputSource != aEvent.mInputSource ||
|
||||
mCoalescedInputEvent->pointerId != aEvent.pointerId ||
|
||||
mCoalescedInputEvent->mButton != aEvent.mButton ||
|
||||
mCoalescedInputEvent->mButtons != aEvent.mButtons || mGuid != aGuid ||
|
||||
mInputBlockId != aInputBlockId) {
|
||||
return false;
|
||||
}
|
||||
// Basically, tests do not want to coalesces the consecutive mouse events.
|
||||
// However, if the test calls nsIDOMWindowUtils::AdvanceTimeAndRefresh(0),
|
||||
// they must try to check coalesced mouse move events.
|
||||
if (!aEvent.mFlags.mIsSynthesizedForTests) {
|
||||
return true;
|
||||
}
|
||||
return aRefreshDriver && aRefreshDriver->IsTestControllingRefreshesEnabled();
|
||||
return !mCoalescedInputEvent ||
|
||||
(!mCoalescedInputEvent->mFlags.mIsSynthesizedForTests &&
|
||||
!aEvent.mFlags.mIsSynthesizedForTests &&
|
||||
mCoalescedInputEvent->mModifiers == aEvent.mModifiers &&
|
||||
mCoalescedInputEvent->mInputSource == aEvent.mInputSource &&
|
||||
mCoalescedInputEvent->pointerId == aEvent.pointerId &&
|
||||
mCoalescedInputEvent->mButton == aEvent.mButton &&
|
||||
mCoalescedInputEvent->mButtons == aEvent.mButtons && mGuid == aGuid &&
|
||||
mInputBlockId == aInputBlockId);
|
||||
}
|
||||
|
||||
CoalescedMouseMoveFlusher::CoalescedMouseMoveFlusher(
|
||||
|
||||
@@ -27,8 +27,7 @@ class CoalescedMouseData final : public CoalescedInputData<WidgetMouseEvent> {
|
||||
|
||||
bool CanCoalesce(const WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsRefreshDriver* aRefreshDriver);
|
||||
const uint64_t& aInputBlockId);
|
||||
};
|
||||
|
||||
class CoalescedMouseMoveFlusher final : public CoalescedInputFlusher {
|
||||
|
||||
@@ -28,7 +28,6 @@ void CoalescedTouchData::CreateCoalescedTouchEvent(
|
||||
PointerEventHandler::InitPointerEventFromTouch(*event, aEvent, *touch);
|
||||
event->mFlags.mBubbles = false;
|
||||
event->mFlags.mCancelable = false;
|
||||
event->convertToPointerRawUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,9 +47,10 @@ void CoalescedTouchData::Coalesce(const WidgetTouchEvent& aEvent,
|
||||
MOZ_ASSERT(mCoalescedInputEvent->mModifiers == aEvent.mModifiers);
|
||||
MOZ_ASSERT(mCoalescedInputEvent->mInputSource == aEvent.mInputSource);
|
||||
|
||||
for (const RefPtr<Touch>& touch : aEvent.mTouches) {
|
||||
for (size_t i = 0; i < aEvent.mTouches.Length(); i++) {
|
||||
const RefPtr<Touch>& touch = aEvent.mTouches[i];
|
||||
// Get the same touch in the original event
|
||||
const RefPtr<Touch> sameTouch = GetTouch(touch->Identifier());
|
||||
RefPtr<Touch> sameTouch = GetTouch(touch->Identifier());
|
||||
// The checks in CoalescedTouchData::CanCoalesce ensure it should never
|
||||
// be null.
|
||||
MOZ_ASSERT(sameTouch);
|
||||
@@ -58,7 +58,6 @@ void CoalescedTouchData::Coalesce(const WidgetTouchEvent& aEvent,
|
||||
MOZ_ASSERT(!sameTouch->mCoalescedWidgetEvents->mEvents.IsEmpty());
|
||||
if (!sameTouch->Equals(touch)) {
|
||||
sameTouch->SetSameAs(touch);
|
||||
sameTouch->convertToPointerRawUpdate = touch->convertToPointerRawUpdate;
|
||||
WidgetPointerEvent* event =
|
||||
sameTouch->mCoalescedWidgetEvents->mEvents.AppendElement(
|
||||
WidgetPointerEvent(aEvent.IsTrusted(), ePointerMove,
|
||||
@@ -73,18 +72,6 @@ void CoalescedTouchData::Coalesce(const WidgetTouchEvent& aEvent,
|
||||
}
|
||||
}
|
||||
|
||||
void CoalescedTouchData::NotifyTouchRawUpdateOfHandled(
|
||||
const WidgetTouchEvent& aEvent) {
|
||||
if (IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (const RefPtr<Touch>& touch : aEvent.mTouches) {
|
||||
if (const RefPtr<Touch> sameTouch = GetTouch(touch->Identifier())) {
|
||||
sameTouch->convertToPointerRawUpdate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CoalescedTouchData::CanCoalesce(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
|
||||
@@ -27,8 +27,6 @@ class CoalescedTouchData final : public CoalescedInputData<WidgetTouchEvent> {
|
||||
|
||||
nsEventStatus GetApzResponse() { return mApzResponse; }
|
||||
|
||||
void NotifyTouchRawUpdateOfHandled(const WidgetTouchEvent& aEvent);
|
||||
|
||||
private:
|
||||
Touch* GetTouch(int32_t aIdentifier);
|
||||
|
||||
|
||||
@@ -1857,8 +1857,6 @@ let interfaceNamesInGlobalScope = [
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "onpointerover", insecureContext: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "onpointerrawupdate" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "onpointerup", insecureContext: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "onpopstate", insecureContext: true },
|
||||
|
||||
@@ -116,8 +116,6 @@ interface mixin GlobalEventHandlers {
|
||||
attribute EventHandler onpointerover;
|
||||
attribute EventHandler onpointerenter;
|
||||
attribute EventHandler onpointerleave;
|
||||
[SecureContext, Pref="dom.event.pointer.rawupdate.enabled"]
|
||||
attribute EventHandler onpointerrawupdate;
|
||||
attribute EventHandler ongotpointercapture;
|
||||
attribute EventHandler onlostpointercapture;
|
||||
|
||||
|
||||
@@ -336,9 +336,6 @@ void APZEventState::ProcessTouchEvent(
|
||||
break;
|
||||
}
|
||||
|
||||
case eTouchRawUpdate:
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown touch event type");
|
||||
break;
|
||||
|
||||
@@ -7069,8 +7069,6 @@ void PresShell::RecordPointerLocation(WidgetGUIEvent* aEvent) {
|
||||
break;
|
||||
}
|
||||
case ePointerMove:
|
||||
case ePointerRawUpdate:
|
||||
case eMouseRawUpdate:
|
||||
if (!aEvent->AsMouseEvent()->IsReal()) {
|
||||
break;
|
||||
}
|
||||
@@ -7155,7 +7153,6 @@ PresShell* PresShell::GetShellForEventTarget(nsIFrame* aFrame,
|
||||
PresShell* PresShell::GetShellForTouchEvent(WidgetGUIEvent* aEvent) {
|
||||
switch (aEvent->mMessage) {
|
||||
case eTouchMove:
|
||||
case eTouchRawUpdate:
|
||||
case eTouchCancel:
|
||||
case eTouchEnd: {
|
||||
// get the correct shell to dispatch to
|
||||
@@ -7307,7 +7304,6 @@ nsresult PresShell::HandleEvent(nsIFrame* aFrameForPresShell,
|
||||
if (mPresContext) {
|
||||
switch (aGUIEvent->mMessage) {
|
||||
case eMouseMove:
|
||||
case eMouseRawUpdate:
|
||||
if (!aGUIEvent->AsMouseEvent()->IsReal()) {
|
||||
break;
|
||||
}
|
||||
@@ -7352,124 +7348,11 @@ nsresult PresShell::HandleEvent(nsIFrame* aFrameForPresShell,
|
||||
}
|
||||
}
|
||||
|
||||
// If the event may cause ePointerMove, we need to dispatch ePointerRawUpdate
|
||||
// before that if and only if there are some `pointerrawupdate` event
|
||||
// listeners. Note that if a `pointerrawupdate` event listener destroys its
|
||||
// document/window, we need to dispatch the following pointer event (e.g.,
|
||||
// ePointerMove) in the parent document/window with the parent PresShell.
|
||||
// Therefore, we need to consider the target PresShell for each event
|
||||
// (ePointerRawUpdate and the following pointer event) in
|
||||
// EventHandler::HandleEvent(). Thus, we need to dispatch the internal event
|
||||
// for ePointerRawUpdate before calling EventHandler::HandleEvent() below.
|
||||
if (!aDontRetargetEvents &&
|
||||
StaticPrefs::dom_event_pointer_rawupdate_enabled()) {
|
||||
nsresult rv = EnsurePrecedingPointerRawUpdate(
|
||||
weakFrameForPresShell, *aGUIEvent, aDontRetargetEvents);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (!CanHandleUserInputEvents(aGUIEvent)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
EventHandler eventHandler(*this);
|
||||
return eventHandler.HandleEvent(weakFrameForPresShell, aGUIEvent,
|
||||
aDontRetargetEvents, aEventStatus);
|
||||
}
|
||||
|
||||
nsresult PresShell::EnsurePrecedingPointerRawUpdate(
|
||||
AutoWeakFrame& aWeakFrameForPresShell, const WidgetGUIEvent& aSourceEvent,
|
||||
bool aDontRetargetEvents) {
|
||||
MOZ_ASSERT(StaticPrefs::dom_event_pointer_rawupdate_enabled());
|
||||
if (PointerEventHandler::ToPointerEventMessage(&aSourceEvent) !=
|
||||
ePointerMove) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We should not dispatch ePointerRawUpdate directly because dispatching
|
||||
// it requires some steps which are defined by "fire a pointer event" section
|
||||
// in the spec. https://w3c.github.io/pointerevents/#dfn-fire-a-pointer-event
|
||||
// We handle the steps when we call DispatchPrecedingPointerEvent().
|
||||
// Therefore, this method dispatches eMouseRawUpdate or eTouchRawUpdate event
|
||||
// if the event should follow a ePointerRawUpdate. Then,
|
||||
// HandleEventUsingCoordinates() will stop handling the internal events after
|
||||
// calling DispatchPrecedingPointerEvent().
|
||||
|
||||
MOZ_ASSERT(aSourceEvent.mMessage != eMouseRawUpdate);
|
||||
MOZ_ASSERT(aSourceEvent.mMessage != eTouchRawUpdate);
|
||||
|
||||
// If no window in the browser child has `pointerrawupdate` event listener,
|
||||
// we should do nothing.
|
||||
if (auto* const browserChild = BrowserChild::GetFrom(this)) {
|
||||
if (!browserChild->HasPointerRawUpdateEventListeners()) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
static bool sDispatchingRawUpdateEventFromHere = false;
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
!sDispatchingRawUpdateEventFromHere,
|
||||
"Dispatching ePointerRawUpdate should not be done recursively");
|
||||
AutoRestore<bool> restoreDispathingFlag(sDispatchingRawUpdateEventFromHere);
|
||||
sDispatchingRawUpdateEventFromHere = true;
|
||||
#endif // #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
|
||||
if (const WidgetMouseEvent* const mouseEvent = aSourceEvent.AsMouseEvent()) {
|
||||
// If `convertToPointer` is `false`, it means that we've already handled the
|
||||
// event to dispatch a preceding pointer event. Therefore, its preceding
|
||||
// event should've already been handled.
|
||||
// If `convertToPointerRawUpdate` is `false`, it means that the event was in
|
||||
// the queue in BrowserChild and BrowserChild has already dispatched
|
||||
// `eMouseRawUpdate`. Therefore, we don't need to dispatch it again here.
|
||||
if (mouseEvent->IsSynthesized() || !mouseEvent->convertToPointer ||
|
||||
!mouseEvent->convertToPointerRawUpdate) {
|
||||
return NS_OK;
|
||||
}
|
||||
WidgetMouseEvent mouseRawUpdateEvent(*mouseEvent);
|
||||
mouseRawUpdateEvent.mMessage = eMouseRawUpdate;
|
||||
mouseRawUpdateEvent.mCoalescedWidgetEvents = nullptr;
|
||||
nsEventStatus rawUpdateStatus = nsEventStatus_eIgnore;
|
||||
EventHandler eventHandler(*this);
|
||||
return eventHandler.HandleEvent(aWeakFrameForPresShell,
|
||||
&mouseRawUpdateEvent, aDontRetargetEvents,
|
||||
&rawUpdateStatus);
|
||||
}
|
||||
if (const WidgetTouchEvent* const touchEvent = aSourceEvent.AsTouchEvent()) {
|
||||
WidgetTouchEvent touchRawUpdate(*touchEvent,
|
||||
WidgetTouchEvent::CloneTouches::No);
|
||||
touchRawUpdate.mMessage = eTouchRawUpdate;
|
||||
touchRawUpdate.mTouches.Clear();
|
||||
for (const RefPtr<Touch>& touch : touchEvent->mTouches) {
|
||||
// If `convertToPointer` is `false`, it means that we've already handled
|
||||
// the event to dispatch a preceding pointer event. Therefore, its
|
||||
// preceding event should've already been handled.
|
||||
// If ShouldConvertTouchToPointer() returns `false`, the touch is not an
|
||||
// active pointer or the touch hasn't been changed from the previous
|
||||
// state. Therefore, we don't need to dispatch ePointerRawUpdate for the
|
||||
// touch.
|
||||
if (!touch->convertToPointerRawUpdate ||
|
||||
!TouchManager::ShouldConvertTouchToPointer(touch, &touchRawUpdate)) {
|
||||
continue;
|
||||
}
|
||||
RefPtr<Touch> newTouch = new Touch(*touch);
|
||||
newTouch->mMessage = eTouchRawUpdate;
|
||||
newTouch->mCoalescedWidgetEvents = nullptr;
|
||||
touchRawUpdate.mTouches.AppendElement(std::move(newTouch));
|
||||
}
|
||||
nsEventStatus rawUpdateStatus = nsEventStatus_eIgnore;
|
||||
if (touchRawUpdate.mTouches.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
EventHandler eventHandler(*this);
|
||||
return eventHandler.HandleEvent(aWeakFrameForPresShell, &touchRawUpdate,
|
||||
aDontRetargetEvents, &rawUpdateStatus);
|
||||
}
|
||||
MOZ_ASSERT_UNREACHABLE("Handle the event to dispatch ePointerRawUpdate");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool PresShell::EventHandler::UpdateFocusSequenceNumber(
|
||||
nsIFrame* aFrameForPresShell, uint64_t aEventFocusSequenceNumber) {
|
||||
uint64_t focusSequenceNumber;
|
||||
@@ -7602,24 +7485,6 @@ nsresult PresShell::EventHandler::HandleEventUsingCoordinates(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we are trying to dispatch an ePointerRawUpdate but it's not allowed in
|
||||
// the (maybe retargetted) document, we should not flush the capture state
|
||||
// below.
|
||||
if (aGUIEvent->mMessage == eMouseRawUpdate ||
|
||||
aGUIEvent->mMessage == eTouchRawUpdate) {
|
||||
EventTargetDataWithCapture eventTargetData =
|
||||
EventTargetDataWithCapture::QueryEventTargetUsingCoordinates(
|
||||
*this, aWeakFrameForPresShell,
|
||||
EventTargetDataWithCapture::Query::PendingState, aGUIEvent);
|
||||
if (!PointerEventHandler::NeedToDispatchPointerRawUpdate(
|
||||
eventTargetData.GetDocument())) {
|
||||
return NS_OK;
|
||||
}
|
||||
// Then, we need to recompute the target with processing the pending pointer
|
||||
// capture. Note that the result may be differnet since `gotpointercapture`
|
||||
// event listener does something tricky things.
|
||||
}
|
||||
|
||||
EventTargetDataWithCapture eventTargetData =
|
||||
EventTargetDataWithCapture::QueryEventTargetUsingCoordinates(
|
||||
*this, aWeakFrameForPresShell,
|
||||
@@ -7744,12 +7609,6 @@ PresShell::EventHandler::EventTargetDataWithCapture::EventTargetDataWithCapture(
|
||||
if (GetDocument() && aGUIEvent->mClass == eTouchEventClass) {
|
||||
PointerLockManager::Unlock("TouchEvent");
|
||||
}
|
||||
// XXX If aGUIEvent is eMouseRawUpdate or eTouchRawUpdate and it's
|
||||
// dispatched by BrowserChild, i.e., the event won't cause ePointerMove
|
||||
// immediately after ePointerRawUpdate, should we skip fluhsing pending
|
||||
// animations here? Doing this could cause different animation result while
|
||||
// the user moves mouse cursor during a long animation whether there is a
|
||||
// `pointerrawupdate` event listener or not.
|
||||
aEventHandler.MaybeFlushThrottledStyles(aWeakFrameForPresShell);
|
||||
// Previously, MaybeFlushThrottledStyles() recomputed the closest ancestor
|
||||
// frame for view of mPresShell if it's reframed. Therefore, we should keep
|
||||
@@ -8055,15 +7914,11 @@ bool PresShell::EventHandler::DispatchPrecedingPointerEvent(
|
||||
aPointerCapturingElement, aGUIEvent, aDontRetargetEvents, aEventStatus,
|
||||
getter_AddRefs(mouseOrTouchEventTargetContent));
|
||||
|
||||
const bool maybeCallerCanHandleEvent =
|
||||
aGUIEvent->mMessage != eMouseRawUpdate &&
|
||||
aGUIEvent->mMessage != eTouchRawUpdate;
|
||||
|
||||
// If the target frame is alive, the caller should keep handling the event
|
||||
// unless event target frame is destroyed.
|
||||
if (weakTargetFrame.IsAlive() && weakFrame.IsAlive()) {
|
||||
aEventTargetData->UpdateTouchEventTarget(aGUIEvent);
|
||||
return maybeCallerCanHandleEvent;
|
||||
return true;
|
||||
}
|
||||
|
||||
presShell->FlushPendingNotifications(FlushType::Layout);
|
||||
@@ -8101,7 +7956,7 @@ bool PresShell::EventHandler::DispatchPrecedingPointerEvent(
|
||||
}
|
||||
|
||||
aEventTargetData->UpdateTouchEventTarget(aGUIEvent);
|
||||
return maybeCallerCanHandleEvent;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8521,16 +8376,6 @@ bool PresShell::EventHandler::MaybeDiscardOrDelayMouseEvent(
|
||||
MOZ_ASSERT(aFrameToHandleEvent);
|
||||
MOZ_ASSERT(aGUIEvent);
|
||||
|
||||
// We must not need to let suspend listeners know ePointerRawUpdate events.
|
||||
// And also the delayed events will be dispatched via widget. Therefore,
|
||||
// ePointerRawUpdate event will be dispatched by PresShell::HandleEvent()
|
||||
// again.
|
||||
if (aGUIEvent->mMessage == eMouseRawUpdate ||
|
||||
aGUIEvent->mMessage == eTouchRawUpdate ||
|
||||
aGUIEvent->mMessage == ePointerRawUpdate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aGUIEvent->IsMouseEventClassOrHasClickRelatedPointerEvent()) {
|
||||
return false;
|
||||
}
|
||||
@@ -9232,11 +9077,6 @@ bool PresShell::EventHandler::PrepareToDispatchEvent(
|
||||
MaybeHandleKeyboardEventBeforeDispatch(keyboardEvent);
|
||||
return true;
|
||||
}
|
||||
case eMouseRawUpdate:
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"eMouseRawUpdate shouldn't be handled as a DOM event");
|
||||
return false;
|
||||
|
||||
case eMouseMove: {
|
||||
bool allowCapture = EventStateManager::GetActiveEventStateManager() &&
|
||||
GetPresContext() &&
|
||||
@@ -9291,10 +9131,6 @@ bool PresShell::EventHandler::PrepareToDispatchEvent(
|
||||
return mPresShell->mTouchManager.PreHandleEvent(
|
||||
aEvent, aEventStatus, *aTouchIsNew,
|
||||
mPresShell->mCurrentEventTarget.mContent);
|
||||
case eTouchRawUpdate:
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"eTouchRawUpdate shouldn't be handled as a DOM event");
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
@@ -9336,10 +9172,6 @@ void PresShell::EventHandler::FinalizeHandlingEvent(
|
||||
// reset the capturing content now that the mouse button is up
|
||||
PresShell::ReleaseCapturingContent();
|
||||
break;
|
||||
case eMouseRawUpdate:
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"eMouseRawUpdate shouldn't be handled as a DOM event");
|
||||
break;
|
||||
case eMouseMove:
|
||||
PresShell::AllowMouseCapture(false);
|
||||
break;
|
||||
@@ -9369,10 +9201,6 @@ void PresShell::EventHandler::FinalizeHandlingEvent(
|
||||
mPresShell->mTouchManager.PostHandleEvent(aEvent, aStatus);
|
||||
break;
|
||||
}
|
||||
case eTouchRawUpdate:
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"eTouchRawUpdate shouldn't be handled as a DOM event");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -9485,10 +9313,6 @@ void PresShell::EventHandler::RecordEventPreparationPerformance(
|
||||
nsPresContext::InteractionType::ClickInteraction, aEvent->mTimeStamp);
|
||||
return;
|
||||
|
||||
case eMouseRawUpdate:
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"eMouseRawUpdate shouldn't be handled as a DOM event");
|
||||
break;
|
||||
case eMouseMove:
|
||||
GetPresContext()->RecordInteractionTime(
|
||||
nsPresContext::InteractionType::MouseMoveInteraction,
|
||||
@@ -9669,7 +9493,6 @@ nsresult PresShell::EventHandler::DispatchEventToDOM(
|
||||
void PresShell::EventHandler::DispatchTouchEventToDOM(
|
||||
WidgetEvent* aEvent, nsEventStatus* aEventStatus,
|
||||
nsPresShellEventCB* aEventCB, bool aTouchIsNew) {
|
||||
MOZ_ASSERT(aEvent->mMessage != eTouchRawUpdate);
|
||||
// calling preventDefault on touchstart or the first touchmove for a
|
||||
// point prevents mouse events. calling it on the touchend should
|
||||
// prevent click dispatching.
|
||||
|
||||
@@ -1996,15 +1996,6 @@ class PresShell final : public nsStubDocumentObserver,
|
||||
// Utility method to restore the root scrollframe state
|
||||
void RestoreRootScrollPosition();
|
||||
|
||||
/**
|
||||
* Dispatch eMouseRawUpdate or eTouchRawUpdate event if aSourceEvent requires
|
||||
* a preceding "pointerrawupdate" event and there are some windows which have
|
||||
* its listener.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT nsresult EnsurePrecedingPointerRawUpdate(
|
||||
AutoWeakFrame& aWeakFrameForPresShell, const WidgetGUIEvent& aSourceEvent,
|
||||
bool aDontRetargetEvents);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void MaybeReleaseCapturingContent();
|
||||
|
||||
class DelayedEvent {
|
||||
|
||||
@@ -303,9 +303,6 @@ bool TouchManager::PreHandleEvent(WidgetEvent* aEvent, nsEventStatus* aStatus,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eTouchRawUpdate:
|
||||
MOZ_ASSERT_UNREACHABLE("eTouchRawUpdate shouldn't be handled as a touch");
|
||||
break;
|
||||
case eTouchMove: {
|
||||
// Check for touches that changed. Mark them add to queue
|
||||
WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
|
||||
@@ -451,9 +448,6 @@ bool TouchManager::PreHandleEvent(WidgetEvent* aEvent, nsEventStatus* aStatus,
|
||||
void TouchManager::PostHandleEvent(const WidgetEvent* aEvent,
|
||||
const nsEventStatus* aStatus) {
|
||||
switch (aEvent->mMessage) {
|
||||
case eTouchRawUpdate:
|
||||
MOZ_ASSERT_UNREACHABLE("eTouchRawUpdate shouldn't be handled as a touch");
|
||||
break;
|
||||
case eTouchMove: {
|
||||
if (sSingleTouchStartTimeStamp.IsNull()) {
|
||||
break;
|
||||
@@ -565,8 +559,7 @@ bool TouchManager::ShouldConvertTouchToPointer(const Touch* aTouch,
|
||||
// We don't want to fire duplicated pointerdown.
|
||||
return false;
|
||||
}
|
||||
case eTouchMove:
|
||||
case eTouchRawUpdate: {
|
||||
case eTouchMove: {
|
||||
return !aTouch->Equals(info.mTouch);
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -2820,12 +2820,6 @@
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Whether pointerrawupdate event is enabled or disabled.
|
||||
- name: dom.event.pointer.rawupdate.enabled
|
||||
type: bool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Whether wheel event target's should be grouped. When enabled, all wheel
|
||||
# events that occur in a given wheel transaction have the same event target.
|
||||
- name: dom.event.wheel-event-groups.enabled
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
[idlharness.https.window.html]
|
||||
[Document interface: attribute onpointerrawupdate]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document must inherit property "onpointerrawupdate" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[Window interface: attribute onpointerrawupdate]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: attribute onpointerrawupdate]
|
||||
expected: FAIL
|
||||
|
||||
[Window interface: window must inherit property "onpointerrawupdate" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[PointerEvent interface: attribute persistentDeviceId]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[pointerevent_boundary_events_before_pointerrawupdate.https.html]
|
||||
[Pointer boundary events should be fired before `pointerrawupdate`]
|
||||
expected: FAIL
|
||||
@@ -0,0 +1,4 @@
|
||||
[pointerevent_pointerrawupdate.https.html]
|
||||
[pointerrawupdate event received]
|
||||
expected: FAIL
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[pointerevent_pointerrawupdate_after_adoption_from_child.https.html]
|
||||
[`pointerrawupdate` events should be fired after the element is moved from the parent doc to a child doc]
|
||||
expected: FAIL
|
||||
@@ -0,0 +1,3 @@
|
||||
[pointerevent_pointerrawupdate_after_adoption_from_parent.https.html]
|
||||
[`pointerrawupdate` events should be fired after the element is moved from a child doc to the parent doc]
|
||||
expected: FAIL
|
||||
@@ -0,0 +1,3 @@
|
||||
[pointerevent_pointerrawupdate_flush_pointercapture.https.html]
|
||||
[Pointer capture state should be updated before `pointerrawupdate`]
|
||||
expected: FAIL
|
||||
@@ -1,3 +1,9 @@
|
||||
[pointerevent_pointerrawupdate_remove_target.https.html]
|
||||
["pointermove" and its preceding boundary events should be fired on parent if "pointerrawupdate" event listener removes its target]
|
||||
expected: FAIL
|
||||
|
||||
["pointermove" and its preceding boundary events should be fired on ancestor if "pointerrawupdate" event listener removes its target parent]
|
||||
expected: FAIL
|
||||
|
||||
["pointermove" and its preceding boundary events should be fired on parent if "pointerrawupdate" event listener removes its document]
|
||||
expected: FAIL
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
[pointerevent_pointerrawupdate_in_pointerlock.https.html]
|
||||
max-asserts: 1 # in PointerEventHandler::DispatchPointerFromMouseOrTouch
|
||||
expected:
|
||||
if (os == "win") and debug and (processor == "x86_64"): [OK, TIMEOUT]
|
||||
if (os == "win") and debug and (processor == "x86"): TIMEOUT
|
||||
if (os == "linux") and debug and fission: [OK, TIMEOUT]
|
||||
if (os == "linux") and debug and not fission: [OK, ERROR, TIMEOUT]
|
||||
if (os == "linux") and not debug: [OK, TIMEOUT]
|
||||
[pointerrawupdate event received]
|
||||
expected:
|
||||
if (os == "win") and debug and (processor == "x86_64"): [FAIL, NOTRUN]
|
||||
if (os == "win") and debug and (processor == "x86"): NOTRUN
|
||||
if os == "linux": [FAIL, NOTRUN]
|
||||
FAIL
|
||||
|
||||
@@ -454,9 +454,9 @@ class WidgetEvent : public WidgetEventTime {
|
||||
break;
|
||||
case ePointerEventClass:
|
||||
mFlags.mCancelable =
|
||||
(mMessage != ePointerRawUpdate && mMessage != ePointerEnter &&
|
||||
mMessage != ePointerLeave && mMessage != ePointerCancel &&
|
||||
mMessage != ePointerGotCapture && mMessage != ePointerLostCapture);
|
||||
(mMessage != ePointerEnter && mMessage != ePointerLeave &&
|
||||
mMessage != ePointerCancel && mMessage != ePointerGotCapture &&
|
||||
mMessage != ePointerLostCapture);
|
||||
mFlags.mBubbles =
|
||||
(mMessage != ePointerEnter && mMessage != ePointerLeave);
|
||||
break;
|
||||
@@ -931,12 +931,12 @@ class WidgetEvent : public WidgetEventTime {
|
||||
case ePointerEventClass:
|
||||
// All pointer events are composed
|
||||
mFlags.mComposed =
|
||||
mMessage == ePointerRawUpdate || mMessage == ePointerMove ||
|
||||
mMessage == ePointerClick || mMessage == ePointerAuxClick ||
|
||||
mMessage == eContextMenu || mMessage == ePointerDown ||
|
||||
mMessage == ePointerUp || mMessage == ePointerCancel ||
|
||||
mMessage == ePointerOver || mMessage == ePointerOut ||
|
||||
mMessage == ePointerGotCapture || mMessage == ePointerLostCapture;
|
||||
mMessage == ePointerMove || mMessage == ePointerUp ||
|
||||
mMessage == ePointerCancel || mMessage == ePointerOver ||
|
||||
mMessage == ePointerOut || mMessage == ePointerGotCapture ||
|
||||
mMessage == ePointerLostCapture;
|
||||
break;
|
||||
case eTouchEventClass:
|
||||
// All touch events are composed
|
||||
@@ -1011,7 +1011,6 @@ class WidgetEvent : public WidgetEventTime {
|
||||
aEventTypeArg.EqualsLiteral("pointerout") ||
|
||||
aEventTypeArg.EqualsLiteral("pointerenter") ||
|
||||
aEventTypeArg.EqualsLiteral("pointerleave") ||
|
||||
aEventTypeArg.EqualsLiteral("pointerrawupdate") ||
|
||||
aEventTypeArg.EqualsLiteral("gotpointercapture") ||
|
||||
aEventTypeArg.EqualsLiteral("lostpointercapture") ||
|
||||
// touch events
|
||||
|
||||
@@ -93,14 +93,6 @@ NS_EVENT_MESSAGE(eMouseEnter)
|
||||
NS_EVENT_MESSAGE(eMouseLeave)
|
||||
NS_EVENT_MESSAGE(eMouseTouchDrag)
|
||||
NS_EVENT_MESSAGE(eMouseLongTap)
|
||||
// eMouseRawUpdate is for dispatching ePointerRawUpdate caused by a mouse input.
|
||||
// When we dispatch ePointerRawUpdate, we need to handle the steps defined by
|
||||
// the spec in "fire a pointer event" section like the other pointer event.
|
||||
// The steps are handled by
|
||||
// PresShell::EventHandler::DispatchPrecedingPointerEvent() and for using it, we
|
||||
// should dispatch this internal event instead of dispatching ePointerRawUpdate
|
||||
// directly.
|
||||
NS_EVENT_MESSAGE(eMouseRawUpdate)
|
||||
NS_EVENT_MESSAGE(eMouseExploreByTouch)
|
||||
NS_EVENT_MESSAGE_FIRST_LAST(eMouseEvent, eMouseMove, eMouseExploreByTouch)
|
||||
|
||||
@@ -108,13 +100,6 @@ NS_EVENT_MESSAGE(ePointerClick)
|
||||
NS_EVENT_MESSAGE(ePointerAuxClick)
|
||||
|
||||
// Pointer spec events
|
||||
// NOTE: We handle the steps before dispatching a pointer event which is defined
|
||||
// by the spec in "fire a pointer event" section in
|
||||
// PresShell::EventHandler::DispatchPrecedingPointerEvent(). Therefore,
|
||||
// we should not dispatch ePointer* events with
|
||||
// `PresShell::EventHandler::HandleEvent` directly. Create a new internal
|
||||
// message for implementing a new pointer event if the new event is defined as
|
||||
// dispatched with "fire a pointer event" steps.
|
||||
NS_EVENT_MESSAGE(ePointerMove)
|
||||
NS_EVENT_MESSAGE(ePointerUp)
|
||||
NS_EVENT_MESSAGE(ePointerDown)
|
||||
@@ -123,7 +108,6 @@ NS_EVENT_MESSAGE(ePointerOut)
|
||||
NS_EVENT_MESSAGE(ePointerEnter)
|
||||
NS_EVENT_MESSAGE(ePointerLeave)
|
||||
NS_EVENT_MESSAGE(ePointerCancel)
|
||||
NS_EVENT_MESSAGE(ePointerRawUpdate)
|
||||
NS_EVENT_MESSAGE(ePointerGotCapture)
|
||||
NS_EVENT_MESSAGE(ePointerLostCapture)
|
||||
NS_EVENT_MESSAGE_FIRST_LAST(ePointerEvent, ePointerMove, ePointerLostCapture)
|
||||
@@ -448,14 +432,6 @@ NS_EVENT_MESSAGE(eTouchMove)
|
||||
NS_EVENT_MESSAGE(eTouchEnd)
|
||||
NS_EVENT_MESSAGE(eTouchCancel)
|
||||
NS_EVENT_MESSAGE(eTouchPointerCancel)
|
||||
// eTouchRawUpdate is for dispatching ePointerRawUpdate caused by a touch.
|
||||
// When we dispatch ePointerRawUpdate, we need to handle the steps defined by
|
||||
// the spec in "fire a pointer event" section like the other pointer event.
|
||||
// The steps are handled by
|
||||
// PresShell::EventHandler::DispatchPrecedingPointerEvent() and for using it, we
|
||||
// should dispatch this internal event instead of dispatching ePointerRawUpdate
|
||||
// directly.
|
||||
NS_EVENT_MESSAGE(eTouchRawUpdate)
|
||||
|
||||
// Pointerlock DOM API
|
||||
NS_EVENT_MESSAGE(ePointerLockChange)
|
||||
|
||||
@@ -43,22 +43,22 @@ class WidgetPointerEventHolder final {
|
||||
|
||||
class WidgetPointerHelper {
|
||||
public:
|
||||
uint32_t pointerId = 0;
|
||||
int32_t tiltX = 0;
|
||||
int32_t tiltY = 0;
|
||||
int32_t twist = 0;
|
||||
float tangentialPressure = 0.0f;
|
||||
bool convertToPointer = true;
|
||||
// When convertToPointerRawUpdate is set to true, the event or the touch may
|
||||
// cause ePointerRawUpdate event in PresShell::HandleEvent() if it's requested
|
||||
// by the web app. This is set to false if the source mouse event or the
|
||||
// source touch move event is not dispatched immediately by BrowserChild
|
||||
// because BrowserChild dispatches only eMouseRawUpdate or eTouchRawUpdate to
|
||||
// dispatch ePointerRawUpdate immediately.
|
||||
bool convertToPointerRawUpdate = true;
|
||||
uint32_t pointerId;
|
||||
int32_t tiltX;
|
||||
int32_t tiltY;
|
||||
int32_t twist;
|
||||
float tangentialPressure;
|
||||
bool convertToPointer;
|
||||
RefPtr<WidgetPointerEventHolder> mCoalescedWidgetEvents;
|
||||
|
||||
WidgetPointerHelper() = default;
|
||||
WidgetPointerHelper()
|
||||
: pointerId(0),
|
||||
tiltX(0),
|
||||
tiltY(0),
|
||||
twist(0),
|
||||
tangentialPressure(0),
|
||||
convertToPointer(true) {}
|
||||
|
||||
WidgetPointerHelper(uint32_t aPointerId, uint32_t aTiltX, uint32_t aTiltY,
|
||||
uint32_t aTwist = 0, float aTangentialPressure = 0)
|
||||
: pointerId(aPointerId),
|
||||
@@ -108,7 +108,6 @@ class WidgetPointerHelper {
|
||||
twist = aEvent.twist;
|
||||
tangentialPressure = aEvent.tangentialPressure;
|
||||
convertToPointer = aEvent.convertToPointer;
|
||||
convertToPointerRawUpdate = aEvent.convertToPointerRawUpdate;
|
||||
if (aCopyCoalescedEvents) {
|
||||
mCoalescedWidgetEvents = aEvent.mCoalescedWidgetEvents;
|
||||
}
|
||||
@@ -414,13 +413,7 @@ class WidgetMouseEvent : public WidgetMouseEventBase,
|
||||
* Returns true if the event is a real mouse event. Otherwise, i.e., it's
|
||||
* a synthesized event by scroll or something, returns false.
|
||||
*/
|
||||
[[nodiscard]] bool IsReal() const { return mReason == eReal; }
|
||||
|
||||
/**
|
||||
* Returns true if the event is synthesized for scroll or layout change.
|
||||
* Do not confuse this with a synthesized event for tests.
|
||||
*/
|
||||
[[nodiscard]] bool IsSynthesized() const { return mReason == eSynthesized; }
|
||||
bool IsReal() const { return mReason == eReal; }
|
||||
|
||||
/**
|
||||
* Returns true if middle click paste is enabled.
|
||||
|
||||
@@ -151,23 +151,13 @@ class WidgetTouchEvent final : public WidgetInputEvent {
|
||||
|
||||
MOZ_COUNTED_DEFAULT_CTOR(WidgetTouchEvent)
|
||||
|
||||
enum class CloneTouches : bool { No, Yes };
|
||||
WidgetTouchEvent(const WidgetTouchEvent& aOther,
|
||||
CloneTouches aCloneTouches = CloneTouches::No)
|
||||
WidgetTouchEvent(const WidgetTouchEvent& aOther)
|
||||
: WidgetInputEvent(aOther.IsTrusted(), aOther.mMessage, aOther.mWidget,
|
||||
eTouchEventClass) {
|
||||
MOZ_COUNT_CTOR(WidgetTouchEvent);
|
||||
mModifiers = aOther.mModifiers;
|
||||
mTimeStamp = aOther.mTimeStamp;
|
||||
if (static_cast<bool>(aCloneTouches)) {
|
||||
mTouches.SetCapacity(aOther.mTouches.Length());
|
||||
for (const RefPtr<dom::Touch>& touch : aOther.mTouches) {
|
||||
RefPtr<dom::Touch> clonedTouch = new dom::Touch(*touch);
|
||||
mTouches.AppendElement(std::move(clonedTouch));
|
||||
}
|
||||
} else {
|
||||
mTouches.AppendElements(aOther.mTouches);
|
||||
}
|
||||
mTouches.AppendElements(aOther.mTouches);
|
||||
mInputSource = aOther.mInputSource;
|
||||
mButton = aOther.mButton;
|
||||
mButtons = aOther.mButtons;
|
||||
@@ -223,20 +213,6 @@ class WidgetTouchEvent final : public WidgetInputEvent {
|
||||
mTouches.AppendElements(aEvent.mTouches);
|
||||
mInputSource = aEvent.mInputSource;
|
||||
}
|
||||
|
||||
void SetConvertToPointerRawUpdate(bool aConvert) {
|
||||
for (dom::Touch* const touch : mTouches) {
|
||||
touch->convertToPointerRawUpdate = aConvert;
|
||||
}
|
||||
}
|
||||
[[nodiscard]] bool CanConvertToPointerRawUpdate() const {
|
||||
for (const dom::Touch* const touch : mTouches) {
|
||||
if (touch->convertToPointerRawUpdate) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -73,7 +73,6 @@ bool IsPointerEventMessage(EventMessage aMessage) {
|
||||
case ePointerOut:
|
||||
case ePointerEnter:
|
||||
case ePointerLeave:
|
||||
case ePointerRawUpdate:
|
||||
case ePointerGotCapture:
|
||||
case ePointerLostCapture:
|
||||
case ePointerClick:
|
||||
@@ -122,7 +121,6 @@ bool IsForbiddenDispatchingToNonElementContent(EventMessage aMessage) {
|
||||
case ePointerOut:
|
||||
case ePointerEnter:
|
||||
case ePointerLeave:
|
||||
case ePointerRawUpdate:
|
||||
case ePointerCancel:
|
||||
case ePointerGotCapture:
|
||||
case ePointerLostCapture:
|
||||
@@ -174,12 +172,6 @@ bool IsForbiddenDispatchingToNonElementContent(EventMessage aMessage) {
|
||||
case eTouchPointerCancel:
|
||||
return true;
|
||||
|
||||
case eMouseRawUpdate:
|
||||
case eTouchRawUpdate:
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"Internal raw update events shouldn't be dispatched to the DOM");
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -390,7 +382,6 @@ bool WidgetEvent::HasMouseEventMessage() const {
|
||||
case eMouseOut:
|
||||
case eMouseHitTest:
|
||||
case eMouseMove:
|
||||
case eMouseRawUpdate:
|
||||
return true;
|
||||
// TODO: Perhaps, we should rename this method.
|
||||
case ePointerClick:
|
||||
@@ -538,7 +529,7 @@ bool WidgetEvent::IsTargetedAtFocusedContent() const {
|
||||
bool WidgetEvent::IsAllowedToDispatchDOMEvent() const {
|
||||
switch (mClass) {
|
||||
case eMouseEventClass:
|
||||
if (mMessage == eMouseRawUpdate || mMessage == eMouseTouchDrag) {
|
||||
if (mMessage == eMouseTouchDrag) {
|
||||
return false;
|
||||
}
|
||||
[[fallthrough]];
|
||||
@@ -548,7 +539,7 @@ bool WidgetEvent::IsAllowedToDispatchDOMEvent() const {
|
||||
// DOM events.
|
||||
// Synthesized button up events also do not cause DOM events because they
|
||||
// do not have a reliable mRefPoint.
|
||||
return AsMouseEvent()->IsReal();
|
||||
return AsMouseEvent()->mReason == WidgetMouseEvent::eReal;
|
||||
|
||||
case eWheelEventClass: {
|
||||
// wheel event whose all delta values are zero by user pref applied, it
|
||||
@@ -558,7 +549,7 @@ bool WidgetEvent::IsAllowedToDispatchDOMEvent() const {
|
||||
wheelEvent->mDeltaZ != 0.0;
|
||||
}
|
||||
case eTouchEventClass:
|
||||
return mMessage != eTouchRawUpdate && mMessage != eTouchPointerCancel;
|
||||
return mMessage != eTouchPointerCancel;
|
||||
// Following events are handled in EventStateManager, so, we don't need to
|
||||
// dispatch DOM event for them into the DOM tree.
|
||||
case eQueryContentEventClass:
|
||||
@@ -915,7 +906,6 @@ float WidgetMouseEventBase::ComputeMouseButtonPressure() const {
|
||||
switch (mMessage) {
|
||||
// This method is designed for mouse events.
|
||||
case eMouseMove:
|
||||
case eMouseRawUpdate:
|
||||
case eMouseUp:
|
||||
case eMouseDown:
|
||||
case eMouseEnterIntoWidget:
|
||||
@@ -944,7 +934,6 @@ float WidgetMouseEventBase::ComputeMouseButtonPressure() const {
|
||||
case ePointerClick:
|
||||
case ePointerAuxClick:
|
||||
case ePointerMove:
|
||||
case ePointerRawUpdate:
|
||||
case ePointerUp:
|
||||
case ePointerDown:
|
||||
case ePointerCancel:
|
||||
|
||||
@@ -1955,7 +1955,6 @@ STATIC_ATOMS = [
|
||||
Atom("onpointerout", "onpointerout"),
|
||||
Atom("onpointerenter", "onpointerenter"),
|
||||
Atom("onpointerleave", "onpointerleave"),
|
||||
Atom("onpointerrawupdate", "onpointerrawupdate"),
|
||||
Atom("ongotpointercapture", "ongotpointercapture"),
|
||||
Atom("onlostpointercapture", "onlostpointercapture"),
|
||||
# orientation support
|
||||
|
||||
Reference in New Issue
Block a user