diff options
Diffstat (limited to 'gfx/layers/apz/src')
-rw-r--r-- | gfx/layers/apz/src/APZCTreeManager.cpp | 56 | ||||
-rw-r--r-- | gfx/layers/apz/src/APZCTreeManager.h | 9 | ||||
-rw-r--r-- | gfx/layers/apz/src/APZUpdater.cpp | 30 | ||||
-rw-r--r-- | gfx/layers/apz/src/AsyncPanZoomController.cpp | 46 | ||||
-rw-r--r-- | gfx/layers/apz/src/AsyncPanZoomController.h | 2 | ||||
-rw-r--r-- | gfx/layers/apz/src/AutoscrollAnimation.cpp | 2 | ||||
-rw-r--r-- | gfx/layers/apz/src/GenericScrollAnimation.cpp | 9 | ||||
-rw-r--r-- | gfx/layers/apz/src/GestureEventListener.cpp | 87 | ||||
-rw-r--r-- | gfx/layers/apz/src/GestureEventListener.h | 3 |
9 files changed, 178 insertions, 66 deletions
diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index d28392b716..ef3cde3596 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -62,6 +62,8 @@ mozilla::LazyLogModule mozilla::layers::APZCTreeManager::sLog("apz.manager"); #define APZCTM_LOG(...) \ MOZ_LOG(APZCTreeManager::sLog, LogLevel::Debug, (__VA_ARGS__)) +#define APZCTM_LOGV(...) \ + MOZ_LOG(APZCTreeManager::sLog, LogLevel::Verbose, (__VA_ARGS__)) static mozilla::LazyLogModule sApzKeyLog("apz.key"); #define APZ_KEY_LOG(...) MOZ_LOG(sApzKeyLog, LogLevel::Debug, (__VA_ARGS__)) @@ -83,10 +85,10 @@ typedef CompositorBridgeParent::LayerTreeState LayerTreeState; struct APZCTreeManager::TreeBuildingState { TreeBuildingState(LayersId aRootLayersId, bool aIsFirstPaint, LayersId aOriginatingLayersId, APZTestData* aTestData, - uint32_t aPaintSequence) + uint32_t aPaintSequence, bool aIsTestLoggingEnabled) : mIsFirstPaint(aIsFirstPaint), mOriginatingLayersId(aOriginatingLayersId), - mPaintLogger(aTestData, aPaintSequence) { + mPaintLogger(aTestData, aPaintSequence, aIsTestLoggingEnabled) { CompositorBridgeParent::CallWithIndirectShadowTree( aRootLayersId, [this](LayerTreeState& aState) -> void { mCompositorController = aState.GetCompositorController(); @@ -158,6 +160,9 @@ struct APZCTreeManager::TreeBuildingState { // cumulative EventRegionsOverride flags from the reflayers, and is used to // apply them to descendant layers. std::stack<EventRegionsOverride> mOverrideFlags; + + // Wether the APZC correspoinding to the originating LayersId was updated. + bool mOriginatingLayersIdUpdated = false; }; class APZCTreeManager::CheckerboardFlushObserver : public nsIObserver { @@ -391,8 +396,7 @@ void APZCTreeManager::SetAllowedTouchBehavior( uint64_t aInputBlockId, const nsTArray<TouchBehaviorFlags>& aValues) { if (!APZThreadUtils::IsControllerThread()) { APZThreadUtils::RunOnControllerThread( - NewRunnableMethod<uint64_t, - StoreCopyPassByLRef<nsTArray<TouchBehaviorFlags>>>( + NewRunnableMethod<uint64_t, nsTArray<TouchBehaviorFlags>>( "layers::APZCTreeManager::SetAllowedTouchBehavior", this, &APZCTreeManager::SetAllowedTouchBehavior, aInputBlockId, aValues.Clone())); @@ -420,9 +424,11 @@ void APZCTreeManager::SetBrowserGestureResponse( mInputQueue->SetBrowserGestureResponse(aInputBlockId, aResponse); } -void APZCTreeManager::UpdateHitTestingTree( - const WebRenderScrollDataWrapper& aRoot, bool aIsFirstPaint, - LayersId aOriginatingLayersId, uint32_t aPaintSequenceNumber) { +APZCTreeManager::OriginatingLayersIdUpdated +APZCTreeManager::UpdateHitTestingTree(const WebRenderScrollDataWrapper& aRoot, + bool aIsFirstPaint, + LayersId aOriginatingLayersId, + uint32_t aPaintSequenceNumber) { AssertOnUpdaterThread(); RecursiveMutexAutoLock lock(mTreeLock); @@ -430,7 +436,8 @@ void APZCTreeManager::UpdateHitTestingTree( // For testing purposes, we log some data to the APZTestData associated with // the layers id that originated this update. APZTestData* testData = nullptr; - if (StaticPrefs::apz_test_logging_enabled()) { + const bool testLoggingEnabled = StaticPrefs::apz_test_logging_enabled(); + if (testLoggingEnabled) { MutexAutoLock lock(mTestDataLock); UniquePtr<APZTestData> ptr = MakeUnique<APZTestData>(); auto result = @@ -440,7 +447,7 @@ void APZCTreeManager::UpdateHitTestingTree( } TreeBuildingState state(mRootLayersId, aIsFirstPaint, aOriginatingLayersId, - testData, aPaintSequenceNumber); + testData, aPaintSequenceNumber, testLoggingEnabled); // We do this business with collecting the entire tree into an array because // otherwise it's very hard to determine which APZC instances need to be @@ -730,6 +737,8 @@ void APZCTreeManager::UpdateHitTestingTree( mRootNode->Dump(" "); } SendSubtreeTransformsToChromeMainThread(nullptr); + + return OriginatingLayersIdUpdated{state.mOriginatingLayersIdUpdated}; } void APZCTreeManager::UpdateFocusState(LayersId aRootLayerTreeId, @@ -763,7 +772,7 @@ void APZCTreeManager::SampleForWebRender(const Maybe<VsyncId>& aVsyncId, controller->ScheduleRenderOnCompositorThread( wr::RenderReasons::ANIMATED_PROPERTY); } - APZCTM_LOG( + APZCTM_LOGV( "APZCTreeManager(%p)::SampleForWebRender, want more composites: %d\n", this, (activeAnimations && controller)); @@ -1231,6 +1240,10 @@ HitTestingTreeNode* APZCTreeManager::PrepareNodeForLayer( "Found APZC %p for layer %p with identifiers %" PRIx64 " %" PRId64 "\n", apzc.get(), aLayer.GetLayer(), uint64_t(guid.mLayersId), guid.mScrollId); + if (aLayersId == aState.mOriginatingLayersId) { + aState.mOriginatingLayersIdUpdated = true; + } + // If we haven't encountered a layer already with the same metrics, then we // need to do the full reuse-or-make-an-APZC algorithm, which is contained // inside the block below. @@ -1522,6 +1535,11 @@ APZEventResult APZCTreeManager::ReceiveInputEvent( } case MOUSE_INPUT: { MouseInput& mouseInput = aEvent.AsMouseInput(); + MOZ_LOG(APZCTreeManager::sLog, + mouseInput.mType == MouseInput::MOUSE_MOVE ? LogLevel::Verbose + : LogLevel::Debug, + ("Received mouse input type %d at %s\n", (int)mouseInput.mType, + ToString(mouseInput.mOrigin).c_str())); mouseInput.mHandledByAPZ = true; SetCurrentMousePosition(mouseInput.mOrigin); @@ -1613,6 +1631,9 @@ APZEventResult APZCTreeManager::ReceiveInputEvent( // Do this before early return for Fission hit testing. ScrollWheelInput& wheelInput = aEvent.AsScrollWheelInput(); + APZCTM_LOG("Received wheel input at %s with delta (%f, %f)\n", + ToString(wheelInput.mOrigin).c_str(), wheelInput.mDeltaX, + wheelInput.mDeltaY); state.mHit = GetTargetAPZC(wheelInput.mOrigin); wheelInput.mHandledByAPZ = WillHandleInput(wheelInput); @@ -1674,6 +1695,9 @@ APZEventResult APZCTreeManager::ReceiveInputEvent( // Do this before early return for Fission hit testing. PanGestureInput& panInput = aEvent.AsPanGestureInput(); + APZCTM_LOG("Received pan gesture input type %d at %s with delta %s\n", + (int)panInput.mType, ToString(panInput.mPanStartPoint).c_str(), + ToString(panInput.mPanDisplacement).c_str()); state.mHit = GetTargetAPZC(panInput.mPanStartPoint); panInput.mHandledByAPZ = WillHandleInput(panInput); @@ -2021,6 +2045,18 @@ APZEventResult APZCTreeManager::InputHandlingState::Finish( void APZCTreeManager::ProcessTouchInput(InputHandlingState& aState, MultiTouchInput& aInput) { + APZCTM_LOG("Received touch input type %d with touch points [%s]\n", + (int)aInput.mType, + [&] { + nsCString result; + for (const auto& touch : aInput.mTouches) { + result.AppendPrintf("%s", + ToString(touch.mScreenPoint).c_str()); + } + return result; + }() + .get()); + aInput.mHandledByAPZ = true; nsTArray<TouchBehaviorFlags> touchBehaviors; HitTestingTreeNodeAutoLock hitScrollbarNode; diff --git a/gfx/layers/apz/src/APZCTreeManager.h b/gfx/layers/apz/src/APZCTreeManager.h index ff9bba51ca..71d35fd5a6 100644 --- a/gfx/layers/apz/src/APZCTreeManager.h +++ b/gfx/layers/apz/src/APZCTreeManager.h @@ -190,10 +190,13 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge { * this layer update. Note that every child * process' layer subtree has its own sequence * numbers. + * @return OriginatingLayersIdUpdated whether the given + * |aOriginatingLayersId|'s data was processed. */ - void UpdateHitTestingTree(const WebRenderScrollDataWrapper& aRoot, - bool aIsFirstPaint, LayersId aOriginatingLayersId, - uint32_t aPaintSequenceNumber); + enum class OriginatingLayersIdUpdated : bool { No, Yes }; + OriginatingLayersIdUpdated UpdateHitTestingTree( + const WebRenderScrollDataWrapper& aRoot, bool aIsFirstPaint, + LayersId aOriginatingLayersId, uint32_t aPaintSequenceNumber); /** * Called when webrender is enabled, from the sampler thread. This function diff --git a/gfx/layers/apz/src/APZUpdater.cpp b/gfx/layers/apz/src/APZUpdater.cpp index 2bbad6e1a7..2f1b551f3a 100644 --- a/gfx/layers/apz/src/APZUpdater.cpp +++ b/gfx/layers/apz/src/APZUpdater.cpp @@ -191,14 +191,38 @@ void APZUpdater::UpdateScrollDataAndTreeState( auto isFirstPaint = aScrollData.IsFirstPaint(); auto paintSequenceNumber = aScrollData.GetPaintSequenceNumber(); + auto previous = self->mScrollData.find(aOriginatingLayersId); + // If there's the previous scroll data which hasn't yet been + // processed, we need to merge the previous scroll position updates + // into the latest one. + if (previous != self->mScrollData.end()) { + WebRenderScrollData& previousData = previous->second; + if (previousData.GetWasUpdateSkipped()) { + MOZ_ASSERT(previousData.IsFirstPaint()); + aScrollData.PrependUpdates(previousData); + } + } + self->mScrollData[aOriginatingLayersId] = std::move(aScrollData); auto root = self->mScrollData.find(aRootLayerTreeId); if (root == self->mScrollData.end()) { return; } - self->mApz->UpdateHitTestingTree( - WebRenderScrollDataWrapper(*self, &(root->second)), - isFirstPaint, aOriginatingLayersId, paintSequenceNumber); + if ((self->mApz->UpdateHitTestingTree( + WebRenderScrollDataWrapper(*self, &(root->second)), + isFirstPaint, aOriginatingLayersId, paintSequenceNumber) == + APZCTreeManager::OriginatingLayersIdUpdated::No) && + isFirstPaint) { + // If the given |aOriginatingLayersId| data wasn't used for + // updating, it's likly that the parent process hasn't yet + // received the LayersId as "ReferentId", thus we need to process + // it in a subsequent update where we got the "ReferentId". + // + // NOTE: We restrict the above previous scroll data prepending to + // the first paint case, otherwise the cumulative scroll data may + // be exploded if we have never received the "ReferenceId". + self->mScrollData[aOriginatingLayersId].SetWasUpdateSkipped(); + } })); } diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index 342375c019..edbd2ecffa 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -106,6 +106,10 @@ static mozilla::LazyLogModule sApzCtlLog("apz.controller"); APZC_LOG("%p(%s scrollId=%" PRIu64 "): " fmt, (apzc), \ (apzc)->IsRootContent() ? "root" : "subframe", \ (apzc)->GetScrollId(), ##__VA_ARGS__) +#define APZC_LOGV_DETAIL(fmt, apzc, ...) \ + APZC_LOGV("%p(%s scrollId=%" PRIu64 "): " fmt, (apzc), \ + (apzc)->IsRootContent() ? "root" : "subframe", \ + (apzc)->GetScrollId(), ##__VA_ARGS__) #define APZC_LOG_FM_COMMON(fm, prefix, level, ...) \ if (MOZ_LOG_TEST(sApzCtlLog, level)) { \ @@ -2248,6 +2252,11 @@ CSSRect AsyncPanZoomController::GetCurrentScrollRangeInCssPixels() const { return Metrics().CalculateScrollRange(); } +bool AsyncPanZoomController::AllowOneTouchPinch() const { + return StaticPrefs::apz_one_touch_pinch_enabled() && + ZoomConstraintsAllowZoom(); +} + // Return whether or not the underlying layer can be scrolled on either axis. bool AsyncPanZoomController::CanScroll(const InputData& aEvent) const { ParentLayerPoint delta = GetDeltaForEvent(aEvent); @@ -4734,7 +4743,7 @@ bool AsyncPanZoomController::UpdateAnimation( // Even if there's no animation, if we have a scroll offset change pending due // to the frame delay, we need to keep compositing. if (mLastSampleTime == aSampleTime) { - APZC_LOG_DETAIL( + APZC_LOGV_DETAIL( "UpdateAnimation short-circuit, animation=%p, pending frame-delayed " "offset=%d\n", this, mAnimation.get(), HavePendingFrameDelayedOffset()); @@ -4754,8 +4763,8 @@ bool AsyncPanZoomController::UpdateAnimation( // so that e.g. a main-thread animation can stay in sync with user-driven // scrolling or a compositor animation. bool needComposite = SampleCompositedAsyncTransform(aProofOfLock); - APZC_LOG_DETAIL("UpdateAnimation needComposite=%d mAnimation=%p\n", this, - needComposite, mAnimation.get()); + APZC_LOGV_DETAIL("UpdateAnimation needComposite=%d mAnimation=%p\n", this, + needComposite, mAnimation.get()); TimeDuration sampleTimeDelta = aSampleTime - mLastSampleTime; mLastSampleTime = aSampleTime; @@ -5581,17 +5590,6 @@ void AsyncPanZoomController::NotifyLayersUpdated( aScrollMetadata.GetOverscrollBehavior()); } - if (needToReclampScroll) { - // Whenever scrollable rect or composition bounds has changed, we need to - // re-clamp the scroll offset since it may be out of bounds. Also note that - // we need to re-clamp before updating new scroll offsets from content since - // we will use the last scroll offset to reflect the new offsets. - ClampAndSetVisualScrollOffset(Metrics().GetVisualScrollOffset()); - for (auto& sampledState : mSampledState) { - sampledState.ClampVisualScrollOffset(Metrics()); - } - } - bool instantScrollMayTriggerTransform = false; bool scrollOffsetUpdated = false; bool smoothScrollRequested = false; @@ -5738,20 +5736,11 @@ void AsyncPanZoomController::NotifyLayersUpdated( relativeDelta = Some(Metrics().ApplyPureRelativeScrollUpdateFrom(scrollUpdate)); Metrics().RecalculateLayoutViewportOffset(); - } else if (scrollUpdate.GetType() == ScrollUpdateType::MergeableAbsolute) { - APZC_LOG("%p mergeable updating scroll offset from %s to %s\n", this, - ToString(Metrics().GetVisualScrollOffset()).c_str(), - ToString(scrollUpdate.GetDestination()).c_str()); - relativeDelta = - Some(Metrics().ApplyAbsoluteScrollUpdateFrom(scrollUpdate).second); - Metrics().RecalculateLayoutViewportOffset(); - scrollOffsetUpdated = true; } else { APZC_LOG("%p updating scroll offset from %s to %s\n", this, ToString(Metrics().GetVisualScrollOffset()).c_str(), ToString(scrollUpdate.GetDestination()).c_str()); - auto [offsetChanged, _] = - Metrics().ApplyAbsoluteScrollUpdateFrom(scrollUpdate); + bool offsetChanged = Metrics().ApplyScrollUpdateFrom(scrollUpdate); Metrics().RecalculateLayoutViewportOffset(); if (offsetChanged || scrollUpdate.GetMode() != ScrollMode::Instant || @@ -5788,6 +5777,15 @@ void AsyncPanZoomController::NotifyLayersUpdated( } } + if (aIsFirstPaint || needToReclampScroll) { + // The scrollable rect or composition bounds may have changed in a way that + // makes our local scroll offset out of bounds, so clamp it. + ClampAndSetVisualScrollOffset(Metrics().GetVisualScrollOffset()); + for (auto& sampledState : mSampledState) { + sampledState.ClampVisualScrollOffset(Metrics()); + } + } + if (scrollOffsetUpdated) { for (auto& sampledState : mSampledState) { if (!didCancelAnimation && cumulativeRelativeDelta.isSome()) { diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h index fdc72b1971..d0c4537a66 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.h +++ b/gfx/layers/apz/src/AsyncPanZoomController.h @@ -1305,6 +1305,8 @@ class AsyncPanZoomController { */ CSSRect GetCurrentScrollRangeInCssPixels() const; + bool AllowOneTouchPinch() const; + private: /** * Advances to the next sample, if there is one, the list of sampled states diff --git a/gfx/layers/apz/src/AutoscrollAnimation.cpp b/gfx/layers/apz/src/AutoscrollAnimation.cpp index 8d4b8fca10..45063ef2b4 100644 --- a/gfx/layers/apz/src/AutoscrollAnimation.cpp +++ b/gfx/layers/apz/src/AutoscrollAnimation.cpp @@ -17,7 +17,7 @@ namespace mozilla { namespace layers { // Helper function for AutoscrollAnimation::DoSample(). -// Basically copied as-is from toolkit/actors/AutoScrollChild.jsm. +// Basically copied as-is from toolkit/actors/AutoScrollChild.sys.mjs. static float Accelerate(ScreenCoord curr, ScreenCoord start) { static const int speed = 12; float val = (curr - start) / speed; diff --git a/gfx/layers/apz/src/GenericScrollAnimation.cpp b/gfx/layers/apz/src/GenericScrollAnimation.cpp index 04ca8c4697..62f19fab35 100644 --- a/gfx/layers/apz/src/GenericScrollAnimation.cpp +++ b/gfx/layers/apz/src/GenericScrollAnimation.cpp @@ -15,6 +15,9 @@ #include "ScrollAnimationMSDPhysics.h" #include "mozilla/StaticPrefs_general.h" +static mozilla::LazyLogModule sApzScrollAnimLog("apz.scrollanimation"); +#define GSA_LOG(...) MOZ_LOG(sApzScrollAnimLog, LogLevel::Debug, (__VA_ARGS__)) + namespace mozilla { namespace layers { @@ -101,6 +104,12 @@ bool GenericScrollAnimation::DoSample(FrameMetrics& aFrameMetrics, // then end the animation early. Note that the initial displacement could be 0 // if the compositor ran very quickly (<1ms) after the animation was created. // When that happens we want to make sure the animation continues. + GSA_LOG( + "Sampling GenericScrollAnimation: time %f finished %d sampledDest %s " + "adjustedOffset %s overscroll %s\n", + (now - TimeStamp::ProcessCreation()).ToMilliseconds(), finished, + ToString(CSSPoint::FromAppUnits(sampledDest)).c_str(), + ToString(adjustedOffset).c_str(), ToString(overscroll).c_str()); if (!IsZero(displacement / zoom) && IsZero(adjustedOffset / zoom)) { // Nothing more to do - end the animation. return false; diff --git a/gfx/layers/apz/src/GestureEventListener.cpp b/gfx/layers/apz/src/GestureEventListener.cpp index b54674b593..4300e9ba41 100644 --- a/gfx/layers/apz/src/GestureEventListener.cpp +++ b/gfx/layers/apz/src/GestureEventListener.cpp @@ -5,13 +5,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "GestureEventListener.h" -#include <algorithm> // for max +#include <algorithm> // for max +#include <ostream> #include <math.h> // for fabsf #include <stddef.h> // for size_t #include "AsyncPanZoomController.h" // for AsyncPanZoomController #include "InputBlockState.h" // for TouchBlockState #include "base/task.h" // for CancelableTask, etc #include "InputBlockState.h" // for TouchBlockState +#include "mozilla/Assertions.h" +#include "mozilla/EventForwards.h" #include "mozilla/StaticPrefs_apz.h" #include "mozilla/StaticPrefs_ui.h" #include "nsDebug.h" // for NS_WARNING @@ -83,8 +86,8 @@ GestureEventListener::~GestureEventListener() = default; nsEventStatus GestureEventListener::HandleInputEvent( const MultiTouchInput& aEvent) { - GEL_LOG("Receiving event type %d with %zu touches in state %d\n", - aEvent.mType, aEvent.mTouches.Length(), mState); + GEL_LOG("Receiving event type %d with %zu touches in state %s\n", + aEvent.mType, aEvent.mTouches.Length(), ToString(mState).c_str()); nsEventStatus rv = nsEventStatus_eIgnore; @@ -175,16 +178,15 @@ nsEventStatus GestureEventListener::HandleInputTouchSingleStart() { EnterFirstSingleTouchDown(); break; case GESTURE_FIRST_SINGLE_TOUCH_UP: + // Bail out of any gesture that includes the first tap. + CancelLongTapTimeoutTask(); + CancelMaxTapTimeoutTask(); if (SecondTapIsFar()) { - // If the second tap goes down far away from the first, then bail out - // of any gesture that includes the first tap. - CancelLongTapTimeoutTask(); - CancelMaxTapTimeoutTask(); - mSingleTapSent = Nothing(); - - // But still allow the second tap to participate in a gesture + // If the second tap goes down far away from the first, + // allow the second tap to participate in a gesture // (e.g. lead to a single tap, or a double tap if an additional // tap occurs near the same location). + mSingleTapSent = Nothing(); EnterFirstSingleTouchDown(); } else { // Otherwise, reset the touch start position so that, if this turns into @@ -225,9 +227,10 @@ nsEventStatus GestureEventListener::HandleInputTouchMultiStart() { rv = nsEventStatus_eConsumeNoDefault; break; case GESTURE_FIRST_SINGLE_TOUCH_UP: - case GESTURE_SECOND_SINGLE_TOUCH_DOWN: // Cancel wait for double tap CancelMaxTapTimeoutTask(); + [[fallthrough]]; + case GESTURE_SECOND_SINGLE_TOUCH_DOWN: MOZ_ASSERT(mSingleTapSent.isSome()); if (!mSingleTapSent.value()) { TriggerSingleTapConfirmedEvent(); @@ -307,12 +310,8 @@ nsEventStatus GestureEventListener::HandleInputTouchMove() { // If touch has moved noticeably (within StaticPrefs::apz_max_tap_time()), // change state. if (MoveDistanceIsLarge()) { - CancelLongTapTimeoutTask(); - CancelMaxTapTimeoutTask(); mSingleTapSent = Nothing(); - if (!StaticPrefs::apz_one_touch_pinch_enabled()) { - // If the one-touch-pinch feature is disabled, bail out of the double- - // tap gesture instead. + if (!mAsyncPanZoomController->AllowOneTouchPinch()) { SetState(GESTURE_NONE); break; } @@ -451,7 +450,6 @@ nsEventStatus GestureEventListener::HandleInputTouchEnd() { } case GESTURE_SECOND_SINGLE_TOUCH_DOWN: { - CancelMaxTapTimeoutTask(); MOZ_ASSERT(mSingleTapSent.isSome()); mAsyncPanZoomController->HandleGestureEvent(CreateTapEvent( mLastTouchInput, mSingleTapSent.value() @@ -535,7 +533,9 @@ nsEventStatus GestureEventListener::HandleInputTouchCancel() { } void GestureEventListener::HandleInputTimeoutLongTap() { - GEL_LOG("Running long-tap timeout task in state %d\n", mState); + MOZ_ASSERT(mState != GESTURE_SECOND_SINGLE_TOUCH_DOWN); + GEL_LOG("Running long-tap timeout task in state %s\n", + ToString(mState).c_str()); mLongTapTimeoutTask = nullptr; @@ -559,14 +559,15 @@ void GestureEventListener::HandleInputTimeoutLongTap() { } void GestureEventListener::HandleInputTimeoutMaxTap(bool aDuringFastFling) { - GEL_LOG("Running max-tap timeout task in state %d\n", mState); + MOZ_ASSERT(mState != GESTURE_SECOND_SINGLE_TOUCH_DOWN); + GEL_LOG("Running max-tap timeout task in state %s\n", + ToString(mState).c_str()); mMaxTapTimeoutTask = nullptr; if (mState == GESTURE_FIRST_SINGLE_TOUCH_DOWN) { SetState(GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN); - } else if (mState == GESTURE_FIRST_SINGLE_TOUCH_UP || - mState == GESTURE_SECOND_SINGLE_TOUCH_DOWN) { + } else if (mState == GESTURE_FIRST_SINGLE_TOUCH_UP) { MOZ_ASSERT(mSingleTapSent.isSome()); if (!aDuringFastFling && !mSingleTapSent.value()) { TriggerSingleTapConfirmedEvent(); @@ -585,6 +586,8 @@ void GestureEventListener::TriggerSingleTapConfirmedEvent() { } void GestureEventListener::SetState(GestureState aState) { + GEL_LOG("State change from %s to %s", ToString(mState).c_str(), + ToString(aState).c_str()); mState = aState; if (mState == GESTURE_NONE) { @@ -598,10 +601,7 @@ void GestureEventListener::SetState(GestureState aState) { } void GestureEventListener::CancelLongTapTimeoutTask() { - if (mState == GESTURE_SECOND_SINGLE_TOUCH_DOWN) { - // being in this state means the task has been canceled already - return; - } + MOZ_ASSERT(mState != GESTURE_SECOND_SINGLE_TOUCH_DOWN); if (mLongTapTimeoutTask) { mLongTapTimeoutTask->Cancel(); @@ -628,6 +628,8 @@ void GestureEventListener::CreateLongTapTimeoutTask() { } void GestureEventListener::CancelMaxTapTimeoutTask() { + MOZ_ASSERT(mState != GESTURE_SECOND_SINGLE_TOUCH_DOWN); + if (mState == GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN) { // being in this state means the timer has just been triggered return; @@ -659,5 +661,40 @@ void GestureEventListener::CreateMaxTapTimeoutTask() { std::max(0L, remainingDelay)); } +std::ostream& operator<<(std::ostream& os, + GestureEventListener::GestureState aState) { + switch (aState) { + case GestureEventListener::GESTURE_NONE: + os << "GESTURE_NONE"; + break; + case GestureEventListener::GESTURE_FIRST_SINGLE_TOUCH_DOWN: + os << "GESTURE_FIRST_SINGLE_TOUCH_DOWN"; + break; + case GestureEventListener::GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN: + os << "GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN"; + break; + case GestureEventListener::GESTURE_FIRST_SINGLE_TOUCH_UP: + os << "GESTURE_FIRST_SINGLE_TOUCH_UP"; + break; + case GestureEventListener::GESTURE_SECOND_SINGLE_TOUCH_DOWN: + os << "GESTURE_SECOND_SINGLE_TOUCH_DOWN"; + break; + case GestureEventListener::GESTURE_LONG_TOUCH_DOWN: + os << "GESTURE_LONG_TOUCH_DOWN"; + break; + case GestureEventListener::GESTURE_MULTI_TOUCH_DOWN: + os << "GESTURE_MULTI_TOUCH_DOWN"; + break; + case GestureEventListener::GESTURE_PINCH: + os << "GESTURE_PINCH"; + break; + case GestureEventListener::GESTURE_ONE_TOUCH_PINCH: + os << "GESTURE_ONE_TOUCH_PINCH"; + break; + } + + return os; +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/apz/src/GestureEventListener.h b/gfx/layers/apz/src/GestureEventListener.h index aa51889fdd..bf50d4f40a 100644 --- a/gfx/layers/apz/src/GestureEventListener.h +++ b/gfx/layers/apz/src/GestureEventListener.h @@ -7,6 +7,7 @@ #ifndef mozilla_layers_GestureEventListener_h #define mozilla_layers_GestureEventListener_h +#include <iosfwd> #include "InputData.h" // for MultiTouchInput, etc #include "Units.h" #include "mozilla/EventForwards.h" // for nsEventStatus @@ -135,6 +136,8 @@ class GestureEventListener final { GESTURE_ONE_TOUCH_PINCH }; + friend std::ostream& operator<<(std::ostream& os, GestureState aState); + /** * These HandleInput* functions comprise input alphabet of the GEL * finite-state machine triggering state transitions. |