/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_layers_APZEventState_h #define mozilla_layers_APZEventState_h #include #include "ActiveElementManager.h" #include "Units.h" #include "mozilla/EventForwards.h" #include "mozilla/layers/GeckoContentControllerTypes.h" // for APZStateChange #include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid #include "mozilla/layers/TouchCounter.h" // for TouchCounter #include "mozilla/RefPtr.h" #include "mozilla/StaticPrefs_ui.h" #include "nsCOMPtr.h" #include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING #include "nsITimer.h" #include "nsIWeakReferenceUtils.h" // for nsWeakPtr #include #include template class nsCOMPtr; class nsIContent; class nsIWidget; namespace mozilla { class PresShell; enum class PreventDefaultResult : uint8_t; namespace layers { class ActiveElementManager; typedef std::function ContentReceivedInputBlockCallback; /** * A content-side component that keeps track of state for handling APZ * gestures and sending APZ notifications. */ class APZEventState final { typedef GeckoContentController_APZStateChange APZStateChange; typedef ScrollableLayerGuid::ViewID ViewID; public: APZEventState(nsIWidget* aWidget, ContentReceivedInputBlockCallback&& aCallback); NS_INLINE_DECL_REFCOUNTING(APZEventState); MOZ_CAN_RUN_SCRIPT void ProcessSingleTap(const CSSPoint& aPoint, const CSSToLayoutDeviceScale& aScale, Modifiers aModifiers, int32_t aClickCount, uint64_t aInputBlockId); MOZ_CAN_RUN_SCRIPT void ProcessLongTap(PresShell* aPresShell, const CSSPoint& aPoint, const CSSToLayoutDeviceScale& aScale, Modifiers aModifiers, uint64_t aInputBlockId); MOZ_CAN_RUN_SCRIPT void ProcessLongTapUp(PresShell* aPresShell, const CSSPoint& aPoint, const CSSToLayoutDeviceScale& aScale, Modifiers aModifiers); void ProcessTouchEvent(const WidgetTouchEvent& aEvent, const ScrollableLayerGuid& aGuid, uint64_t aInputBlockId, nsEventStatus aApzResponse, nsEventStatus aContentResponse, nsTArray&& aAllowedTouchBehaviors); void ProcessWheelEvent(const WidgetWheelEvent& aEvent, uint64_t aInputBlockId); void ProcessMouseEvent(const WidgetMouseEvent& aEvent, uint64_t aInputBlockId); void ProcessAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg, Maybe aInputBlockId); /** * Cleanup on destroy window. */ void Destroy(); private: ~APZEventState(); void SendPendingTouchPreventedResponse(bool aPreventDefault); MOZ_CAN_RUN_SCRIPT PreventDefaultResult FireContextmenuEvents( PresShell* aPresShell, const CSSPoint& aPoint, const CSSToLayoutDeviceScale& aScale, Modifiers aModifiers, const nsCOMPtr& aWidget); already_AddRefed GetWidget() const; already_AddRefed GetTouchRollup() const; bool MainThreadAgreesEventsAreConsumableByAPZ() const; private: nsWeakPtr mWidget; RefPtr mActiveElementManager; ContentReceivedInputBlockCallback mContentReceivedInputBlockCallback; TouchCounter mTouchCounter; bool mPendingTouchPreventedResponse; ScrollableLayerGuid mPendingTouchPreventedGuid; uint64_t mPendingTouchPreventedBlockId; bool mEndTouchIsClick; bool mFirstTouchCancelled; bool mTouchEndCancelled; // Set to true when we have received any one of // touch-move/touch-end/touch-cancel events in the touch block being // processed. bool mReceivedNonTouchStart; bool mTouchStartPrevented; int32_t mLastTouchIdentifier; nsTArray mTouchBlockAllowedBehaviors; // Because touch-triggered mouse events (e.g. mouse events from a tap // gesture) happen asynchronously from the touch events themselves, we // need to stash and replicate some of the state from the touch events // to the mouse events. One piece of state is the rollup content, which // is the content for which a popup window was recently closed. If we // don't replicate this state properly during the mouse events, the // synthetic click might reopen a popup window that was just closed by // the touch event, which is undesirable. See also documentation in // nsAutoRollup.h // Note that in cases where we get multiple touch blocks interleaved with // their single-tap event notifications, mTouchRollup may hold an incorrect // value. This is kind of an edge case, and falls in the same category of // problems as bug 1227241. I intend that fixing that bug will also take // care of this potential problem. nsWeakPtr mTouchRollup; }; } // namespace layers } // namespace mozilla #endif /* mozilla_layers_APZEventState_h */