APZEventState.h (5965B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_layers_APZEventState_h 8 #define mozilla_layers_APZEventState_h 9 10 #include <stdint.h> 11 12 #include "ElementStateManager.h" 13 #include "Units.h" 14 #include "mozilla/EventForwards.h" 15 #include "mozilla/layers/GeckoContentControllerTypes.h" // for APZStateChange 16 #include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid 17 #include "mozilla/layers/TouchCounter.h" // for TouchCounter 18 #include "mozilla/RefPtr.h" 19 #include "mozilla/StaticPrefs_ui.h" 20 #include "nsCOMPtr.h" 21 #include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING 22 #include "nsITimer.h" 23 #include "nsIWeakReferenceUtils.h" // for nsWeakPtr 24 25 #include <functional> 26 27 template <class> 28 class nsCOMPtr; 29 class nsIContent; 30 class nsIWidget; 31 32 namespace mozilla { 33 34 class PresShell; 35 enum class PreventDefaultResult : uint8_t; 36 37 namespace layers { 38 39 class ElementStateManager; 40 41 enum class SynthesizeForTests : bool; // Defined in APZCCallbackHelper.cpp 42 43 namespace apz { 44 enum class PrecedingPointerDown : bool { NotConsumed, ConsumedByContent }; 45 enum class SingleTapState : uint8_t; 46 } // namespace apz 47 48 typedef std::function<void(uint64_t /* input block id */, 49 bool /* prevent default */)> 50 ContentReceivedInputBlockCallback; 51 52 /** 53 * A content-side component that keeps track of state for handling APZ 54 * gestures and sending APZ notifications. 55 */ 56 class APZEventState final { 57 typedef GeckoContentController_APZStateChange APZStateChange; 58 typedef ScrollableLayerGuid::ViewID ViewID; 59 60 public: 61 using PrecedingPointerDown = apz::PrecedingPointerDown; 62 63 APZEventState(nsIWidget* aWidget, 64 ContentReceivedInputBlockCallback&& aCallback); 65 66 NS_INLINE_DECL_REFCOUNTING(APZEventState); 67 68 MOZ_CAN_RUN_SCRIPT 69 void ProcessSingleTap(const CSSPoint& aPoint, 70 const CSSToLayoutDeviceScale& aScale, 71 Modifiers aModifiers, int32_t aClickCount, 72 uint64_t aInputBlockId); 73 MOZ_CAN_RUN_SCRIPT 74 void ProcessLongTap(PresShell* aPresShell, const CSSPoint& aPoint, 75 const CSSToLayoutDeviceScale& aScale, 76 Modifiers aModifiers, uint64_t aInputBlockId); 77 MOZ_CAN_RUN_SCRIPT 78 void ProcessLongTapUp(PresShell* aPresShell, const CSSPoint& aPoint, 79 const CSSToLayoutDeviceScale& aScale, 80 Modifiers aModifiers); 81 void ProcessTouchEvent(const WidgetTouchEvent& aEvent, 82 const ScrollableLayerGuid& aGuid, 83 uint64_t aInputBlockId, nsEventStatus aApzResponse, 84 nsEventStatus aContentResponse, 85 nsTArray<TouchBehaviorFlags>&& aAllowedTouchBehaviors); 86 void ProcessWheelEvent(const WidgetWheelEvent& aEvent, 87 uint64_t aInputBlockId); 88 void ProcessMouseEvent(const WidgetMouseEvent& aEvent, 89 uint64_t aInputBlockId); 90 void ProcessAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg, 91 Maybe<uint64_t> aInputBlockId); 92 /** 93 * Cleanup on destroy window. 94 */ 95 void Destroy(); 96 97 private: 98 ~APZEventState(); 99 void SendPendingTouchPreventedResponse(bool aPreventDefault); 100 MOZ_CAN_RUN_SCRIPT PreventDefaultResult FireContextmenuEvents( 101 PresShell* aPresShell, const CSSPoint& aPoint, 102 const CSSToLayoutDeviceScale& aScale, uint32_t aPointerId, 103 Modifiers aModifiers, const nsCOMPtr<nsIWidget>& aWidget, 104 SynthesizeForTests aSynthesizeForTests); 105 already_AddRefed<nsIWidget> GetWidget() const; 106 already_AddRefed<nsIContent> GetTouchRollup() const; 107 bool MainThreadAgreesEventsAreConsumableByAPZ() const; 108 109 private: 110 nsWeakPtr mWidget; 111 RefPtr<ElementStateManager> mElementStateManager; 112 ContentReceivedInputBlockCallback mContentReceivedInputBlockCallback; 113 TouchCounter mTouchCounter; 114 ScrollableLayerGuid mPendingTouchPreventedGuid; 115 uint64_t mPendingTouchPreventedBlockId; 116 apz::SingleTapState mEndTouchState; 117 PrecedingPointerDown mPrecedingPointerDownState = 118 PrecedingPointerDown::NotConsumed; 119 SynthesizeForTests mLastTouchSynthesizedForTests{false}; 120 bool mPendingTouchPreventedResponse = false; 121 bool mFirstTouchCancelled = false; 122 bool mTouchEndCancelled = false; 123 // Set to true when we have received any one of 124 // touch-move/touch-end/touch-cancel events in the touch block being 125 // processed. 126 bool mReceivedNonTouchStart = false; 127 bool mTouchStartPrevented = false; 128 129 int32_t mLastTouchIdentifier = 0; 130 nsTArray<TouchBehaviorFlags> mTouchBlockAllowedBehaviors; 131 132 // Because touch-triggered mouse events (e.g. mouse events from a tap 133 // gesture) happen asynchronously from the touch events themselves, we 134 // need to stash and replicate some of the state from the touch events 135 // to the mouse events. One piece of state is the rollup content, which 136 // is the content for which a popup window was recently closed. If we 137 // don't replicate this state properly during the mouse events, the 138 // synthetic click might reopen a popup window that was just closed by 139 // the touch event, which is undesirable. See also documentation in 140 // nsAutoRollup.h 141 // Note that in cases where we get multiple touch blocks interleaved with 142 // their single-tap event notifications, mTouchRollup may hold an incorrect 143 // value. This is kind of an edge case, and falls in the same category of 144 // problems as bug 1227241. I intend that fixing that bug will also take 145 // care of this potential problem. 146 nsWeakPtr mTouchRollup; 147 }; 148 149 } // namespace layers 150 } // namespace mozilla 151 152 #endif /* mozilla_layers_APZEventState_h */