tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 */