Bug 1891304 - Make APZEventState manage whether the pointerdown was consumed by content or not r=smaug,hiro
The Pointer Events spec defines that: > Authors can prevent the firing of certain compatibility mouse events by > canceling the pointerdown event (if the isPrimary property is true). > <snip> > Note, however, that this does not prevent the mouseover, mouseenter, mouseout, > or mouseleave events from firing. https://w3c.github.io/pointerevents/#the-pointerdown-event The other browsers conform to this. Therefore, we should stop dispatching compatibility mouse events only if the preceding `pointerdown` is consumed by content. I.e., we need to keep dispatching touch events and `click` etc which indicate what should happen on the element. Currently, `APZEventState` does not manage whether the preceding `pointerdown` is canceled or not. So, it dispatches compatibility mouse events via `APZCCallbackHelper` after the consumed pointer is removed. Therefore, we need to make it manage whether the preceding `pointerdown` of the first touch is consumed or not and `APZCCallbackHelper` needs an option to dispatch the compatibility mouse events only to chrome (they are required to dispatch `click` etc). However, if `APZEventState` is not available like test API used in the remote process, `TouchManager` needs to manage it instead of `APZEventState`. I don't think only `TouchManager` should manage it because `APZEventState` manages complicated state of touch gestures and that can know whether the synthesizing compatibility mouse events related to the consumed `pointerdown` or not strictly. Therefore, this patch makes the `TouchManager` state used only in the path handling synthesized events for tests. Differential Revision: https://phabricator.services.mozilla.com/D208706
This commit is contained in:
@@ -147,6 +147,30 @@ SimpleTest.waitForFocus(async () => {
|
|||||||
);
|
);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
await (async function test_single_tap_with_consuming_pointerdown() {
|
||||||
|
await promiseFlushingAPZGestureState();
|
||||||
|
info("test_single_tap_with_consuming_pointerdown: testing...");
|
||||||
|
events = [];
|
||||||
|
const waitForTouchEnd = promiseEvent("click");
|
||||||
|
child.addEventListener("pointerdown", event => {
|
||||||
|
event.preventDefault();
|
||||||
|
}, {once: true});
|
||||||
|
synthesizeTouch(child, 5, 5);
|
||||||
|
await waitForTouchEnd;
|
||||||
|
const result = stringifyEvents(events);
|
||||||
|
const expected = stringifyEvents([
|
||||||
|
{ type: "touchend", target: child },
|
||||||
|
{ type: "click", target: child, detail: 1, button: 0, buttons: 0 },
|
||||||
|
]);
|
||||||
|
// If testing on Windows, the result is really unstable. Let's allow to
|
||||||
|
// fail for now.
|
||||||
|
(navigator.platform.includes("Win") && result != expected ? todo_is : is)(
|
||||||
|
result,
|
||||||
|
expected,
|
||||||
|
`Single tap should not cause mouse events if pointerdown is consumed, but click event should be fired ${desc}`
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
|
||||||
await (async function test_single_tap_with_consuming_touchstart() {
|
await (async function test_single_tap_with_consuming_touchstart() {
|
||||||
await promiseFlushingAPZGestureState();
|
await promiseFlushingAPZGestureState();
|
||||||
info("test_single_tap_with_consuming_touchstart: testing...");
|
info("test_single_tap_with_consuming_touchstart: testing...");
|
||||||
@@ -223,6 +247,8 @@ SimpleTest.waitForFocus(async () => {
|
|||||||
`Multiple touch should not cause mouse events ${desc}`
|
`Multiple touch should not cause mouse events ${desc}`
|
||||||
);
|
);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// FIXME: Add long tap tests which won't frequently fail.
|
||||||
}
|
}
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include "APZCCallbackHelper.h"
|
#include "APZCCallbackHelper.h"
|
||||||
|
|
||||||
|
#include "APZEventState.h" // for PrecedingPointerDown
|
||||||
|
|
||||||
#include "gfxPlatform.h" // For gfxPlatform::UseTiling
|
#include "gfxPlatform.h" // For gfxPlatform::UseTiling
|
||||||
|
|
||||||
#include "mozilla/AsyncEventDispatcher.h"
|
#include "mozilla/AsyncEventDispatcher.h"
|
||||||
@@ -510,7 +512,8 @@ nsEventStatus APZCCallbackHelper::DispatchWidgetEvent(WidgetGUIEvent& aEvent) {
|
|||||||
|
|
||||||
nsEventStatus APZCCallbackHelper::DispatchSynthesizedMouseEvent(
|
nsEventStatus APZCCallbackHelper::DispatchSynthesizedMouseEvent(
|
||||||
EventMessage aMsg, const LayoutDevicePoint& aRefPoint, Modifiers aModifiers,
|
EventMessage aMsg, const LayoutDevicePoint& aRefPoint, Modifiers aModifiers,
|
||||||
int32_t aClickCount, nsIWidget* aWidget) {
|
int32_t aClickCount, PrecedingPointerDown aPrecedingPointerDownState,
|
||||||
|
nsIWidget* aWidget) {
|
||||||
MOZ_ASSERT(aMsg == eMouseMove || aMsg == eMouseDown || aMsg == eMouseUp ||
|
MOZ_ASSERT(aMsg == eMouseMove || aMsg == eMouseDown || aMsg == eMouseUp ||
|
||||||
aMsg == eMouseLongTap);
|
aMsg == eMouseLongTap);
|
||||||
|
|
||||||
@@ -524,6 +527,15 @@ nsEventStatus APZCCallbackHelper::DispatchSynthesizedMouseEvent(
|
|||||||
if (aMsg == eMouseLongTap) {
|
if (aMsg == eMouseLongTap) {
|
||||||
event.mFlags.mOnlyChromeDispatch = true;
|
event.mFlags.mOnlyChromeDispatch = true;
|
||||||
}
|
}
|
||||||
|
// If the preceding `pointerdown` was canceled by content, we should not
|
||||||
|
// dispatch the compatibility mouse events into the content, but they are
|
||||||
|
// required to dispatch `click`, `dblclick` and `auxclick` events by
|
||||||
|
// EventStateManager. Therefore, we need to dispatch them only to chrome.
|
||||||
|
else if (aPrecedingPointerDownState ==
|
||||||
|
PrecedingPointerDown::ConsumedByContent) {
|
||||||
|
event.PreventDefault(false);
|
||||||
|
event.mFlags.mOnlyChromeDispatch = true;
|
||||||
|
}
|
||||||
if (aMsg != eMouseMove) {
|
if (aMsg != eMouseMove) {
|
||||||
event.mClickCount = aClickCount;
|
event.mClickCount = aClickCount;
|
||||||
}
|
}
|
||||||
@@ -551,21 +563,20 @@ PreventDefaultResult APZCCallbackHelper::DispatchMouseEvent(
|
|||||||
return preventDefaultResult;
|
return preventDefaultResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APZCCallbackHelper::FireSingleTapEvent(const LayoutDevicePoint& aPoint,
|
void APZCCallbackHelper::FireSingleTapEvent(
|
||||||
Modifiers aModifiers,
|
const LayoutDevicePoint& aPoint, Modifiers aModifiers, int32_t aClickCount,
|
||||||
int32_t aClickCount,
|
PrecedingPointerDown aPrecedingPointerDownState, nsIWidget* aWidget) {
|
||||||
nsIWidget* aWidget) {
|
|
||||||
if (aWidget->Destroyed()) {
|
if (aWidget->Destroyed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
APZCCH_LOG("Dispatching single-tap component events to %s\n",
|
APZCCH_LOG("Dispatching single-tap component events to %s\n",
|
||||||
ToString(aPoint).c_str());
|
ToString(aPoint).c_str());
|
||||||
DispatchSynthesizedMouseEvent(eMouseMove, aPoint, aModifiers, aClickCount,
|
DispatchSynthesizedMouseEvent(eMouseMove, aPoint, aModifiers, aClickCount,
|
||||||
aWidget);
|
aPrecedingPointerDownState, aWidget);
|
||||||
DispatchSynthesizedMouseEvent(eMouseDown, aPoint, aModifiers, aClickCount,
|
DispatchSynthesizedMouseEvent(eMouseDown, aPoint, aModifiers, aClickCount,
|
||||||
aWidget);
|
aPrecedingPointerDownState, aWidget);
|
||||||
DispatchSynthesizedMouseEvent(eMouseUp, aPoint, aModifiers, aClickCount,
|
DispatchSynthesizedMouseEvent(eMouseUp, aPoint, aModifiers, aClickCount,
|
||||||
aWidget);
|
aPrecedingPointerDownState, aWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
static dom::Element* GetDisplayportElementFor(
|
static dom::Element* GetDisplayportElementFor(
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ namespace layers {
|
|||||||
|
|
||||||
struct RepaintRequest;
|
struct RepaintRequest;
|
||||||
|
|
||||||
|
namespace apz {
|
||||||
|
enum class PrecedingPointerDown : bool;
|
||||||
|
}
|
||||||
|
|
||||||
/* Refer to documentation on SendSetTargetAPZCNotification for this class */
|
/* Refer to documentation on SendSetTargetAPZCNotification for this class */
|
||||||
class DisplayportSetListener : public ManagedPostRefreshObserver {
|
class DisplayportSetListener : public ManagedPostRefreshObserver {
|
||||||
public:
|
public:
|
||||||
@@ -61,6 +65,8 @@ class APZCCallbackHelper {
|
|||||||
typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
|
typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using PrecedingPointerDown = apz::PrecedingPointerDown;
|
||||||
|
|
||||||
static void NotifyLayerTransforms(const nsTArray<MatrixMessage>& aTransforms);
|
static void NotifyLayerTransforms(const nsTArray<MatrixMessage>& aTransforms);
|
||||||
|
|
||||||
/* Applies the scroll and zoom parameters from the given RepaintRequest object
|
/* Applies the scroll and zoom parameters from the given RepaintRequest object
|
||||||
@@ -107,7 +113,8 @@ class APZCCallbackHelper {
|
|||||||
MOZ_CAN_RUN_SCRIPT
|
MOZ_CAN_RUN_SCRIPT
|
||||||
static nsEventStatus DispatchSynthesizedMouseEvent(
|
static nsEventStatus DispatchSynthesizedMouseEvent(
|
||||||
EventMessage aMsg, const LayoutDevicePoint& aRefPoint,
|
EventMessage aMsg, const LayoutDevicePoint& aRefPoint,
|
||||||
Modifiers aModifiers, int32_t aClickCount, nsIWidget* aWidget);
|
Modifiers aModifiers, int32_t aClickCount,
|
||||||
|
PrecedingPointerDown aPrecedingPointerDownState, nsIWidget* aWidget);
|
||||||
|
|
||||||
/* Dispatch a mouse event with the given parameters.
|
/* Dispatch a mouse event with the given parameters.
|
||||||
* Return whether or not any listeners have called preventDefault on the
|
* Return whether or not any listeners have called preventDefault on the
|
||||||
@@ -123,9 +130,10 @@ class APZCCallbackHelper {
|
|||||||
/* Fire a single-tap event at the given point. The event is dispatched
|
/* Fire a single-tap event at the given point. The event is dispatched
|
||||||
* via the given widget. */
|
* via the given widget. */
|
||||||
MOZ_CAN_RUN_SCRIPT
|
MOZ_CAN_RUN_SCRIPT
|
||||||
static void FireSingleTapEvent(const LayoutDevicePoint& aPoint,
|
static void FireSingleTapEvent(
|
||||||
Modifiers aModifiers, int32_t aClickCount,
|
const LayoutDevicePoint& aPoint, Modifiers aModifiers,
|
||||||
nsIWidget* aWidget);
|
int32_t aClickCount, PrecedingPointerDown aPrecedingPointerDownState,
|
||||||
|
nsIWidget* aWidget);
|
||||||
|
|
||||||
/* Perform hit-testing on the touch points of |aEvent| to determine
|
/* Perform hit-testing on the touch points of |aEvent| to determine
|
||||||
* which scrollable frames they target. If any of these frames don't have
|
* which scrollable frames they target. If any of these frames don't have
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "mozilla/ViewportUtils.h"
|
#include "mozilla/ViewportUtils.h"
|
||||||
#include "mozilla/dom/BrowserChild.h"
|
#include "mozilla/dom/BrowserChild.h"
|
||||||
#include "mozilla/dom/MouseEventBinding.h"
|
#include "mozilla/dom/MouseEventBinding.h"
|
||||||
|
#include "mozilla/dom/PointerEventHandler.h"
|
||||||
#include "mozilla/layers/APZCCallbackHelper.h"
|
#include "mozilla/layers/APZCCallbackHelper.h"
|
||||||
#include "mozilla/layers/APZUtils.h"
|
#include "mozilla/layers/APZUtils.h"
|
||||||
#include "mozilla/layers/IAPZCTreeManager.h"
|
#include "mozilla/layers/IAPZCTreeManager.h"
|
||||||
@@ -100,13 +101,8 @@ APZEventState::APZEventState(nsIWidget* aWidget,
|
|||||||
,
|
,
|
||||||
mActiveElementManager(new ActiveElementManager()),
|
mActiveElementManager(new ActiveElementManager()),
|
||||||
mContentReceivedInputBlockCallback(std::move(aCallback)),
|
mContentReceivedInputBlockCallback(std::move(aCallback)),
|
||||||
mPendingTouchPreventedResponse(false),
|
|
||||||
mPendingTouchPreventedBlockId(0),
|
mPendingTouchPreventedBlockId(0),
|
||||||
mEndTouchState(apz::SingleTapState::NotClick),
|
mEndTouchState(apz::SingleTapState::NotClick),
|
||||||
mFirstTouchCancelled(false),
|
|
||||||
mTouchEndCancelled(false),
|
|
||||||
mReceivedNonTouchStart(false),
|
|
||||||
mTouchStartPrevented(false),
|
|
||||||
mLastTouchIdentifier(0) {
|
mLastTouchIdentifier(0) {
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
mWidget = do_GetWeakReference(aWidget, &rv);
|
mWidget = do_GetWeakReference(aWidget, &rv);
|
||||||
@@ -139,8 +135,9 @@ void APZEventState::ProcessSingleTap(const CSSPoint& aPoint,
|
|||||||
nsCOMPtr<nsIWidget> localWidget = do_QueryReferent(mWidget);
|
nsCOMPtr<nsIWidget> localWidget = do_QueryReferent(mWidget);
|
||||||
if (localWidget) {
|
if (localWidget) {
|
||||||
widget::nsAutoRollup rollup(touchRollup);
|
widget::nsAutoRollup rollup(touchRollup);
|
||||||
APZCCallbackHelper::FireSingleTapEvent(aPoint * aScale, aModifiers,
|
APZCCallbackHelper::FireSingleTapEvent(
|
||||||
aClickCount, localWidget);
|
aPoint * aScale, aModifiers, aClickCount, mPrecedingPointerDownState,
|
||||||
|
localWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
mActiveElementManager->ProcessSingleTap();
|
mActiveElementManager->ProcessSingleTap();
|
||||||
@@ -161,7 +158,8 @@ PreventDefaultResult APZEventState::FireContextmenuEvents(
|
|||||||
// Note that we don't need to check whether mousemove event is consumed or
|
// Note that we don't need to check whether mousemove event is consumed or
|
||||||
// not because Chrome also ignores the result.
|
// not because Chrome also ignores the result.
|
||||||
APZCCallbackHelper::DispatchSynthesizedMouseEvent(
|
APZCCallbackHelper::DispatchSynthesizedMouseEvent(
|
||||||
eMouseMove, aPoint * aScale, aModifiers, 0 /* clickCount */, aWidget);
|
eMouseMove, aPoint * aScale, aModifiers, 0 /* clickCount */,
|
||||||
|
mPrecedingPointerDownState, aWidget);
|
||||||
|
|
||||||
// Converting the modifiers to DOM format for the DispatchMouseEvent call
|
// Converting the modifiers to DOM format for the DispatchMouseEvent call
|
||||||
// is the most useless thing ever because nsDOMWindowUtils::SendMouseEvent
|
// is the most useless thing ever because nsDOMWindowUtils::SendMouseEvent
|
||||||
@@ -186,7 +184,7 @@ PreventDefaultResult APZEventState::FireContextmenuEvents(
|
|||||||
// If the contextmenu wasn't consumed, fire the eMouseLongTap event.
|
// If the contextmenu wasn't consumed, fire the eMouseLongTap event.
|
||||||
nsEventStatus status = APZCCallbackHelper::DispatchSynthesizedMouseEvent(
|
nsEventStatus status = APZCCallbackHelper::DispatchSynthesizedMouseEvent(
|
||||||
eMouseLongTap, aPoint * aScale, aModifiers,
|
eMouseLongTap, aPoint * aScale, aModifiers,
|
||||||
/*clickCount*/ 1, aWidget);
|
/*clickCount*/ 1, mPrecedingPointerDownState, aWidget);
|
||||||
APZES_LOG("eMouseLongTap event %s\n", ToString(status).c_str());
|
APZES_LOG("eMouseLongTap event %s\n", ToString(status).c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -228,7 +226,8 @@ void APZEventState::ProcessLongTap(PresShell* aPresShell,
|
|||||||
// at this time, because things like text selection or dragging may want
|
// at this time, because things like text selection or dragging may want
|
||||||
// to know about it.
|
// to know about it.
|
||||||
APZCCallbackHelper::DispatchSynthesizedMouseEvent(
|
APZCCallbackHelper::DispatchSynthesizedMouseEvent(
|
||||||
eMouseLongTap, aPoint * aScale, aModifiers, /*clickCount*/ 1, widget);
|
eMouseLongTap, aPoint * aScale, aModifiers, /*clickCount*/ 1,
|
||||||
|
mPrecedingPointerDownState, widget);
|
||||||
#else
|
#else
|
||||||
PreventDefaultResult preventDefaultResult =
|
PreventDefaultResult preventDefaultResult =
|
||||||
FireContextmenuEvents(aPresShell, aPoint, aScale, aModifiers, widget);
|
FireContextmenuEvents(aPresShell, aPoint, aScale, aModifiers, widget);
|
||||||
@@ -324,6 +323,14 @@ void APZEventState::ProcessTouchEvent(
|
|||||||
// touchstart was prevented by content.
|
// touchstart was prevented by content.
|
||||||
if (mTouchCounter.GetActiveTouchCount() == 0) {
|
if (mTouchCounter.GetActiveTouchCount() == 0) {
|
||||||
mFirstTouchCancelled = isTouchPrevented;
|
mFirstTouchCancelled = isTouchPrevented;
|
||||||
|
const PointerInfo* pointerInfo =
|
||||||
|
!aEvent.mTouches.IsEmpty() ? PointerEventHandler::GetPointerInfo(
|
||||||
|
aEvent.mTouches[0]->Identifier())
|
||||||
|
: nullptr;
|
||||||
|
mPrecedingPointerDownState =
|
||||||
|
pointerInfo && pointerInfo->mPreventMouseEventByContent
|
||||||
|
? PrecedingPointerDown::ConsumedByContent
|
||||||
|
: PrecedingPointerDown::NotConsumed;
|
||||||
} else {
|
} else {
|
||||||
if (mFirstTouchCancelled && !isTouchPrevented) {
|
if (mFirstTouchCancelled && !isTouchPrevented) {
|
||||||
APZES_LOG(
|
APZES_LOG(
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ namespace layers {
|
|||||||
class ActiveElementManager;
|
class ActiveElementManager;
|
||||||
|
|
||||||
namespace apz {
|
namespace apz {
|
||||||
|
enum class PrecedingPointerDown : bool { NotConsumed, ConsumedByContent };
|
||||||
enum class SingleTapState : uint8_t;
|
enum class SingleTapState : uint8_t;
|
||||||
} // namespace apz
|
} // namespace apz
|
||||||
|
|
||||||
@@ -56,6 +57,8 @@ class APZEventState final {
|
|||||||
typedef ScrollableLayerGuid::ViewID ViewID;
|
typedef ScrollableLayerGuid::ViewID ViewID;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using PrecedingPointerDown = apz::PrecedingPointerDown;
|
||||||
|
|
||||||
APZEventState(nsIWidget* aWidget,
|
APZEventState(nsIWidget* aWidget,
|
||||||
ContentReceivedInputBlockCallback&& aCallback);
|
ContentReceivedInputBlockCallback&& aCallback);
|
||||||
|
|
||||||
@@ -107,17 +110,19 @@ class APZEventState final {
|
|||||||
RefPtr<ActiveElementManager> mActiveElementManager;
|
RefPtr<ActiveElementManager> mActiveElementManager;
|
||||||
ContentReceivedInputBlockCallback mContentReceivedInputBlockCallback;
|
ContentReceivedInputBlockCallback mContentReceivedInputBlockCallback;
|
||||||
TouchCounter mTouchCounter;
|
TouchCounter mTouchCounter;
|
||||||
bool mPendingTouchPreventedResponse;
|
|
||||||
ScrollableLayerGuid mPendingTouchPreventedGuid;
|
ScrollableLayerGuid mPendingTouchPreventedGuid;
|
||||||
uint64_t mPendingTouchPreventedBlockId;
|
uint64_t mPendingTouchPreventedBlockId;
|
||||||
apz::SingleTapState mEndTouchState;
|
apz::SingleTapState mEndTouchState;
|
||||||
bool mFirstTouchCancelled;
|
PrecedingPointerDown mPrecedingPointerDownState =
|
||||||
bool mTouchEndCancelled;
|
PrecedingPointerDown::NotConsumed;
|
||||||
|
bool mPendingTouchPreventedResponse = false;
|
||||||
|
bool mFirstTouchCancelled = false;
|
||||||
|
bool mTouchEndCancelled = false;
|
||||||
// Set to true when we have received any one of
|
// Set to true when we have received any one of
|
||||||
// touch-move/touch-end/touch-cancel events in the touch block being
|
// touch-move/touch-end/touch-cancel events in the touch block being
|
||||||
// processed.
|
// processed.
|
||||||
bool mReceivedNonTouchStart;
|
bool mReceivedNonTouchStart = false;
|
||||||
bool mTouchStartPrevented;
|
bool mTouchStartPrevented = false;
|
||||||
|
|
||||||
int32_t mLastTouchIdentifier;
|
int32_t mLastTouchIdentifier;
|
||||||
nsTArray<TouchBehaviorFlags> mTouchBlockAllowedBehaviors;
|
nsTArray<TouchBehaviorFlags> mTouchBlockAllowedBehaviors;
|
||||||
|
|||||||
@@ -7746,6 +7746,10 @@ void PresShell::EventHandler::MaybeSynthesizeCompatMouseEventsForTouchEnd(
|
|||||||
event.mClickCount = message == eMouseMove ? 0 : 1;
|
event.mClickCount = message == eMouseMove ? 0 : 1;
|
||||||
event.mModifiers = aTouchEndEvent->mModifiers;
|
event.mModifiers = aTouchEndEvent->mModifiers;
|
||||||
event.convertToPointer = false;
|
event.convertToPointer = false;
|
||||||
|
if (TouchManager::IsPrecedingTouchPointerDownConsumedByContent()) {
|
||||||
|
event.PreventDefault(false);
|
||||||
|
event.mFlags.mOnlyChromeDispatch = true;
|
||||||
|
}
|
||||||
nsEventStatus mouseEventStatus = nsEventStatus_eIgnore;
|
nsEventStatus mouseEventStatus = nsEventStatus_eIgnore;
|
||||||
presShell->HandleEvent(frameForPresShell, &event, false, &mouseEventStatus);
|
presShell->HandleEvent(frameForPresShell, &event, false, &mouseEventStatus);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "mozilla/dom/EventTarget.h"
|
#include "mozilla/dom/EventTarget.h"
|
||||||
|
#include "mozilla/dom/PointerEventHandler.h"
|
||||||
#include "mozilla/layers/InputAPZContext.h"
|
#include "mozilla/layers/InputAPZContext.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
@@ -30,6 +31,7 @@ StaticAutoPtr<nsTHashMap<nsUint32HashKey, TouchManager::TouchInfo>>
|
|||||||
layers::LayersId TouchManager::sCaptureTouchLayersId;
|
layers::LayersId TouchManager::sCaptureTouchLayersId;
|
||||||
TimeStamp TouchManager::sSingleTouchStartTimeStamp;
|
TimeStamp TouchManager::sSingleTouchStartTimeStamp;
|
||||||
LayoutDeviceIntPoint TouchManager::sSingleTouchStartPoint;
|
LayoutDeviceIntPoint TouchManager::sSingleTouchStartPoint;
|
||||||
|
bool TouchManager::sPrecedingTouchPointerDownConsumedByContent = false;
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
void TouchManager::InitializeStatics() {
|
void TouchManager::InitializeStatics() {
|
||||||
@@ -271,7 +273,11 @@ bool TouchManager::PreHandleEvent(WidgetEvent* aEvent, nsEventStatus* aStatus,
|
|||||||
// event, all subsequent touch events will use the same layers id.
|
// event, all subsequent touch events will use the same layers id.
|
||||||
sCaptureTouchLayersId = aEvent->mLayersId;
|
sCaptureTouchLayersId = aEvent->mLayersId;
|
||||||
sSingleTouchStartTimeStamp = aEvent->mTimeStamp;
|
sSingleTouchStartTimeStamp = aEvent->mTimeStamp;
|
||||||
sSingleTouchStartPoint = aEvent->AsTouchEvent()->mTouches[0]->mRefPoint;
|
sSingleTouchStartPoint = touchEvent->mTouches[0]->mRefPoint;
|
||||||
|
const PointerInfo* pointerInfo = PointerEventHandler::GetPointerInfo(
|
||||||
|
touchEvent->mTouches[0]->Identifier());
|
||||||
|
sPrecedingTouchPointerDownConsumedByContent =
|
||||||
|
pointerInfo && pointerInfo->mPreventMouseEventByContent;
|
||||||
} else {
|
} else {
|
||||||
touchEvent->mLayersId = sCaptureTouchLayersId;
|
touchEvent->mLayersId = sCaptureTouchLayersId;
|
||||||
sSingleTouchStartTimeStamp = TimeStamp();
|
sSingleTouchStartTimeStamp = TimeStamp();
|
||||||
@@ -585,4 +591,9 @@ bool TouchManager::IsSingleTapEndToDoDefault(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
bool TouchManager::IsPrecedingTouchPointerDownConsumedByContent() {
|
||||||
|
return sPrecedingTouchPointerDownConsumedByContent;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -69,6 +69,10 @@ class TouchManager {
|
|||||||
// dispatch mouse events for touch events synthesized without APZ.
|
// dispatch mouse events for touch events synthesized without APZ.
|
||||||
static bool IsSingleTapEndToDoDefault(const WidgetTouchEvent* aTouchEndEvent);
|
static bool IsSingleTapEndToDoDefault(const WidgetTouchEvent* aTouchEndEvent);
|
||||||
|
|
||||||
|
// Returns true if the preceding `pointerdown` was consumed by content of
|
||||||
|
// the last active pointers of touches.
|
||||||
|
static bool IsPrecedingTouchPointerDownConsumedByContent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void EvictTouches(dom::Document* aLimitToDocument = nullptr);
|
void EvictTouches(dom::Document* aLimitToDocument = nullptr);
|
||||||
static void EvictTouchPoint(RefPtr<dom::Touch>& aTouch,
|
static void EvictTouchPoint(RefPtr<dom::Touch>& aTouch,
|
||||||
@@ -89,10 +93,20 @@ class TouchManager {
|
|||||||
static layers::LayersId sCaptureTouchLayersId;
|
static layers::LayersId sCaptureTouchLayersId;
|
||||||
// The last start of a single tap. This will be set to "Null" if the tap is
|
// The last start of a single tap. This will be set to "Null" if the tap is
|
||||||
// consumed or becomes not a single tap.
|
// consumed or becomes not a single tap.
|
||||||
|
// NOTE: This is used for touches without APZ, i.e., if they are synthesized
|
||||||
|
// in-process for tests.
|
||||||
static TimeStamp sSingleTouchStartTimeStamp;
|
static TimeStamp sSingleTouchStartTimeStamp;
|
||||||
// The last start point of the single tap tracked with
|
// The last start point of the single tap tracked with
|
||||||
// sSingleTouchStartTimeStamp.
|
// sSingleTouchStartTimeStamp.
|
||||||
|
// NOTE: This is used for touches without APZ, i.e., if they are synthesized
|
||||||
|
// in-process for tests.
|
||||||
static LayoutDeviceIntPoint sSingleTouchStartPoint;
|
static LayoutDeviceIntPoint sSingleTouchStartPoint;
|
||||||
|
// Whether the preceding `pointerdown` of the last active touches is consumed
|
||||||
|
// by content or not. If APZ is enabled, same state is managed by
|
||||||
|
// APZEventState.
|
||||||
|
// NOTE: This is used for touches without APZ, i.e., if they are synthesized
|
||||||
|
// in-process for tests.
|
||||||
|
static bool sPrecedingTouchPointerDownConsumedByContent;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
Reference in New Issue
Block a user