OverscrollHandoffState.h (8000B)
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_OverscrollHandoffChain_h 8 #define mozilla_layers_OverscrollHandoffChain_h 9 10 #include <vector> 11 #include "mozilla/RefPtr.h" // for RefPtr 12 #include "nsISupportsImpl.h" // for NS_INLINE_DECL_THREADSAFE_REFCOUNTING 13 #include "APZUtils.h" // for CancelAnimationFlags 14 #include "mozilla/layers/LayersTypes.h" // for Layer::ScrollDirection 15 #include "Units.h" // for ScreenPoint 16 17 namespace mozilla { 18 19 class InputData; 20 21 namespace layers { 22 23 class AsyncPanZoomController; 24 25 /** 26 * This class represents the chain of APZCs along which overscroll is handed 27 * off. It is created by APZCTreeManager by starting from an initial APZC which 28 * is the target for input events, and following the scroll parent ID links 29 * (often but not always corresponding to parent pointers in the APZC tree). 30 */ 31 class OverscrollHandoffChain { 32 protected: 33 // Reference-counted classes cannot have public destructors. 34 ~OverscrollHandoffChain(); 35 36 public: 37 // Threadsafe so that the controller and sampler threads can both maintain 38 // nsRefPtrs to the same handoff chain. 39 // Mutable so that we can pass around the class by 40 // RefPtr<const OverscrollHandoffChain> and thus enforce that, once built, 41 // the chain is not modified. 42 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OverscrollHandoffChain) 43 44 /* 45 * Methods for building the handoff chain. 46 * These should be used only by 47 * AsyncPanZoomController::BuildOverscrollHandoffChain(). 48 */ 49 void Add(AsyncPanZoomController* aApzc); 50 void SortByScrollPriority(); 51 52 /* 53 * Methods for accessing the handoff chain. 54 */ 55 uint32_t Length() const { return mChain.size(); } 56 const RefPtr<AsyncPanZoomController>& GetApzcAtIndex(uint32_t aIndex) const; 57 // Returns Length() if |aApzc| is not on this chain. 58 uint32_t IndexOf(const AsyncPanZoomController* aApzc) const; 59 60 /* 61 * Convenience methods for performing operations on APZCs in the chain. 62 */ 63 64 // Flush repaints all the way up the chain. 65 void FlushRepaints() const; 66 67 // Cancel animations all the way up the chain. 68 void CancelAnimations(CancelAnimationFlags aFlags = Default) const; 69 70 // Clear overscroll all the way up the chain. 71 void ClearOverscroll() const; 72 73 // Snap back the APZC that is overscrolled on the subset of the chain from 74 // |aStart| onwards, if any. 75 void SnapBackOverscrolledApzc(const AsyncPanZoomController* aStart) const; 76 77 // Similar to above SnapbackOverscrolledApzc but for pan gestures with 78 // momentum events, this function doesn't end up calling each APZC's 79 // ScrollSnap. 80 // |aVelocity| is the initial velocity of |aStart|. 81 void SnapBackOverscrolledApzcForMomentum( 82 const AsyncPanZoomController* aStart, 83 const ParentLayerPoint& aVelocity) const; 84 85 // Determine whether the given APZC, or any APZC further in the chain, 86 // has room to be panned. 87 bool CanBePanned(const AsyncPanZoomController* aApzc) const; 88 89 // Determine whether the given APZC, or any APZC further in the chain, 90 // can scroll in the given direction. 91 bool CanScrollInDirection(const AsyncPanZoomController* aApzc, 92 ScrollDirection aDirection) const; 93 94 // Determine whether any APZC along this handoff chain is overscrolled. 95 bool HasOverscrolledApzc() const; 96 97 // Determine whether any APZC along this handoff chain has been flung fast. 98 bool HasFastFlungApzc() const; 99 100 // Determine whether any APZC along this handoff chain is autoscroll. 101 bool HasAutoscrollApzc() const; 102 103 // Find the first APZC in this handoff chain that can be scrolled by |aInput|. 104 // Since overscroll-behavior can restrict handoff in some directions, 105 // |aOutAllowedScrollDirections| is populated with the scroll directions 106 // in which scrolling of the returned APZC is allowed. 107 // |aIncludeOverscroll| is an optional flag whether to consider overscrollable 108 // as scrollable or not. 109 enum class IncludeOverscroll : bool { No, Yes }; 110 RefPtr<AsyncPanZoomController> FindFirstScrollable( 111 const InputData& aInput, ScrollDirections* aOutAllowedScrollDirections, 112 IncludeOverscroll aIncludeOverscroll = IncludeOverscroll::Yes) const; 113 114 // Return a pair of true and the root content APZC if all non-root APZCs in 115 // this handoff chain starting from |aApzc| are not able to scroll downwards 116 // (i.e. there is no room to scroll downwards in each APZC respectively) and 117 // there is any contents covered by the dynamic toolbar, otherwise return a 118 // pair of false and nullptr. 119 std::tuple<bool, const AsyncPanZoomController*> 120 ScrollingDownWillMoveDynamicToolbar( 121 const AsyncPanZoomController* aApzc) const; 122 123 bool ScrollingUpWillTriggerPullToRefresh( 124 const AsyncPanZoomController* aApzc) const; 125 126 private: 127 std::vector<RefPtr<AsyncPanZoomController>> mChain; 128 129 typedef void (AsyncPanZoomController::*APZCMethod)(); 130 typedef bool (AsyncPanZoomController::*APZCPredicate)() const; 131 void ForEachApzc(APZCMethod aMethod) const; 132 bool AnyApzc(APZCPredicate aPredicate) const; 133 }; 134 135 /** 136 * This class groups the state maintained during overscroll handoff. 137 */ 138 struct OverscrollHandoffState { 139 OverscrollHandoffState(const OverscrollHandoffChain& aChain, 140 const ScreenPoint& aPanDistance, 141 ScrollSource aScrollSource) 142 : mChain(aChain), 143 mChainIndex(0), 144 mPanDistance(aPanDistance), 145 mScrollSource(aScrollSource) {} 146 147 // The chain of APZCs along which we hand off scroll. 148 // This is const to indicate that the chain does not change over the 149 // course of handoff. 150 const OverscrollHandoffChain& mChain; 151 152 // The index of the APZC in the chain that we are currently giving scroll to. 153 // This is non-const to indicate that this changes over the course of handoff. 154 uint32_t mChainIndex; 155 156 // The total distance since touch-start of the pan that triggered the 157 // handoff. This is const to indicate that it does not change over the 158 // course of handoff. 159 // The x/y components of this are non-negative. 160 const ScreenPoint mPanDistance; 161 162 ScrollSource mScrollSource; 163 164 // The total amount of actual movement that this scroll caused, including 165 // scrolling and changes to overscroll. This starts at zero and is accumulated 166 // over the course of the handoff. 167 ScreenPoint mTotalMovement; 168 }; 169 170 /* 171 * This class groups the state maintained during fling handoff. 172 */ 173 struct FlingHandoffState { 174 // The velocity of the fling being handed off. 175 ParentLayerPoint mVelocity; 176 177 // The chain of APZCs along which we hand off the fling. 178 // Unlike in OverscrollHandoffState, this is stored by RefPtr because 179 // otherwise it may not stay alive for the entire handoff. 180 RefPtr<const OverscrollHandoffChain> mChain; 181 182 // The time duration between the touch start and the touch move that started 183 // the pan gesture which triggered this fling. In other words, the time it 184 // took for the finger to move enough to cross the touch slop threshold. 185 // Nothing if this fling was not immediately caused by a touch pan. 186 Maybe<TimeDuration> mTouchStartRestingTime; 187 188 // The slowest panning velocity encountered during the pan that triggered this 189 // fling. 190 ParentLayerCoord mMinPanVelocity; 191 192 // Whether handoff has happened by this point, or we're still process 193 // the original fling. 194 bool mIsHandoff; 195 196 // The single APZC that was scrolled by the pan that started this fling. 197 // The fling is only allowed to scroll this APZC, too. 198 // Used only if immediate scroll handoff is disallowed. 199 RefPtr<const AsyncPanZoomController> mScrolledApzc; 200 }; 201 202 } // namespace layers 203 } // namespace mozilla 204 205 #endif /* mozilla_layers_OverscrollHandoffChain_h */