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();
|
StartDying();
|
||||||
|
|
||||||
ClearHasPointerRawUpdateEventListeners();
|
|
||||||
|
|
||||||
if (mDoc && mDoc->GetWindowContext()) {
|
if (mDoc && mDoc->GetWindowContext()) {
|
||||||
// The document is about to lose its window, so this is a good time to send
|
// The document is about to lose its window, so this is a good time to send
|
||||||
// our page use counters.
|
// our page use counters.
|
||||||
@@ -7689,26 +7687,6 @@ TrustedTypePolicyFactory* nsGlobalWindowInner::TrustedTypes() {
|
|||||||
return mTrustedTypePolicyFactory;
|
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 {
|
nsIURI* nsPIDOMWindowInner::GetDocumentURI() const {
|
||||||
return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
|
return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
|
||||||
}
|
}
|
||||||
@@ -7799,7 +7777,29 @@ CloseWatcherManager* nsPIDOMWindowInner::EnsureCloseWatcherManager() {
|
|||||||
|
|
||||||
nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
|
nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
|
||||||
WindowGlobalChild* aActor)
|
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);
|
MOZ_ASSERT(aOuterWindow);
|
||||||
mBrowsingContext = aOuterWindow->GetBrowsingContext();
|
mBrowsingContext = aOuterWindow->GetBrowsingContext();
|
||||||
|
|
||||||
|
|||||||
@@ -3656,9 +3656,6 @@ already_AddRefed<nsINode> nsINode::CloneAndAdopt(
|
|||||||
if (elm->MayHavePointerEnterLeaveEventListener()) {
|
if (elm->MayHavePointerEnterLeaveEventListener()) {
|
||||||
window->SetHasPointerEnterLeaveEventListeners();
|
window->SetHasPointerEnterLeaveEventListeners();
|
||||||
}
|
}
|
||||||
if (elm->MayHavePointerRawUpdateEventListener()) {
|
|
||||||
window->MaybeSetHasPointerRawUpdateEventListeners();
|
|
||||||
}
|
|
||||||
if (elm->MayHaveSelectionChangeEventListener()) {
|
if (elm->MayHaveSelectionChangeEventListener()) {
|
||||||
window->SetHasSelectionChangeEventListeners();
|
window->SetHasSelectionChangeEventListeners();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -224,29 +224,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
|||||||
mMayHavePointerEnterLeaveEventListener = true;
|
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,
|
* Call this to check whether some node (this window, its document,
|
||||||
* or content in that document) has a transition* event listeners.
|
* or content in that document) has a transition* event listeners.
|
||||||
@@ -672,25 +649,24 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
|||||||
RefPtr<mozilla::dom::Navigator> mNavigator;
|
RefPtr<mozilla::dom::Navigator> mNavigator;
|
||||||
|
|
||||||
// These variables are only used on inner windows.
|
// These variables are only used on inner windows.
|
||||||
uint32_t mMutationBits = 0;
|
uint32_t mMutationBits;
|
||||||
|
|
||||||
uint32_t mActivePeerConnections = 0;
|
uint32_t mActivePeerConnections = 0;
|
||||||
|
|
||||||
bool mIsDocumentLoaded = false;
|
bool mIsDocumentLoaded;
|
||||||
bool mIsHandlingResizeEvent = false;
|
bool mIsHandlingResizeEvent;
|
||||||
bool mMayHaveDOMActivateEventListeners = false;
|
bool mMayHaveDOMActivateEventListeners;
|
||||||
bool mMayHaveTouchEventListener = false;
|
bool mMayHaveTouchEventListener;
|
||||||
bool mMayHaveSelectionChangeEventListener = false;
|
bool mMayHaveSelectionChangeEventListener;
|
||||||
bool mMayHaveFormSelectEventListener = false;
|
bool mMayHaveFormSelectEventListener;
|
||||||
bool mMayHaveMouseEnterLeaveEventListener = false;
|
bool mMayHaveMouseEnterLeaveEventListener;
|
||||||
bool mMayHavePointerEnterLeaveEventListener = false;
|
bool mMayHavePointerEnterLeaveEventListener;
|
||||||
bool mMayHavePointerRawUpdateEventListener = false;
|
bool mMayHaveTransitionEventListener;
|
||||||
bool mMayHaveTransitionEventListener = false;
|
bool mMayHaveSMILTimeEventListener;
|
||||||
bool mMayHaveSMILTimeEventListener = false;
|
|
||||||
// Only used for telemetry probes. This may be wrong if some nodes have
|
// Only used for telemetry probes. This may be wrong if some nodes have
|
||||||
// come from another document with `Document.adoptNode`.
|
// come from another document with `Document.adoptNode`.
|
||||||
bool mMayHaveBeforeInputEventListenerForTelemetry = false;
|
bool mMayHaveBeforeInputEventListenerForTelemetry;
|
||||||
bool mMutationObserverHasObservedNodeForTelemetry = false;
|
bool mMutationObserverHasObservedNodeForTelemetry;
|
||||||
|
|
||||||
// Our inner window's outer window.
|
// Our inner window's outer window.
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> mOuterWindow;
|
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
|
// A unique (as long as our 64-bit counter doesn't roll over) id for
|
||||||
// this window.
|
// this window.
|
||||||
uint64_t mWindowID = 0;
|
uint64_t mWindowID;
|
||||||
|
|
||||||
// Set to true once we've sent the (chrome|content)-document-global-created
|
// Set to true once we've sent the (chrome|content)-document-global-created
|
||||||
// notification.
|
// notification.
|
||||||
bool mHasNotifiedGlobalCreated = false;
|
bool mHasNotifiedGlobalCreated;
|
||||||
|
|
||||||
// Whether when focused via an "unknown" focus method, we should show outlines
|
// 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
|
// 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).
|
// without any other user interaction).
|
||||||
bool mUnknownFocusMethodShouldShowOutline = true;
|
bool mUnknownFocusMethodShouldShowOutline = true;
|
||||||
|
|
||||||
uint32_t mMarkedCCGeneration = 0;
|
uint32_t mMarkedCCGeneration;
|
||||||
|
|
||||||
// mTopInnerWindow is used for tab-wise check by timeout throttling. It could
|
// mTopInnerWindow is used for tab-wise check by timeout throttling. It could
|
||||||
// be null.
|
// be null.
|
||||||
@@ -732,17 +708,17 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
|||||||
// The evidence that we have tried to cache mTopInnerWindow only once from
|
// The evidence that we have tried to cache mTopInnerWindow only once from
|
||||||
// SetNewDocument(). Note: We need this extra flag because mTopInnerWindow
|
// SetNewDocument(). Note: We need this extra flag because mTopInnerWindow
|
||||||
// could be null and we don't want it to be set multiple times.
|
// 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.
|
// The number of active IndexedDB databases.
|
||||||
uint32_t mNumOfIndexedDBDatabases = 0;
|
uint32_t mNumOfIndexedDBDatabases;
|
||||||
|
|
||||||
// The number of open WebSockets.
|
// The number of open WebSockets.
|
||||||
uint32_t mNumOfOpenWebSockets = 0;
|
uint32_t mNumOfOpenWebSockets;
|
||||||
|
|
||||||
// The event dispatch code sets and unsets this while keeping
|
// The event dispatch code sets and unsets this while keeping
|
||||||
// the event object alive.
|
// the event object alive.
|
||||||
mozilla::dom::Event* mEvent = nullptr;
|
mozilla::dom::Event* mEvent;
|
||||||
|
|
||||||
// The WindowGlobalChild actor for this window.
|
// The WindowGlobalChild actor for this window.
|
||||||
//
|
//
|
||||||
@@ -750,7 +726,7 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
|||||||
// during SetNewDocument, and cleared during FreeInnerObjects.
|
// during SetNewDocument, and cleared during FreeInnerObjects.
|
||||||
RefPtr<mozilla::dom::WindowGlobalChild> mWindowGlobalChild;
|
RefPtr<mozilla::dom::WindowGlobalChild> mWindowGlobalChild;
|
||||||
|
|
||||||
bool mWasSuspendedByGroup = false;
|
bool mWasSuspendedByGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count of the number of active LockRequest objects, including ones from
|
* Count of the number of active LockRequest objects, including ones from
|
||||||
|
|||||||
@@ -25,12 +25,8 @@
|
|||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/PresShell.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/AbortSignal.h"
|
||||||
#include "mozilla/dom/BindingUtils.h"
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
#include "mozilla/dom/ChromeUtils.h"
|
|
||||||
#include "mozilla/dom/EventCallbackDebuggerNotification.h"
|
#include "mozilla/dom/EventCallbackDebuggerNotification.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/Event.h"
|
#include "mozilla/dom/Event.h"
|
||||||
@@ -41,6 +37,9 @@
|
|||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
#include "mozilla/dom/TouchEvent.h"
|
#include "mozilla/dom/TouchEvent.h"
|
||||||
#include "mozilla/dom/UserActivation.h"
|
#include "mozilla/dom/UserActivation.h"
|
||||||
|
#include "mozilla/ScopeExit.h"
|
||||||
|
#include "mozilla/TimeStamp.h"
|
||||||
|
#include "mozilla/dom/ChromeUtils.h"
|
||||||
|
|
||||||
#include "EventListenerService.h"
|
#include "EventListenerService.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
@@ -146,7 +145,6 @@ EventListenerManagerBase::EventListenerManagerBase()
|
|||||||
mMayHaveTouchEventListener(false),
|
mMayHaveTouchEventListener(false),
|
||||||
mMayHaveMouseEnterLeaveEventListener(false),
|
mMayHaveMouseEnterLeaveEventListener(false),
|
||||||
mMayHavePointerEnterLeaveEventListener(false),
|
mMayHavePointerEnterLeaveEventListener(false),
|
||||||
mMayHavePointerRawUpdateEventListener(false),
|
|
||||||
mMayHaveSelectionChangeEventListener(false),
|
mMayHaveSelectionChangeEventListener(false),
|
||||||
mMayHaveFormSelectEventListener(false),
|
mMayHaveFormSelectEventListener(false),
|
||||||
mMayHaveTransitionEventListener(false),
|
mMayHaveTransitionEventListener(false),
|
||||||
@@ -415,18 +413,6 @@ void EventListenerManager::AddEventListenerInternal(
|
|||||||
window->SetHasPointerEnterLeaveEventListeners();
|
window->SetHasPointerEnterLeaveEventListeners();
|
||||||
}
|
}
|
||||||
break;
|
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 eGamepadButtonDown:
|
||||||
case eGamepadButtonUp:
|
case eGamepadButtonUp:
|
||||||
case eGamepadAxisMove:
|
case eGamepadAxisMove:
|
||||||
@@ -876,15 +862,6 @@ void EventListenerManager::RemoveEventListenerInternal(
|
|||||||
DisableDevice(aUserType);
|
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) {
|
static bool IsDefaultPassiveWhenOnRoot(EventMessage aMessage) {
|
||||||
@@ -1852,20 +1829,16 @@ bool EventListenerManager::HasNonPassiveListenersFor(
|
|||||||
// After dispatching wheel, legacy mouse scroll events are dispatched
|
// After dispatching wheel, legacy mouse scroll events are dispatched
|
||||||
// and listeners on those can also default prevent the behavior.
|
// and listeners on those can also default prevent the behavior.
|
||||||
if (aEvent->mMessage == eWheel) {
|
if (aEvent->mMessage == eWheel) {
|
||||||
if (const auto& listeners =
|
if (const auto& listeners = mListenerMap.GetListenersForType(nsGkAtoms::onDOMMouseScroll)) {
|
||||||
mListenerMap.GetListenersForType(nsGkAtoms::onDOMMouseScroll)) {
|
|
||||||
for (const Listener& listener : listeners->NonObservingRange()) {
|
for (const Listener& listener : listeners->NonObservingRange()) {
|
||||||
if (!listener.mFlags.mPassive &&
|
if (!listener.mFlags.mPassive && ListenerCanHandle(&listener, aEvent)) {
|
||||||
ListenerCanHandle(&listener, aEvent)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (const auto& listeners = mListenerMap.GetListenersForType(
|
if (const auto& listeners = mListenerMap.GetListenersForType(nsGkAtoms::onMozMousePixelScroll)) {
|
||||||
nsGkAtoms::onMozMousePixelScroll)) {
|
|
||||||
for (const Listener& listener : listeners->NonObservingRange()) {
|
for (const Listener& listener : listeners->NonObservingRange()) {
|
||||||
if (!listener.mFlags.mPassive &&
|
if (!listener.mFlags.mPassive && ListenerCanHandle(&listener, aEvent)) {
|
||||||
ListenerCanHandle(&listener, aEvent)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,7 +159,6 @@ class EventListenerManagerBase {
|
|||||||
uint16_t mMayHaveTouchEventListener : 1;
|
uint16_t mMayHaveTouchEventListener : 1;
|
||||||
uint16_t mMayHaveMouseEnterLeaveEventListener : 1;
|
uint16_t mMayHaveMouseEnterLeaveEventListener : 1;
|
||||||
uint16_t mMayHavePointerEnterLeaveEventListener : 1;
|
uint16_t mMayHavePointerEnterLeaveEventListener : 1;
|
||||||
uint16_t mMayHavePointerRawUpdateEventListener : 1;
|
|
||||||
uint16_t mMayHaveSelectionChangeEventListener : 1;
|
uint16_t mMayHaveSelectionChangeEventListener : 1;
|
||||||
uint16_t mMayHaveFormSelectEventListener : 1;
|
uint16_t mMayHaveFormSelectEventListener : 1;
|
||||||
uint16_t mMayHaveTransitionEventListener : 1;
|
uint16_t mMayHaveTransitionEventListener : 1;
|
||||||
@@ -555,9 +554,6 @@ class EventListenerManager final : public EventListenerManagerBase {
|
|||||||
bool MayHavePointerEnterLeaveEventListener() const {
|
bool MayHavePointerEnterLeaveEventListener() const {
|
||||||
return mMayHavePointerEnterLeaveEventListener;
|
return mMayHavePointerEnterLeaveEventListener;
|
||||||
}
|
}
|
||||||
bool MayHavePointerRawUpdateEventListener() const {
|
|
||||||
return mMayHavePointerRawUpdateEventListener;
|
|
||||||
}
|
|
||||||
bool MayHaveSelectionChangeEventListener() const {
|
bool MayHaveSelectionChangeEventListener() const {
|
||||||
return mMayHaveSelectionChangeEventListener;
|
return mMayHaveSelectionChangeEventListener;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,8 +225,6 @@ EVENT(pointerover, ePointerOver, EventNameType_All, ePointerEventClass)
|
|||||||
EVENT(pointerout, ePointerOut, EventNameType_All, ePointerEventClass)
|
EVENT(pointerout, ePointerOut, EventNameType_All, ePointerEventClass)
|
||||||
EVENT(pointerenter, ePointerEnter, EventNameType_All, ePointerEventClass)
|
EVENT(pointerenter, ePointerEnter, EventNameType_All, ePointerEventClass)
|
||||||
EVENT(pointerleave, ePointerLeave, EventNameType_All, ePointerEventClass)
|
EVENT(pointerleave, ePointerLeave, EventNameType_All, ePointerEventClass)
|
||||||
EVENT(pointerrawupdate, ePointerRawUpdate, EventNameType_All,
|
|
||||||
ePointerEventClass)
|
|
||||||
EVENT(gotpointercapture, ePointerGotCapture, EventNameType_All,
|
EVENT(gotpointercapture, ePointerGotCapture, EventNameType_All,
|
||||||
ePointerEventClass)
|
ePointerEventClass)
|
||||||
EVENT(lostpointercapture, ePointerLostCapture, EventNameType_All,
|
EVENT(lostpointercapture, ePointerLostCapture, EventNameType_All,
|
||||||
|
|||||||
@@ -995,7 +995,6 @@ nsresult EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||||||
if (touchEvent->mMessage == eTouchMove) {
|
if (touchEvent->mMessage == eTouchMove) {
|
||||||
GenerateDragGesture(aPresContext, touchEvent);
|
GenerateDragGesture(aPresContext, touchEvent);
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(touchEvent->mMessage != eTouchRawUpdate);
|
|
||||||
mInTouchDrag = false;
|
mInTouchDrag = false;
|
||||||
StopTrackingDragGesture(true);
|
StopTrackingDragGesture(true);
|
||||||
}
|
}
|
||||||
@@ -1143,8 +1142,7 @@ nsresult EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||||||
}
|
}
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case eMouseMove:
|
case eMouseMove:
|
||||||
case ePointerMove:
|
case ePointerMove: {
|
||||||
case ePointerRawUpdate: {
|
|
||||||
if (aEvent->mMessage == ePointerMove) {
|
if (aEvent->mMessage == ePointerMove) {
|
||||||
PointerEventHandler::UpdateActivePointerState(mouseEvent,
|
PointerEventHandler::UpdateActivePointerState(mouseEvent,
|
||||||
aTargetContent);
|
aTargetContent);
|
||||||
@@ -4368,22 +4366,20 @@ nsresult EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||||||
// events after they have been processed. When determining if
|
// events after they have been processed. When determining if
|
||||||
// a swipe should occur, we should not prefer the current wheel
|
// a swipe should occur, we should not prefer the current wheel
|
||||||
// transaction.
|
// transaction.
|
||||||
nsIFrame* lastScrollFrame =
|
nsIFrame* lastScrollFrame = WheelTransaction::GetScrollTargetFrame();
|
||||||
WheelTransaction::GetScrollTargetFrame();
|
|
||||||
bool wheelTransactionHandlesInput = false;
|
bool wheelTransactionHandlesInput = false;
|
||||||
if (lastScrollFrame) {
|
if (lastScrollFrame) {
|
||||||
ScrollContainerFrame* scrollContainerFrame =
|
ScrollContainerFrame* scrollContainerFrame = lastScrollFrame->GetScrollTargetFrame();
|
||||||
lastScrollFrame->GetScrollTargetFrame();
|
|
||||||
if (scrollContainerFrame->IsRootScrollFrameOfDocument()) {
|
if (scrollContainerFrame->IsRootScrollFrameOfDocument()) {
|
||||||
// If the current wheel transaction target is the root scroll
|
// If the current wheel transaction target is the root scroll
|
||||||
// frame and is not scrollable on the x-axis, all delta is
|
// frame and is not scrollable on the x-axis, all delta is
|
||||||
// overflown and swipe-to-nav may occur.
|
// overflown and swipe-to-nav may occur.
|
||||||
wheelTransactionHandlesInput = true;
|
wheelTransactionHandlesInput = true;
|
||||||
allDeltaOverflown = !WheelHandlingUtils::CanScrollOn(
|
allDeltaOverflown = !WheelHandlingUtils::CanScrollOn(scrollContainerFrame,
|
||||||
scrollContainerFrame, wheelEvent->mDeltaX, 0.0);
|
wheelEvent->mDeltaX, 0.0);
|
||||||
} else if (WheelHandlingUtils::CanScrollOn(
|
} else if(WheelHandlingUtils::CanScrollOn(scrollContainerFrame,
|
||||||
scrollContainerFrame, wheelEvent->mDeltaX,
|
wheelEvent->mDeltaX,
|
||||||
wheelEvent->mDeltaY)) {
|
wheelEvent->mDeltaY)) {
|
||||||
// If the current wheel transaction target is not the root
|
// If the current wheel transaction target is not the root
|
||||||
// scroll frame, ensure that swipe to nav does not occur if
|
// scroll frame, ensure that swipe to nav does not occur if
|
||||||
// the scroll frame is scrollable on the x or y axis. If the
|
// the scroll frame is scrollable on the x or y axis. If the
|
||||||
@@ -5568,8 +5564,7 @@ void EventStateManager::GeneratePointerEnterExit(EventMessage aMessage,
|
|||||||
/* static */
|
/* static */
|
||||||
void EventStateManager::UpdateLastRefPointOfMouseEvent(
|
void EventStateManager::UpdateLastRefPointOfMouseEvent(
|
||||||
WidgetMouseEvent* aMouseEvent) {
|
WidgetMouseEvent* aMouseEvent) {
|
||||||
if (aMouseEvent->mMessage != ePointerRawUpdate &&
|
if (aMouseEvent->mMessage != eMouseMove &&
|
||||||
aMouseEvent->mMessage != eMouseMove &&
|
|
||||||
aMouseEvent->mMessage != ePointerMove) {
|
aMouseEvent->mMessage != ePointerMove) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5602,8 +5597,7 @@ void EventStateManager::UpdateLastRefPointOfMouseEvent(
|
|||||||
void EventStateManager::ResetPointerToWindowCenterWhilePointerLocked(
|
void EventStateManager::ResetPointerToWindowCenterWhilePointerLocked(
|
||||||
WidgetMouseEvent* aMouseEvent) {
|
WidgetMouseEvent* aMouseEvent) {
|
||||||
MOZ_ASSERT(PointerLockManager::IsLocked());
|
MOZ_ASSERT(PointerLockManager::IsLocked());
|
||||||
if ((aMouseEvent->mMessage != ePointerRawUpdate &&
|
if ((aMouseEvent->mMessage != eMouseMove &&
|
||||||
aMouseEvent->mMessage != eMouseMove &&
|
|
||||||
aMouseEvent->mMessage != ePointerMove) ||
|
aMouseEvent->mMessage != ePointerMove) ||
|
||||||
!aMouseEvent->mWidget) {
|
!aMouseEvent->mWidget) {
|
||||||
return;
|
return;
|
||||||
@@ -5664,7 +5658,6 @@ void EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent) {
|
|||||||
switch (aMouseEvent->mMessage) {
|
switch (aMouseEvent->mMessage) {
|
||||||
case eMouseMove:
|
case eMouseMove:
|
||||||
case ePointerMove:
|
case ePointerMove:
|
||||||
case ePointerRawUpdate:
|
|
||||||
case ePointerDown:
|
case ePointerDown:
|
||||||
case ePointerGotCapture: {
|
case ePointerGotCapture: {
|
||||||
// Get the target content target (mousemove target == mouseover target)
|
// Get the target content target (mousemove target == mouseover target)
|
||||||
|
|||||||
@@ -385,9 +385,7 @@ void PointerEvent::GetCoalescedEvents(
|
|||||||
|
|
||||||
void PointerEvent::EnsureFillingCoalescedEvents(
|
void PointerEvent::EnsureFillingCoalescedEvents(
|
||||||
WidgetPointerEvent& aWidgetEvent) {
|
WidgetPointerEvent& aWidgetEvent) {
|
||||||
if (!aWidgetEvent.IsTrusted() ||
|
if (!aWidgetEvent.IsTrusted() || aWidgetEvent.mMessage != ePointerMove ||
|
||||||
(aWidgetEvent.mMessage != ePointerMove &&
|
|
||||||
aWidgetEvent.mMessage != ePointerRawUpdate) ||
|
|
||||||
!mCoalescedEvents.IsEmpty() ||
|
!mCoalescedEvents.IsEmpty() ||
|
||||||
(aWidgetEvent.mCoalescedWidgetEvents &&
|
(aWidgetEvent.mCoalescedWidgetEvents &&
|
||||||
!aWidgetEvent.mCoalescedWidgetEvents->mEvents.IsEmpty()) ||
|
!aWidgetEvent.mCoalescedWidgetEvents->mEvents.IsEmpty()) ||
|
||||||
|
|||||||
@@ -715,9 +715,7 @@ void PointerEventHandler::InitPointerEventFromTouch(
|
|||||||
WidgetPointerEvent& aPointerEvent, const WidgetTouchEvent& aTouchEvent,
|
WidgetPointerEvent& aPointerEvent, const WidgetTouchEvent& aTouchEvent,
|
||||||
const mozilla::dom::Touch& aTouch) {
|
const mozilla::dom::Touch& aTouch) {
|
||||||
// Use mButton/mButtons only when mButton got a value (from pen input)
|
// Use mButton/mButtons only when mButton got a value (from pen input)
|
||||||
int16_t button = aTouchEvent.mMessage == eTouchRawUpdate ||
|
int16_t button = aTouchEvent.mMessage == eTouchMove ? MouseButton::eNotPressed
|
||||||
aTouchEvent.mMessage == eTouchMove
|
|
||||||
? MouseButton::eNotPressed
|
|
||||||
: aTouchEvent.mButton != MouseButton::eNotPressed
|
: aTouchEvent.mButton != MouseButton::eNotPressed
|
||||||
? aTouchEvent.mButton
|
? aTouchEvent.mButton
|
||||||
: MouseButton::ePrimary;
|
: MouseButton::ePrimary;
|
||||||
@@ -785,9 +783,6 @@ EventMessage PointerEventHandler::ToPointerEventMessage(
|
|||||||
MOZ_ASSERT(aMouseOrTouchEvent);
|
MOZ_ASSERT(aMouseOrTouchEvent);
|
||||||
|
|
||||||
switch (aMouseOrTouchEvent->mMessage) {
|
switch (aMouseOrTouchEvent->mMessage) {
|
||||||
case eMouseRawUpdate:
|
|
||||||
case eTouchRawUpdate:
|
|
||||||
return ePointerRawUpdate;
|
|
||||||
case eMouseMove:
|
case eMouseMove:
|
||||||
return ePointerMove;
|
return ePointerMove;
|
||||||
case eMouseUp:
|
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 */
|
/* static */
|
||||||
void PointerEventHandler::DispatchPointerFromMouseOrTouch(
|
void PointerEventHandler::DispatchPointerFromMouseOrTouch(
|
||||||
PresShell* aShell, nsIFrame* aEventTargetFrame,
|
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
|
// 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
|
// 2. We don't synthesize pointer events for those events that are not
|
||||||
if (!mouseEvent->convertToPointer || mouseEvent->IsSynthesized()) {
|
// dispatched to DOM.
|
||||||
|
if (!mouseEvent->convertToPointer ||
|
||||||
|
!aMouseOrTouchEvent->IsAllowedToDispatchDOMEvent()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,30 +849,6 @@ void PointerEventHandler::DispatchPointerFromMouseOrTouch(
|
|||||||
if (pointerMessage == eVoidEvent) {
|
if (pointerMessage == eVoidEvent) {
|
||||||
return;
|
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);
|
WidgetPointerEvent event(*mouseEvent);
|
||||||
InitPointerEventFromMouse(&event, mouseEvent, pointerMessage);
|
InitPointerEventFromMouse(&event, mouseEvent, pointerMessage);
|
||||||
event.convertToPointer = mouseEvent->convertToPointer = false;
|
event.convertToPointer = mouseEvent->convertToPointer = false;
|
||||||
@@ -963,7 +927,7 @@ void PointerEventHandler::DispatchPointerFromMouseOrTouch(
|
|||||||
// all pointer events should be dispatched to the same target as their
|
// all pointer events should be dispatched to the same target as their
|
||||||
// corresponding touch events. Call PresShell::HandleEvent so that we do
|
// corresponding touch events. Call PresShell::HandleEvent so that we do
|
||||||
// hit test for pointer events.
|
// 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
|
// different document, we cannot track the pointer event target when
|
||||||
// it's removed from the tree.
|
// it's removed from the tree.
|
||||||
PreHandlePointerEventsPreventDefault(&event, aMouseOrTouchEvent);
|
PreHandlePointerEventsPreventDefault(&event, aMouseOrTouchEvent);
|
||||||
@@ -1028,15 +992,9 @@ void PointerEventHandler::NotifyDestroyPresContext(
|
|||||||
bool PointerEventHandler::IsDragAndDropEnabled(WidgetMouseEvent& aEvent) {
|
bool PointerEventHandler::IsDragAndDropEnabled(WidgetMouseEvent& aEvent) {
|
||||||
// We shouldn't start a drag session if the event is synthesized one because
|
// We shouldn't start a drag session if the event is synthesized one because
|
||||||
// aEvent doesn't have enough information for initializing the ePointerCancel.
|
// aEvent doesn't have enough information for initializing the ePointerCancel.
|
||||||
if (aEvent.IsSynthesized()) {
|
if (!aEvent.IsReal()) {
|
||||||
return false;
|
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
|
#ifdef XP_WIN
|
||||||
if (StaticPrefs::dom_w3c_pointer_events_dispatch_by_pointer_messages()) {
|
if (StaticPrefs::dom_w3c_pointer_events_dispatch_by_pointer_messages()) {
|
||||||
// WM_POINTER does not support drag and drop, see bug 1692277
|
// WM_POINTER does not support drag and drop, see bug 1692277
|
||||||
|
|||||||
@@ -270,16 +270,14 @@ class PointerEventHandler final {
|
|||||||
const WidgetPointerEvent& aSourceEvent);
|
const WidgetPointerEvent& aSourceEvent);
|
||||||
|
|
||||||
static bool ShouldGeneratePointerEventFromMouse(WidgetGUIEvent* aEvent) {
|
static bool ShouldGeneratePointerEventFromMouse(WidgetGUIEvent* aEvent) {
|
||||||
return aEvent->mMessage == eMouseRawUpdate ||
|
return aEvent->mMessage == eMouseDown || aEvent->mMessage == eMouseUp ||
|
||||||
aEvent->mMessage == eMouseDown || aEvent->mMessage == eMouseUp ||
|
|
||||||
(aEvent->mMessage == eMouseMove &&
|
(aEvent->mMessage == eMouseMove &&
|
||||||
aEvent->AsMouseEvent()->IsReal()) ||
|
aEvent->AsMouseEvent()->IsReal()) ||
|
||||||
aEvent->mMessage == eMouseExitFromWidget;
|
aEvent->mMessage == eMouseExitFromWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ShouldGeneratePointerEventFromTouch(WidgetGUIEvent* aEvent) {
|
static bool ShouldGeneratePointerEventFromTouch(WidgetGUIEvent* aEvent) {
|
||||||
return aEvent->mMessage == eTouchRawUpdate ||
|
return aEvent->mMessage == eTouchStart || aEvent->mMessage == eTouchMove ||
|
||||||
aEvent->mMessage == eTouchStart || aEvent->mMessage == eTouchMove ||
|
|
||||||
aEvent->mMessage == eTouchEnd || aEvent->mMessage == eTouchCancel ||
|
aEvent->mMessage == eTouchEnd || aEvent->mMessage == eTouchCancel ||
|
||||||
aEvent->mMessage == eTouchPointerCancel;
|
aEvent->mMessage == eTouchPointerCancel;
|
||||||
}
|
}
|
||||||
@@ -292,18 +290,11 @@ class PointerEventHandler final {
|
|||||||
|
|
||||||
static bool IsDragAndDropEnabled(WidgetMouseEvent& aEvent);
|
static bool IsDragAndDropEnabled(WidgetMouseEvent& aEvent);
|
||||||
|
|
||||||
|
private:
|
||||||
// Get proper pointer event message for a mouse or touch event.
|
// Get proper pointer event message for a mouse or touch event.
|
||||||
[[nodiscard]] static EventMessage ToPointerEventMessage(
|
static EventMessage ToPointerEventMessage(
|
||||||
const WidgetGUIEvent* aMouseOrTouchEvent);
|
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.
|
// Set pointer capture of the specified pointer by the element.
|
||||||
static void SetPointerCaptureById(uint32_t aPointerId,
|
static void SetPointerCaptureById(uint32_t aPointerId,
|
||||||
dom::Element* aElement);
|
dom::Element* aElement);
|
||||||
|
|||||||
@@ -100,20 +100,6 @@ skip-if = [
|
|||||||
|
|
||||||
["test_pointermove_isPrimary_subsequent_pens.html"]
|
["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_remove_frame_when_got_pointer_capture.html"]
|
||||||
|
|
||||||
["test_synthesized_touch.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,
|
// element, allowing media control exclusive consumption on these events,
|
||||||
// and preventing the content from handling them.
|
// and preventing the content from handling them.
|
||||||
switch (aVisitor.mEvent->mMessage) {
|
switch (aVisitor.mEvent->mMessage) {
|
||||||
case eTouchRawUpdate:
|
case ePointerDown:
|
||||||
MOZ_FALLTHROUGH_ASSERT(
|
case ePointerUp:
|
||||||
"eTouchRawUpdate event shouldn't be dispatched into the DOM");
|
case eTouchEnd:
|
||||||
// Always prevent touchmove captured in video element from being handled by
|
// Always prevent touchmove captured in video element from being handled by
|
||||||
// content, since we always do that for touchstart.
|
// content, since we always do that for touchstart.
|
||||||
case eTouchMove:
|
case eTouchMove:
|
||||||
case eTouchEnd:
|
|
||||||
case eTouchStart:
|
case eTouchStart:
|
||||||
case ePointerDown:
|
|
||||||
case ePointerUp:
|
|
||||||
case ePointerClick:
|
case ePointerClick:
|
||||||
case eMouseDoubleClick:
|
case eMouseDoubleClick:
|
||||||
case eMouseDown:
|
case eMouseDown:
|
||||||
@@ -4912,13 +4909,9 @@ void HTMLMediaElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
|||||||
aVisitor.mCanHandle = false;
|
aVisitor.mCanHandle = false;
|
||||||
return;
|
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.
|
// dragged.
|
||||||
case eMouseRawUpdate:
|
|
||||||
MOZ_FALLTHROUGH_ASSERT(
|
|
||||||
"eMouseRawUpdate event shouldn't be dispatched into the DOM");
|
|
||||||
case ePointerMove:
|
case ePointerMove:
|
||||||
case ePointerRawUpdate:
|
|
||||||
case eMouseMove: {
|
case eMouseMove: {
|
||||||
nsINode* node =
|
nsINode* node =
|
||||||
nsINode::FromEventTargetOrNull(aVisitor.mEvent->mOriginalTarget);
|
nsINode::FromEventTargetOrNull(aVisitor.mEvent->mOriginalTarget);
|
||||||
|
|||||||
@@ -1489,7 +1489,7 @@ void BrowserChild::ProcessPendingCoalescedMouseDataAndDispatchEvents() {
|
|||||||
// mToBeDispatchedMouseData while dispatching an event.
|
// mToBeDispatchedMouseData while dispatching an event.
|
||||||
|
|
||||||
// We may have some pending coalesced data while dispatch an event and reentry
|
// 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
|
// pending data until we get new mouse events. Get some helps from
|
||||||
// mCoalescedMouseEventFlusher to trigger it.
|
// mCoalescedMouseEventFlusher to trigger it.
|
||||||
mCoalescedMouseEventFlusher->StartObserver();
|
mCoalescedMouseEventFlusher->StartObserver();
|
||||||
@@ -1500,13 +1500,6 @@ void BrowserChild::ProcessPendingCoalescedMouseDataAndDispatchEvents() {
|
|||||||
|
|
||||||
UniquePtr<WidgetMouseEvent> event = data->TakeCoalescedEvent();
|
UniquePtr<WidgetMouseEvent> event = data->TakeCoalescedEvent();
|
||||||
if (event) {
|
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
|
// Dispatch the pending events. Using HandleRealMouseButtonEvent
|
||||||
// to bypass the coalesce handling in RecvRealMouseMoveEvent. Can't use
|
// to bypass the coalesce handling in RecvRealMouseMoveEvent. Can't use
|
||||||
// RecvRealMouseButtonEvent because we may also put some mouse events
|
// RecvRealMouseButtonEvent because we may also put some mouse events
|
||||||
@@ -1563,20 +1556,11 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealMouseMoveEvent(
|
|||||||
CoalescedMouseData* data =
|
CoalescedMouseData* data =
|
||||||
mCoalescedMouseData.GetOrInsertNew(aEvent.pointerId);
|
mCoalescedMouseData.GetOrInsertNew(aEvent.pointerId);
|
||||||
MOZ_ASSERT(data);
|
MOZ_ASSERT(data);
|
||||||
if (data->CanCoalesce(aEvent, aGuid, aInputBlockId,
|
if (data->CanCoalesce(aEvent, aGuid, aInputBlockId)) {
|
||||||
mCoalescedMouseEventFlusher->GetRefreshDriver())) {
|
data->Coalesce(aEvent, aGuid, aInputBlockId);
|
||||||
// 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);
|
|
||||||
mCoalescedMouseEventFlusher->StartObserver();
|
mCoalescedMouseEventFlusher->StartObserver();
|
||||||
HandleMouseRawUpdateEvent(pendingMouseMoveEvent, aGuid, aInputBlockId);
|
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't coalesce current mousemove event. Put the coalesced mousemove data
|
// Can't coalesce current mousemove event. Put the coalesced mousemove data
|
||||||
// with the same pointer id to mToBeDispatchedMouseData, coalesce the
|
// with the same pointer id to mToBeDispatchedMouseData, coalesce the
|
||||||
// current one, and process all pending data in mToBeDispatchedMouseData.
|
// current one, and process all pending data in mToBeDispatchedMouseData.
|
||||||
@@ -1591,50 +1575,17 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealMouseMoveEvent(
|
|||||||
mCoalescedMouseData
|
mCoalescedMouseData
|
||||||
.InsertOrUpdate(aEvent.pointerId, MakeUnique<CoalescedMouseData>())
|
.InsertOrUpdate(aEvent.pointerId, MakeUnique<CoalescedMouseData>())
|
||||||
.get();
|
.get();
|
||||||
// We don't want to dispatch aEvent immediately. However, we need to
|
newData->Coalesce(aEvent, aGuid, aInputBlockId);
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Dispatch all pending mouse events which does NOT include aEvent.
|
// Dispatch all pending mouse events.
|
||||||
ProcessPendingCoalescedMouseDataAndDispatchEvents();
|
ProcessPendingCoalescedMouseDataAndDispatchEvents();
|
||||||
|
|
||||||
mCoalescedMouseEventFlusher->StartObserver();
|
mCoalescedMouseEventFlusher->StartObserver();
|
||||||
// Finally, dispatch eMouseRawUpdate for aEvent right now.
|
} else if (!RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId)) {
|
||||||
HandleMouseRawUpdateEvent(pendingMouseMoveEvent, aGuid, aInputBlockId);
|
|
||||||
return IPC_OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId)) {
|
|
||||||
return IPC_FAIL_NO_REASON(this);
|
return IPC_FAIL_NO_REASON(this);
|
||||||
}
|
}
|
||||||
return IPC_OK();
|
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(
|
mozilla::ipc::IPCResult BrowserChild::RecvRealMouseMoveEventForTests(
|
||||||
const WidgetMouseEvent& aEvent, const ScrollableLayerGuid& aGuid,
|
const WidgetMouseEvent& aEvent, const ScrollableLayerGuid& aGuid,
|
||||||
const uint64_t& aInputBlockId) {
|
const uint64_t& aInputBlockId) {
|
||||||
@@ -1686,16 +1637,9 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealMouseButtonEvent(
|
|||||||
UniquePtr<CoalescedMouseData> dispatchData =
|
UniquePtr<CoalescedMouseData> dispatchData =
|
||||||
MakeUnique<CoalescedMouseData>();
|
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);
|
dispatchData->Coalesce(aEvent, aGuid, aInputBlockId);
|
||||||
|
|
||||||
mToBeDispatchedMouseData.Push(dispatchData.release());
|
mToBeDispatchedMouseData.Push(dispatchData.release());
|
||||||
|
|
||||||
ProcessPendingCoalescedMouseDataAndDispatchEvents();
|
ProcessPendingCoalescedMouseDataAndDispatchEvents();
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
@@ -1886,7 +1830,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealTouchEvent(
|
|||||||
ProcessPendingCoalescedTouchData();
|
ProcessPendingCoalescedTouchData();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aEvent.mMessage != eTouchMove && aEvent.mMessage != eTouchRawUpdate) {
|
if (aEvent.mMessage != eTouchMove) {
|
||||||
sConsecutiveTouchMoveCount = 0;
|
sConsecutiveTouchMoveCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1949,88 +1893,33 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealTouchMoveEvent(
|
|||||||
++sConsecutiveTouchMoveCount;
|
++sConsecutiveTouchMoveCount;
|
||||||
if (mCoalescedTouchMoveEventFlusher) {
|
if (mCoalescedTouchMoveEventFlusher) {
|
||||||
MOZ_ASSERT(aEvent.mMessage == eTouchMove);
|
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() ||
|
if (mCoalescedTouchData.IsEmpty() ||
|
||||||
mCoalescedTouchData.CanCoalesce(aEvent, aGuid, aInputBlockId,
|
mCoalescedTouchData.CanCoalesce(aEvent, aGuid, aInputBlockId,
|
||||||
aApzResponse)) {
|
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,
|
mCoalescedTouchData.Coalesce(aEvent, aGuid, aInputBlockId,
|
||||||
aApzResponse);
|
aApzResponse);
|
||||||
MOZ_ASSERT(!PostponeDispatchingTouchMove());
|
|
||||||
} else {
|
} else {
|
||||||
UniquePtr<WidgetTouchEvent> touchMoveEvent =
|
UniquePtr<WidgetTouchEvent> touchMoveEvent =
|
||||||
mCoalescedTouchData.TakeCoalescedEvent();
|
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,
|
mCoalescedTouchData.Coalesce(aEvent, aGuid, aInputBlockId,
|
||||||
aApzResponse);
|
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,
|
if (!RecvRealTouchEvent(*touchMoveEvent,
|
||||||
mCoalescedTouchData.GetScrollableLayerGuid(),
|
mCoalescedTouchData.GetScrollableLayerGuid(),
|
||||||
mCoalescedTouchData.GetInputBlockId(),
|
mCoalescedTouchData.GetInputBlockId(),
|
||||||
mCoalescedTouchData.GetApzResponse())) {
|
mCoalescedTouchData.GetApzResponse())) {
|
||||||
return IPC_FAIL_NO_REASON(this);
|
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.
|
if (sConsecutiveTouchMoveCount > 1) {
|
||||||
ProcessPendingCoalescedTouchData();
|
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();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2041,30 +1930,6 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealTouchMoveEvent(
|
|||||||
return IPC_OK();
|
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(
|
mozilla::ipc::IPCResult BrowserChild::RecvNormalPriorityRealTouchMoveEvent(
|
||||||
const WidgetTouchEvent& aEvent, const ScrollableLayerGuid& aGuid,
|
const WidgetTouchEvent& aEvent, const ScrollableLayerGuid& aGuid,
|
||||||
const uint64_t& aInputBlockId, const nsEventStatus& aApzResponse) {
|
const uint64_t& aInputBlockId, const nsEventStatus& aApzResponse) {
|
||||||
@@ -4169,27 +4034,6 @@ void BrowserChild::SetDragSession(nsIDragSession* aSession) {
|
|||||||
mDragSession = 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(
|
BrowserChildMessageManager::BrowserChildMessageManager(
|
||||||
BrowserChild* aBrowserChild)
|
BrowserChild* aBrowserChild)
|
||||||
: ContentFrameMessageManager(new nsFrameMessageManager(aBrowserChild)),
|
: ContentFrameMessageManager(new nsFrameMessageManager(aBrowserChild)),
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ class nsIHttpChannel;
|
|||||||
class nsIRequest;
|
class nsIRequest;
|
||||||
class nsISerialEventTarget;
|
class nsISerialEventTarget;
|
||||||
class nsIWebProgress;
|
class nsIWebProgress;
|
||||||
class nsPIDOMWindowInner;
|
|
||||||
class nsWebBrowser;
|
class nsWebBrowser;
|
||||||
class nsDocShellLoadState;
|
class nsDocShellLoadState;
|
||||||
|
|
||||||
@@ -641,36 +640,14 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||||||
// may reentry the event loop and access to the same hashtable. It's
|
// may reentry the event loop and access to the same hashtable. It's
|
||||||
// called when dispatching some mouse events other than mousemove.
|
// called when dispatching some mouse events other than mousemove.
|
||||||
void FlushAllCoalescedMouseData();
|
void FlushAllCoalescedMouseData();
|
||||||
|
|
||||||
void ProcessPendingCoalescedMouseDataAndDispatchEvents();
|
void ProcessPendingCoalescedMouseDataAndDispatchEvents();
|
||||||
|
|
||||||
void ProcessPendingCoalescedTouchData();
|
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,
|
void HandleRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
|
||||||
const ScrollableLayerGuid& aGuid,
|
const ScrollableLayerGuid& aGuid,
|
||||||
const uint64_t& aInputBlockId);
|
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) {
|
void SetCancelContentJSEpoch(int32_t aEpoch) {
|
||||||
mCancelContentJSEpoch = aEpoch;
|
mCancelContentJSEpoch = aEpoch;
|
||||||
}
|
}
|
||||||
@@ -735,13 +712,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||||||
mozilla::ipc::IPCResult RecvDispatchToDropTargetAndResumeEndDragSession(
|
mozilla::ipc::IPCResult RecvDispatchToDropTargetAndResumeEndDragSession(
|
||||||
bool aShouldDrop);
|
bool aShouldDrop);
|
||||||
|
|
||||||
void OnPointerRawUpdateEventListenerAdded(const nsPIDOMWindowInner* aWindow);
|
|
||||||
void OnPointerRawUpdateEventListenerRemoved(
|
|
||||||
const nsPIDOMWindowInner* aWindow);
|
|
||||||
[[nodiscard]] bool HasPointerRawUpdateEventListeners() const {
|
|
||||||
return !!mPointerRawUpdateWindowCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~BrowserChild();
|
virtual ~BrowserChild();
|
||||||
|
|
||||||
@@ -853,8 +823,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||||||
Maybe<CodeNameIndex> mPreviousConsumedKeyDownCode;
|
Maybe<CodeNameIndex> mPreviousConsumedKeyDownCode;
|
||||||
uint32_t mChromeFlags;
|
uint32_t mChromeFlags;
|
||||||
uint32_t mMaxTouchPoints;
|
uint32_t mMaxTouchPoints;
|
||||||
// The number of windows which may have ePointerRawUpdate event listener.
|
|
||||||
uint32_t mPointerRawUpdateWindowCount = 0;
|
|
||||||
layers::LayersId mLayersId;
|
layers::LayersId mLayersId;
|
||||||
CSSRect mUnscaledOuterRect;
|
CSSRect mUnscaledOuterRect;
|
||||||
Maybe<bool> mLayersConnected;
|
Maybe<bool> mLayersConnected;
|
||||||
|
|||||||
@@ -24,21 +24,12 @@ class CoalescedInputData {
|
|||||||
|
|
||||||
UniquePtr<InputEventType> mCoalescedInputEvent;
|
UniquePtr<InputEventType> mCoalescedInputEvent;
|
||||||
ScrollableLayerGuid mGuid;
|
ScrollableLayerGuid mGuid;
|
||||||
uint64_t mInputBlockId = 0;
|
uint64_t mInputBlockId;
|
||||||
uint32_t mGeneration = 0;
|
|
||||||
|
|
||||||
void AdvanceGeneration() {
|
|
||||||
if (!IsEmpty()) {
|
|
||||||
mGeneration++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CoalescedInputData() = default;
|
CoalescedInputData() : mInputBlockId(0) {}
|
||||||
|
|
||||||
void RetrieveDataFrom(CoalescedInputData& aSource) {
|
void RetrieveDataFrom(CoalescedInputData& aSource) {
|
||||||
aSource.AdvanceGeneration();
|
|
||||||
AdvanceGeneration();
|
|
||||||
mCoalescedInputEvent = std::move(aSource.mCoalescedInputEvent);
|
mCoalescedInputEvent = std::move(aSource.mCoalescedInputEvent);
|
||||||
mGuid = aSource.mGuid;
|
mGuid = aSource.mGuid;
|
||||||
mInputBlockId = aSource.mInputBlockId;
|
mInputBlockId = aSource.mInputBlockId;
|
||||||
@@ -51,23 +42,12 @@ class CoalescedInputData {
|
|||||||
const uint64_t& aInputBlockId);
|
const uint64_t& aInputBlockId);
|
||||||
|
|
||||||
UniquePtr<InputEventType> TakeCoalescedEvent() {
|
UniquePtr<InputEventType> TakeCoalescedEvent() {
|
||||||
AdvanceGeneration();
|
|
||||||
return std::move(mCoalescedInputEvent);
|
return std::move(mCoalescedInputEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollableLayerGuid GetScrollableLayerGuid() { return mGuid; }
|
ScrollableLayerGuid GetScrollableLayerGuid() { return mGuid; }
|
||||||
|
|
||||||
uint64_t GetInputBlockId() { return mInputBlockId; }
|
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 {
|
class CoalescedInputFlusher : public nsARefreshObserver {
|
||||||
@@ -81,17 +61,12 @@ class CoalescedInputFlusher : public nsARefreshObserver {
|
|||||||
void StartObserver();
|
void StartObserver();
|
||||||
void RemoveObserver();
|
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:
|
protected:
|
||||||
virtual ~CoalescedInputFlusher();
|
virtual ~CoalescedInputFlusher();
|
||||||
|
|
||||||
|
nsRefreshDriver* GetRefreshDriver();
|
||||||
|
|
||||||
BrowserChild* mBrowserChild;
|
BrowserChild* mBrowserChild;
|
||||||
// A refresh driver which this instance waits for the next refresh of.
|
|
||||||
RefPtr<nsRefreshDriver> mRefreshDriver;
|
RefPtr<nsRefreshDriver> mRefreshDriver;
|
||||||
};
|
};
|
||||||
} // namespace mozilla::dom
|
} // namespace mozilla::dom
|
||||||
|
|||||||
@@ -58,29 +58,17 @@ void CoalescedMouseData::Coalesce(const WidgetMouseEvent& aEvent,
|
|||||||
|
|
||||||
bool CoalescedMouseData::CanCoalesce(const WidgetMouseEvent& aEvent,
|
bool CoalescedMouseData::CanCoalesce(const WidgetMouseEvent& aEvent,
|
||||||
const ScrollableLayerGuid& aGuid,
|
const ScrollableLayerGuid& aGuid,
|
||||||
const uint64_t& aInputBlockId,
|
const uint64_t& aInputBlockId) {
|
||||||
const nsRefreshDriver* aRefreshDriver) {
|
|
||||||
MOZ_ASSERT(aEvent.mMessage == eMouseMove);
|
MOZ_ASSERT(aEvent.mMessage == eMouseMove);
|
||||||
if (!mCoalescedInputEvent) {
|
return !mCoalescedInputEvent ||
|
||||||
return true;
|
(!mCoalescedInputEvent->mFlags.mIsSynthesizedForTests &&
|
||||||
}
|
!aEvent.mFlags.mIsSynthesizedForTests &&
|
||||||
if (mCoalescedInputEvent->mFlags.mIsSynthesizedForTests !=
|
mCoalescedInputEvent->mModifiers == aEvent.mModifiers &&
|
||||||
aEvent.mFlags.mIsSynthesizedForTests ||
|
mCoalescedInputEvent->mInputSource == aEvent.mInputSource &&
|
||||||
mCoalescedInputEvent->mModifiers != aEvent.mModifiers ||
|
mCoalescedInputEvent->pointerId == aEvent.pointerId &&
|
||||||
mCoalescedInputEvent->mInputSource != aEvent.mInputSource ||
|
mCoalescedInputEvent->mButton == aEvent.mButton &&
|
||||||
mCoalescedInputEvent->pointerId != aEvent.pointerId ||
|
mCoalescedInputEvent->mButtons == aEvent.mButtons && mGuid == aGuid &&
|
||||||
mCoalescedInputEvent->mButton != aEvent.mButton ||
|
mInputBlockId == aInputBlockId);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CoalescedMouseMoveFlusher::CoalescedMouseMoveFlusher(
|
CoalescedMouseMoveFlusher::CoalescedMouseMoveFlusher(
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ class CoalescedMouseData final : public CoalescedInputData<WidgetMouseEvent> {
|
|||||||
|
|
||||||
bool CanCoalesce(const WidgetMouseEvent& aEvent,
|
bool CanCoalesce(const WidgetMouseEvent& aEvent,
|
||||||
const ScrollableLayerGuid& aGuid,
|
const ScrollableLayerGuid& aGuid,
|
||||||
const uint64_t& aInputBlockId,
|
const uint64_t& aInputBlockId);
|
||||||
const nsRefreshDriver* aRefreshDriver);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CoalescedMouseMoveFlusher final : public CoalescedInputFlusher {
|
class CoalescedMouseMoveFlusher final : public CoalescedInputFlusher {
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ void CoalescedTouchData::CreateCoalescedTouchEvent(
|
|||||||
PointerEventHandler::InitPointerEventFromTouch(*event, aEvent, *touch);
|
PointerEventHandler::InitPointerEventFromTouch(*event, aEvent, *touch);
|
||||||
event->mFlags.mBubbles = false;
|
event->mFlags.mBubbles = false;
|
||||||
event->mFlags.mCancelable = 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->mModifiers == aEvent.mModifiers);
|
||||||
MOZ_ASSERT(mCoalescedInputEvent->mInputSource == aEvent.mInputSource);
|
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
|
// 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
|
// The checks in CoalescedTouchData::CanCoalesce ensure it should never
|
||||||
// be null.
|
// be null.
|
||||||
MOZ_ASSERT(sameTouch);
|
MOZ_ASSERT(sameTouch);
|
||||||
@@ -58,7 +58,6 @@ void CoalescedTouchData::Coalesce(const WidgetTouchEvent& aEvent,
|
|||||||
MOZ_ASSERT(!sameTouch->mCoalescedWidgetEvents->mEvents.IsEmpty());
|
MOZ_ASSERT(!sameTouch->mCoalescedWidgetEvents->mEvents.IsEmpty());
|
||||||
if (!sameTouch->Equals(touch)) {
|
if (!sameTouch->Equals(touch)) {
|
||||||
sameTouch->SetSameAs(touch);
|
sameTouch->SetSameAs(touch);
|
||||||
sameTouch->convertToPointerRawUpdate = touch->convertToPointerRawUpdate;
|
|
||||||
WidgetPointerEvent* event =
|
WidgetPointerEvent* event =
|
||||||
sameTouch->mCoalescedWidgetEvents->mEvents.AppendElement(
|
sameTouch->mCoalescedWidgetEvents->mEvents.AppendElement(
|
||||||
WidgetPointerEvent(aEvent.IsTrusted(), ePointerMove,
|
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,
|
bool CoalescedTouchData::CanCoalesce(const WidgetTouchEvent& aEvent,
|
||||||
const ScrollableLayerGuid& aGuid,
|
const ScrollableLayerGuid& aGuid,
|
||||||
const uint64_t& aInputBlockId,
|
const uint64_t& aInputBlockId,
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ class CoalescedTouchData final : public CoalescedInputData<WidgetTouchEvent> {
|
|||||||
|
|
||||||
nsEventStatus GetApzResponse() { return mApzResponse; }
|
nsEventStatus GetApzResponse() { return mApzResponse; }
|
||||||
|
|
||||||
void NotifyTouchRawUpdateOfHandled(const WidgetTouchEvent& aEvent);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Touch* GetTouch(int32_t aIdentifier);
|
Touch* GetTouch(int32_t aIdentifier);
|
||||||
|
|
||||||
|
|||||||
@@ -1857,8 +1857,6 @@ let interfaceNamesInGlobalScope = [
|
|||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
{ name: "onpointerover", insecureContext: true },
|
{ name: "onpointerover", insecureContext: true },
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// 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 },
|
{ name: "onpointerup", insecureContext: true },
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
{ name: "onpopstate", insecureContext: true },
|
{ name: "onpopstate", insecureContext: true },
|
||||||
|
|||||||
@@ -116,8 +116,6 @@ interface mixin GlobalEventHandlers {
|
|||||||
attribute EventHandler onpointerover;
|
attribute EventHandler onpointerover;
|
||||||
attribute EventHandler onpointerenter;
|
attribute EventHandler onpointerenter;
|
||||||
attribute EventHandler onpointerleave;
|
attribute EventHandler onpointerleave;
|
||||||
[SecureContext, Pref="dom.event.pointer.rawupdate.enabled"]
|
|
||||||
attribute EventHandler onpointerrawupdate;
|
|
||||||
attribute EventHandler ongotpointercapture;
|
attribute EventHandler ongotpointercapture;
|
||||||
attribute EventHandler onlostpointercapture;
|
attribute EventHandler onlostpointercapture;
|
||||||
|
|
||||||
|
|||||||
@@ -336,9 +336,6 @@ void APZEventState::ProcessTouchEvent(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eTouchRawUpdate:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
MOZ_ASSERT_UNREACHABLE("Unknown touch event type");
|
MOZ_ASSERT_UNREACHABLE("Unknown touch event type");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -7069,8 +7069,6 @@ void PresShell::RecordPointerLocation(WidgetGUIEvent* aEvent) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ePointerMove:
|
case ePointerMove:
|
||||||
case ePointerRawUpdate:
|
|
||||||
case eMouseRawUpdate:
|
|
||||||
if (!aEvent->AsMouseEvent()->IsReal()) {
|
if (!aEvent->AsMouseEvent()->IsReal()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -7155,7 +7153,6 @@ PresShell* PresShell::GetShellForEventTarget(nsIFrame* aFrame,
|
|||||||
PresShell* PresShell::GetShellForTouchEvent(WidgetGUIEvent* aEvent) {
|
PresShell* PresShell::GetShellForTouchEvent(WidgetGUIEvent* aEvent) {
|
||||||
switch (aEvent->mMessage) {
|
switch (aEvent->mMessage) {
|
||||||
case eTouchMove:
|
case eTouchMove:
|
||||||
case eTouchRawUpdate:
|
|
||||||
case eTouchCancel:
|
case eTouchCancel:
|
||||||
case eTouchEnd: {
|
case eTouchEnd: {
|
||||||
// get the correct shell to dispatch to
|
// get the correct shell to dispatch to
|
||||||
@@ -7307,7 +7304,6 @@ nsresult PresShell::HandleEvent(nsIFrame* aFrameForPresShell,
|
|||||||
if (mPresContext) {
|
if (mPresContext) {
|
||||||
switch (aGUIEvent->mMessage) {
|
switch (aGUIEvent->mMessage) {
|
||||||
case eMouseMove:
|
case eMouseMove:
|
||||||
case eMouseRawUpdate:
|
|
||||||
if (!aGUIEvent->AsMouseEvent()->IsReal()) {
|
if (!aGUIEvent->AsMouseEvent()->IsReal()) {
|
||||||
break;
|
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);
|
EventHandler eventHandler(*this);
|
||||||
return eventHandler.HandleEvent(weakFrameForPresShell, aGUIEvent,
|
return eventHandler.HandleEvent(weakFrameForPresShell, aGUIEvent,
|
||||||
aDontRetargetEvents, aEventStatus);
|
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(
|
bool PresShell::EventHandler::UpdateFocusSequenceNumber(
|
||||||
nsIFrame* aFrameForPresShell, uint64_t aEventFocusSequenceNumber) {
|
nsIFrame* aFrameForPresShell, uint64_t aEventFocusSequenceNumber) {
|
||||||
uint64_t focusSequenceNumber;
|
uint64_t focusSequenceNumber;
|
||||||
@@ -7602,24 +7485,6 @@ nsresult PresShell::EventHandler::HandleEventUsingCoordinates(
|
|||||||
return NS_OK;
|
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 eventTargetData =
|
||||||
EventTargetDataWithCapture::QueryEventTargetUsingCoordinates(
|
EventTargetDataWithCapture::QueryEventTargetUsingCoordinates(
|
||||||
*this, aWeakFrameForPresShell,
|
*this, aWeakFrameForPresShell,
|
||||||
@@ -7744,12 +7609,6 @@ PresShell::EventHandler::EventTargetDataWithCapture::EventTargetDataWithCapture(
|
|||||||
if (GetDocument() && aGUIEvent->mClass == eTouchEventClass) {
|
if (GetDocument() && aGUIEvent->mClass == eTouchEventClass) {
|
||||||
PointerLockManager::Unlock("TouchEvent");
|
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);
|
aEventHandler.MaybeFlushThrottledStyles(aWeakFrameForPresShell);
|
||||||
// Previously, MaybeFlushThrottledStyles() recomputed the closest ancestor
|
// Previously, MaybeFlushThrottledStyles() recomputed the closest ancestor
|
||||||
// frame for view of mPresShell if it's reframed. Therefore, we should keep
|
// 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,
|
aPointerCapturingElement, aGUIEvent, aDontRetargetEvents, aEventStatus,
|
||||||
getter_AddRefs(mouseOrTouchEventTargetContent));
|
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
|
// If the target frame is alive, the caller should keep handling the event
|
||||||
// unless event target frame is destroyed.
|
// unless event target frame is destroyed.
|
||||||
if (weakTargetFrame.IsAlive() && weakFrame.IsAlive()) {
|
if (weakTargetFrame.IsAlive() && weakFrame.IsAlive()) {
|
||||||
aEventTargetData->UpdateTouchEventTarget(aGUIEvent);
|
aEventTargetData->UpdateTouchEventTarget(aGUIEvent);
|
||||||
return maybeCallerCanHandleEvent;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
presShell->FlushPendingNotifications(FlushType::Layout);
|
presShell->FlushPendingNotifications(FlushType::Layout);
|
||||||
@@ -8101,7 +7956,7 @@ bool PresShell::EventHandler::DispatchPrecedingPointerEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
aEventTargetData->UpdateTouchEventTarget(aGUIEvent);
|
aEventTargetData->UpdateTouchEventTarget(aGUIEvent);
|
||||||
return maybeCallerCanHandleEvent;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -8521,16 +8376,6 @@ bool PresShell::EventHandler::MaybeDiscardOrDelayMouseEvent(
|
|||||||
MOZ_ASSERT(aFrameToHandleEvent);
|
MOZ_ASSERT(aFrameToHandleEvent);
|
||||||
MOZ_ASSERT(aGUIEvent);
|
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()) {
|
if (!aGUIEvent->IsMouseEventClassOrHasClickRelatedPointerEvent()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -9232,11 +9077,6 @@ bool PresShell::EventHandler::PrepareToDispatchEvent(
|
|||||||
MaybeHandleKeyboardEventBeforeDispatch(keyboardEvent);
|
MaybeHandleKeyboardEventBeforeDispatch(keyboardEvent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case eMouseRawUpdate:
|
|
||||||
MOZ_ASSERT_UNREACHABLE(
|
|
||||||
"eMouseRawUpdate shouldn't be handled as a DOM event");
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case eMouseMove: {
|
case eMouseMove: {
|
||||||
bool allowCapture = EventStateManager::GetActiveEventStateManager() &&
|
bool allowCapture = EventStateManager::GetActiveEventStateManager() &&
|
||||||
GetPresContext() &&
|
GetPresContext() &&
|
||||||
@@ -9291,10 +9131,6 @@ bool PresShell::EventHandler::PrepareToDispatchEvent(
|
|||||||
return mPresShell->mTouchManager.PreHandleEvent(
|
return mPresShell->mTouchManager.PreHandleEvent(
|
||||||
aEvent, aEventStatus, *aTouchIsNew,
|
aEvent, aEventStatus, *aTouchIsNew,
|
||||||
mPresShell->mCurrentEventTarget.mContent);
|
mPresShell->mCurrentEventTarget.mContent);
|
||||||
case eTouchRawUpdate:
|
|
||||||
MOZ_ASSERT_UNREACHABLE(
|
|
||||||
"eTouchRawUpdate shouldn't be handled as a DOM event");
|
|
||||||
return false;
|
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -9336,10 +9172,6 @@ void PresShell::EventHandler::FinalizeHandlingEvent(
|
|||||||
// reset the capturing content now that the mouse button is up
|
// reset the capturing content now that the mouse button is up
|
||||||
PresShell::ReleaseCapturingContent();
|
PresShell::ReleaseCapturingContent();
|
||||||
break;
|
break;
|
||||||
case eMouseRawUpdate:
|
|
||||||
MOZ_ASSERT_UNREACHABLE(
|
|
||||||
"eMouseRawUpdate shouldn't be handled as a DOM event");
|
|
||||||
break;
|
|
||||||
case eMouseMove:
|
case eMouseMove:
|
||||||
PresShell::AllowMouseCapture(false);
|
PresShell::AllowMouseCapture(false);
|
||||||
break;
|
break;
|
||||||
@@ -9369,10 +9201,6 @@ void PresShell::EventHandler::FinalizeHandlingEvent(
|
|||||||
mPresShell->mTouchManager.PostHandleEvent(aEvent, aStatus);
|
mPresShell->mTouchManager.PostHandleEvent(aEvent, aStatus);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eTouchRawUpdate:
|
|
||||||
MOZ_ASSERT_UNREACHABLE(
|
|
||||||
"eTouchRawUpdate shouldn't be handled as a DOM event");
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -9485,10 +9313,6 @@ void PresShell::EventHandler::RecordEventPreparationPerformance(
|
|||||||
nsPresContext::InteractionType::ClickInteraction, aEvent->mTimeStamp);
|
nsPresContext::InteractionType::ClickInteraction, aEvent->mTimeStamp);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case eMouseRawUpdate:
|
|
||||||
MOZ_ASSERT_UNREACHABLE(
|
|
||||||
"eMouseRawUpdate shouldn't be handled as a DOM event");
|
|
||||||
break;
|
|
||||||
case eMouseMove:
|
case eMouseMove:
|
||||||
GetPresContext()->RecordInteractionTime(
|
GetPresContext()->RecordInteractionTime(
|
||||||
nsPresContext::InteractionType::MouseMoveInteraction,
|
nsPresContext::InteractionType::MouseMoveInteraction,
|
||||||
@@ -9669,7 +9493,6 @@ nsresult PresShell::EventHandler::DispatchEventToDOM(
|
|||||||
void PresShell::EventHandler::DispatchTouchEventToDOM(
|
void PresShell::EventHandler::DispatchTouchEventToDOM(
|
||||||
WidgetEvent* aEvent, nsEventStatus* aEventStatus,
|
WidgetEvent* aEvent, nsEventStatus* aEventStatus,
|
||||||
nsPresShellEventCB* aEventCB, bool aTouchIsNew) {
|
nsPresShellEventCB* aEventCB, bool aTouchIsNew) {
|
||||||
MOZ_ASSERT(aEvent->mMessage != eTouchRawUpdate);
|
|
||||||
// calling preventDefault on touchstart or the first touchmove for a
|
// calling preventDefault on touchstart or the first touchmove for a
|
||||||
// point prevents mouse events. calling it on the touchend should
|
// point prevents mouse events. calling it on the touchend should
|
||||||
// prevent click dispatching.
|
// prevent click dispatching.
|
||||||
|
|||||||
@@ -1996,15 +1996,6 @@ class PresShell final : public nsStubDocumentObserver,
|
|||||||
// Utility method to restore the root scrollframe state
|
// Utility method to restore the root scrollframe state
|
||||||
void RestoreRootScrollPosition();
|
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();
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY void MaybeReleaseCapturingContent();
|
||||||
|
|
||||||
class DelayedEvent {
|
class DelayedEvent {
|
||||||
|
|||||||
@@ -303,9 +303,6 @@ bool TouchManager::PreHandleEvent(WidgetEvent* aEvent, nsEventStatus* aStatus,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eTouchRawUpdate:
|
|
||||||
MOZ_ASSERT_UNREACHABLE("eTouchRawUpdate shouldn't be handled as a touch");
|
|
||||||
break;
|
|
||||||
case eTouchMove: {
|
case eTouchMove: {
|
||||||
// Check for touches that changed. Mark them add to queue
|
// Check for touches that changed. Mark them add to queue
|
||||||
WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
|
WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
|
||||||
@@ -451,9 +448,6 @@ bool TouchManager::PreHandleEvent(WidgetEvent* aEvent, nsEventStatus* aStatus,
|
|||||||
void TouchManager::PostHandleEvent(const WidgetEvent* aEvent,
|
void TouchManager::PostHandleEvent(const WidgetEvent* aEvent,
|
||||||
const nsEventStatus* aStatus) {
|
const nsEventStatus* aStatus) {
|
||||||
switch (aEvent->mMessage) {
|
switch (aEvent->mMessage) {
|
||||||
case eTouchRawUpdate:
|
|
||||||
MOZ_ASSERT_UNREACHABLE("eTouchRawUpdate shouldn't be handled as a touch");
|
|
||||||
break;
|
|
||||||
case eTouchMove: {
|
case eTouchMove: {
|
||||||
if (sSingleTouchStartTimeStamp.IsNull()) {
|
if (sSingleTouchStartTimeStamp.IsNull()) {
|
||||||
break;
|
break;
|
||||||
@@ -565,8 +559,7 @@ bool TouchManager::ShouldConvertTouchToPointer(const Touch* aTouch,
|
|||||||
// We don't want to fire duplicated pointerdown.
|
// We don't want to fire duplicated pointerdown.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case eTouchMove:
|
case eTouchMove: {
|
||||||
case eTouchRawUpdate: {
|
|
||||||
return !aTouch->Equals(info.mTouch);
|
return !aTouch->Equals(info.mTouch);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -2820,12 +2820,6 @@
|
|||||||
value: true
|
value: true
|
||||||
mirror: always
|
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
|
# 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.
|
# events that occur in a given wheel transaction have the same event target.
|
||||||
- name: dom.event.wheel-event-groups.enabled
|
- name: dom.event.wheel-event-groups.enabled
|
||||||
|
|||||||
@@ -1,4 +1,19 @@
|
|||||||
[idlharness.https.window.html]
|
[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]
|
[PointerEvent interface: attribute persistentDeviceId]
|
||||||
expected: FAIL
|
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]
|
[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]
|
["pointermove" and its preceding boundary events should be fired on parent if "pointerrawupdate" event listener removes its document]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
[pointerevent_pointerrawupdate_in_pointerlock.https.html]
|
[pointerevent_pointerrawupdate_in_pointerlock.https.html]
|
||||||
max-asserts: 1 # in PointerEventHandler::DispatchPointerFromMouseOrTouch
|
|
||||||
expected:
|
expected:
|
||||||
if (os == "win") and debug and (processor == "x86_64"): [OK, TIMEOUT]
|
if (os == "win") and debug and (processor == "x86_64"): [OK, TIMEOUT]
|
||||||
if (os == "win") and debug and (processor == "x86"): 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 fission: [OK, TIMEOUT]
|
||||||
if (os == "linux") and debug and not fission: [OK, ERROR, TIMEOUT]
|
if (os == "linux") and debug and not fission: [OK, ERROR, TIMEOUT]
|
||||||
if (os == "linux") and not debug: [OK, 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;
|
break;
|
||||||
case ePointerEventClass:
|
case ePointerEventClass:
|
||||||
mFlags.mCancelable =
|
mFlags.mCancelable =
|
||||||
(mMessage != ePointerRawUpdate && mMessage != ePointerEnter &&
|
(mMessage != ePointerEnter && mMessage != ePointerLeave &&
|
||||||
mMessage != ePointerLeave && mMessage != ePointerCancel &&
|
mMessage != ePointerCancel && mMessage != ePointerGotCapture &&
|
||||||
mMessage != ePointerGotCapture && mMessage != ePointerLostCapture);
|
mMessage != ePointerLostCapture);
|
||||||
mFlags.mBubbles =
|
mFlags.mBubbles =
|
||||||
(mMessage != ePointerEnter && mMessage != ePointerLeave);
|
(mMessage != ePointerEnter && mMessage != ePointerLeave);
|
||||||
break;
|
break;
|
||||||
@@ -931,12 +931,12 @@ class WidgetEvent : public WidgetEventTime {
|
|||||||
case ePointerEventClass:
|
case ePointerEventClass:
|
||||||
// All pointer events are composed
|
// All pointer events are composed
|
||||||
mFlags.mComposed =
|
mFlags.mComposed =
|
||||||
mMessage == ePointerRawUpdate || mMessage == ePointerMove ||
|
|
||||||
mMessage == ePointerClick || mMessage == ePointerAuxClick ||
|
mMessage == ePointerClick || mMessage == ePointerAuxClick ||
|
||||||
mMessage == eContextMenu || mMessage == ePointerDown ||
|
mMessage == eContextMenu || mMessage == ePointerDown ||
|
||||||
mMessage == ePointerUp || mMessage == ePointerCancel ||
|
mMessage == ePointerMove || mMessage == ePointerUp ||
|
||||||
mMessage == ePointerOver || mMessage == ePointerOut ||
|
mMessage == ePointerCancel || mMessage == ePointerOver ||
|
||||||
mMessage == ePointerGotCapture || mMessage == ePointerLostCapture;
|
mMessage == ePointerOut || mMessage == ePointerGotCapture ||
|
||||||
|
mMessage == ePointerLostCapture;
|
||||||
break;
|
break;
|
||||||
case eTouchEventClass:
|
case eTouchEventClass:
|
||||||
// All touch events are composed
|
// All touch events are composed
|
||||||
@@ -1011,7 +1011,6 @@ class WidgetEvent : public WidgetEventTime {
|
|||||||
aEventTypeArg.EqualsLiteral("pointerout") ||
|
aEventTypeArg.EqualsLiteral("pointerout") ||
|
||||||
aEventTypeArg.EqualsLiteral("pointerenter") ||
|
aEventTypeArg.EqualsLiteral("pointerenter") ||
|
||||||
aEventTypeArg.EqualsLiteral("pointerleave") ||
|
aEventTypeArg.EqualsLiteral("pointerleave") ||
|
||||||
aEventTypeArg.EqualsLiteral("pointerrawupdate") ||
|
|
||||||
aEventTypeArg.EqualsLiteral("gotpointercapture") ||
|
aEventTypeArg.EqualsLiteral("gotpointercapture") ||
|
||||||
aEventTypeArg.EqualsLiteral("lostpointercapture") ||
|
aEventTypeArg.EqualsLiteral("lostpointercapture") ||
|
||||||
// touch events
|
// touch events
|
||||||
|
|||||||
@@ -93,14 +93,6 @@ NS_EVENT_MESSAGE(eMouseEnter)
|
|||||||
NS_EVENT_MESSAGE(eMouseLeave)
|
NS_EVENT_MESSAGE(eMouseLeave)
|
||||||
NS_EVENT_MESSAGE(eMouseTouchDrag)
|
NS_EVENT_MESSAGE(eMouseTouchDrag)
|
||||||
NS_EVENT_MESSAGE(eMouseLongTap)
|
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(eMouseExploreByTouch)
|
||||||
NS_EVENT_MESSAGE_FIRST_LAST(eMouseEvent, eMouseMove, eMouseExploreByTouch)
|
NS_EVENT_MESSAGE_FIRST_LAST(eMouseEvent, eMouseMove, eMouseExploreByTouch)
|
||||||
|
|
||||||
@@ -108,13 +100,6 @@ NS_EVENT_MESSAGE(ePointerClick)
|
|||||||
NS_EVENT_MESSAGE(ePointerAuxClick)
|
NS_EVENT_MESSAGE(ePointerAuxClick)
|
||||||
|
|
||||||
// Pointer spec events
|
// 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(ePointerMove)
|
||||||
NS_EVENT_MESSAGE(ePointerUp)
|
NS_EVENT_MESSAGE(ePointerUp)
|
||||||
NS_EVENT_MESSAGE(ePointerDown)
|
NS_EVENT_MESSAGE(ePointerDown)
|
||||||
@@ -123,7 +108,6 @@ NS_EVENT_MESSAGE(ePointerOut)
|
|||||||
NS_EVENT_MESSAGE(ePointerEnter)
|
NS_EVENT_MESSAGE(ePointerEnter)
|
||||||
NS_EVENT_MESSAGE(ePointerLeave)
|
NS_EVENT_MESSAGE(ePointerLeave)
|
||||||
NS_EVENT_MESSAGE(ePointerCancel)
|
NS_EVENT_MESSAGE(ePointerCancel)
|
||||||
NS_EVENT_MESSAGE(ePointerRawUpdate)
|
|
||||||
NS_EVENT_MESSAGE(ePointerGotCapture)
|
NS_EVENT_MESSAGE(ePointerGotCapture)
|
||||||
NS_EVENT_MESSAGE(ePointerLostCapture)
|
NS_EVENT_MESSAGE(ePointerLostCapture)
|
||||||
NS_EVENT_MESSAGE_FIRST_LAST(ePointerEvent, ePointerMove, ePointerLostCapture)
|
NS_EVENT_MESSAGE_FIRST_LAST(ePointerEvent, ePointerMove, ePointerLostCapture)
|
||||||
@@ -448,14 +432,6 @@ NS_EVENT_MESSAGE(eTouchMove)
|
|||||||
NS_EVENT_MESSAGE(eTouchEnd)
|
NS_EVENT_MESSAGE(eTouchEnd)
|
||||||
NS_EVENT_MESSAGE(eTouchCancel)
|
NS_EVENT_MESSAGE(eTouchCancel)
|
||||||
NS_EVENT_MESSAGE(eTouchPointerCancel)
|
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
|
// Pointerlock DOM API
|
||||||
NS_EVENT_MESSAGE(ePointerLockChange)
|
NS_EVENT_MESSAGE(ePointerLockChange)
|
||||||
|
|||||||
@@ -43,22 +43,22 @@ class WidgetPointerEventHolder final {
|
|||||||
|
|
||||||
class WidgetPointerHelper {
|
class WidgetPointerHelper {
|
||||||
public:
|
public:
|
||||||
uint32_t pointerId = 0;
|
uint32_t pointerId;
|
||||||
int32_t tiltX = 0;
|
int32_t tiltX;
|
||||||
int32_t tiltY = 0;
|
int32_t tiltY;
|
||||||
int32_t twist = 0;
|
int32_t twist;
|
||||||
float tangentialPressure = 0.0f;
|
float tangentialPressure;
|
||||||
bool convertToPointer = true;
|
bool convertToPointer;
|
||||||
// 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;
|
|
||||||
RefPtr<WidgetPointerEventHolder> mCoalescedWidgetEvents;
|
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,
|
WidgetPointerHelper(uint32_t aPointerId, uint32_t aTiltX, uint32_t aTiltY,
|
||||||
uint32_t aTwist = 0, float aTangentialPressure = 0)
|
uint32_t aTwist = 0, float aTangentialPressure = 0)
|
||||||
: pointerId(aPointerId),
|
: pointerId(aPointerId),
|
||||||
@@ -108,7 +108,6 @@ class WidgetPointerHelper {
|
|||||||
twist = aEvent.twist;
|
twist = aEvent.twist;
|
||||||
tangentialPressure = aEvent.tangentialPressure;
|
tangentialPressure = aEvent.tangentialPressure;
|
||||||
convertToPointer = aEvent.convertToPointer;
|
convertToPointer = aEvent.convertToPointer;
|
||||||
convertToPointerRawUpdate = aEvent.convertToPointerRawUpdate;
|
|
||||||
if (aCopyCoalescedEvents) {
|
if (aCopyCoalescedEvents) {
|
||||||
mCoalescedWidgetEvents = aEvent.mCoalescedWidgetEvents;
|
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
|
* Returns true if the event is a real mouse event. Otherwise, i.e., it's
|
||||||
* a synthesized event by scroll or something, returns false.
|
* a synthesized event by scroll or something, returns false.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool IsReal() const { return mReason == eReal; }
|
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; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if middle click paste is enabled.
|
* Returns true if middle click paste is enabled.
|
||||||
|
|||||||
@@ -151,23 +151,13 @@ class WidgetTouchEvent final : public WidgetInputEvent {
|
|||||||
|
|
||||||
MOZ_COUNTED_DEFAULT_CTOR(WidgetTouchEvent)
|
MOZ_COUNTED_DEFAULT_CTOR(WidgetTouchEvent)
|
||||||
|
|
||||||
enum class CloneTouches : bool { No, Yes };
|
WidgetTouchEvent(const WidgetTouchEvent& aOther)
|
||||||
WidgetTouchEvent(const WidgetTouchEvent& aOther,
|
|
||||||
CloneTouches aCloneTouches = CloneTouches::No)
|
|
||||||
: WidgetInputEvent(aOther.IsTrusted(), aOther.mMessage, aOther.mWidget,
|
: WidgetInputEvent(aOther.IsTrusted(), aOther.mMessage, aOther.mWidget,
|
||||||
eTouchEventClass) {
|
eTouchEventClass) {
|
||||||
MOZ_COUNT_CTOR(WidgetTouchEvent);
|
MOZ_COUNT_CTOR(WidgetTouchEvent);
|
||||||
mModifiers = aOther.mModifiers;
|
mModifiers = aOther.mModifiers;
|
||||||
mTimeStamp = aOther.mTimeStamp;
|
mTimeStamp = aOther.mTimeStamp;
|
||||||
if (static_cast<bool>(aCloneTouches)) {
|
mTouches.AppendElements(aOther.mTouches);
|
||||||
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);
|
|
||||||
}
|
|
||||||
mInputSource = aOther.mInputSource;
|
mInputSource = aOther.mInputSource;
|
||||||
mButton = aOther.mButton;
|
mButton = aOther.mButton;
|
||||||
mButtons = aOther.mButtons;
|
mButtons = aOther.mButtons;
|
||||||
@@ -223,20 +213,6 @@ class WidgetTouchEvent final : public WidgetInputEvent {
|
|||||||
mTouches.AppendElements(aEvent.mTouches);
|
mTouches.AppendElements(aEvent.mTouches);
|
||||||
mInputSource = aEvent.mInputSource;
|
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
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ bool IsPointerEventMessage(EventMessage aMessage) {
|
|||||||
case ePointerOut:
|
case ePointerOut:
|
||||||
case ePointerEnter:
|
case ePointerEnter:
|
||||||
case ePointerLeave:
|
case ePointerLeave:
|
||||||
case ePointerRawUpdate:
|
|
||||||
case ePointerGotCapture:
|
case ePointerGotCapture:
|
||||||
case ePointerLostCapture:
|
case ePointerLostCapture:
|
||||||
case ePointerClick:
|
case ePointerClick:
|
||||||
@@ -122,7 +121,6 @@ bool IsForbiddenDispatchingToNonElementContent(EventMessage aMessage) {
|
|||||||
case ePointerOut:
|
case ePointerOut:
|
||||||
case ePointerEnter:
|
case ePointerEnter:
|
||||||
case ePointerLeave:
|
case ePointerLeave:
|
||||||
case ePointerRawUpdate:
|
|
||||||
case ePointerCancel:
|
case ePointerCancel:
|
||||||
case ePointerGotCapture:
|
case ePointerGotCapture:
|
||||||
case ePointerLostCapture:
|
case ePointerLostCapture:
|
||||||
@@ -174,12 +172,6 @@ bool IsForbiddenDispatchingToNonElementContent(EventMessage aMessage) {
|
|||||||
case eTouchPointerCancel:
|
case eTouchPointerCancel:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case eMouseRawUpdate:
|
|
||||||
case eTouchRawUpdate:
|
|
||||||
MOZ_ASSERT_UNREACHABLE(
|
|
||||||
"Internal raw update events shouldn't be dispatched to the DOM");
|
|
||||||
return true;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -390,7 +382,6 @@ bool WidgetEvent::HasMouseEventMessage() const {
|
|||||||
case eMouseOut:
|
case eMouseOut:
|
||||||
case eMouseHitTest:
|
case eMouseHitTest:
|
||||||
case eMouseMove:
|
case eMouseMove:
|
||||||
case eMouseRawUpdate:
|
|
||||||
return true;
|
return true;
|
||||||
// TODO: Perhaps, we should rename this method.
|
// TODO: Perhaps, we should rename this method.
|
||||||
case ePointerClick:
|
case ePointerClick:
|
||||||
@@ -538,7 +529,7 @@ bool WidgetEvent::IsTargetedAtFocusedContent() const {
|
|||||||
bool WidgetEvent::IsAllowedToDispatchDOMEvent() const {
|
bool WidgetEvent::IsAllowedToDispatchDOMEvent() const {
|
||||||
switch (mClass) {
|
switch (mClass) {
|
||||||
case eMouseEventClass:
|
case eMouseEventClass:
|
||||||
if (mMessage == eMouseRawUpdate || mMessage == eMouseTouchDrag) {
|
if (mMessage == eMouseTouchDrag) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
@@ -548,7 +539,7 @@ bool WidgetEvent::IsAllowedToDispatchDOMEvent() const {
|
|||||||
// DOM events.
|
// DOM events.
|
||||||
// Synthesized button up events also do not cause DOM events because they
|
// Synthesized button up events also do not cause DOM events because they
|
||||||
// do not have a reliable mRefPoint.
|
// do not have a reliable mRefPoint.
|
||||||
return AsMouseEvent()->IsReal();
|
return AsMouseEvent()->mReason == WidgetMouseEvent::eReal;
|
||||||
|
|
||||||
case eWheelEventClass: {
|
case eWheelEventClass: {
|
||||||
// wheel event whose all delta values are zero by user pref applied, it
|
// 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;
|
wheelEvent->mDeltaZ != 0.0;
|
||||||
}
|
}
|
||||||
case eTouchEventClass:
|
case eTouchEventClass:
|
||||||
return mMessage != eTouchRawUpdate && mMessage != eTouchPointerCancel;
|
return mMessage != eTouchPointerCancel;
|
||||||
// Following events are handled in EventStateManager, so, we don't need to
|
// Following events are handled in EventStateManager, so, we don't need to
|
||||||
// dispatch DOM event for them into the DOM tree.
|
// dispatch DOM event for them into the DOM tree.
|
||||||
case eQueryContentEventClass:
|
case eQueryContentEventClass:
|
||||||
@@ -915,7 +906,6 @@ float WidgetMouseEventBase::ComputeMouseButtonPressure() const {
|
|||||||
switch (mMessage) {
|
switch (mMessage) {
|
||||||
// This method is designed for mouse events.
|
// This method is designed for mouse events.
|
||||||
case eMouseMove:
|
case eMouseMove:
|
||||||
case eMouseRawUpdate:
|
|
||||||
case eMouseUp:
|
case eMouseUp:
|
||||||
case eMouseDown:
|
case eMouseDown:
|
||||||
case eMouseEnterIntoWidget:
|
case eMouseEnterIntoWidget:
|
||||||
@@ -944,7 +934,6 @@ float WidgetMouseEventBase::ComputeMouseButtonPressure() const {
|
|||||||
case ePointerClick:
|
case ePointerClick:
|
||||||
case ePointerAuxClick:
|
case ePointerAuxClick:
|
||||||
case ePointerMove:
|
case ePointerMove:
|
||||||
case ePointerRawUpdate:
|
|
||||||
case ePointerUp:
|
case ePointerUp:
|
||||||
case ePointerDown:
|
case ePointerDown:
|
||||||
case ePointerCancel:
|
case ePointerCancel:
|
||||||
|
|||||||
@@ -1955,7 +1955,6 @@ STATIC_ATOMS = [
|
|||||||
Atom("onpointerout", "onpointerout"),
|
Atom("onpointerout", "onpointerout"),
|
||||||
Atom("onpointerenter", "onpointerenter"),
|
Atom("onpointerenter", "onpointerenter"),
|
||||||
Atom("onpointerleave", "onpointerleave"),
|
Atom("onpointerleave", "onpointerleave"),
|
||||||
Atom("onpointerrawupdate", "onpointerrawupdate"),
|
|
||||||
Atom("ongotpointercapture", "ongotpointercapture"),
|
Atom("ongotpointercapture", "ongotpointercapture"),
|
||||||
Atom("onlostpointercapture", "onlostpointercapture"),
|
Atom("onlostpointercapture", "onlostpointercapture"),
|
||||||
# orientation support
|
# orientation support
|
||||||
|
|||||||
Reference in New Issue
Block a user