tor-browser

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

AutoscrollAnimation.cpp (3400B)


      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 #include "AutoscrollAnimation.h"
      8 
      9 #include <cmath>  // for sqrtf()
     10 
     11 #include "AsyncPanZoomController.h"
     12 #include "APZCTreeManager.h"
     13 #include "FrameMetrics.h"
     14 
     15 namespace mozilla {
     16 namespace layers {
     17 
     18 // Helper function for AutoscrollAnimation::DoSample().
     19 // Basically copied as-is from toolkit/actors/AutoScrollChild.sys.mjs.
     20 static float Accelerate(ScreenCoord curr, ScreenCoord start) {
     21  static const int speed = 12;
     22  float val = (curr - start) / speed;
     23  if (val > 1) {
     24    return val * sqrtf(val) - 1;
     25  }
     26  if (val < -1) {
     27    return val * sqrtf(-val) + 1;
     28  }
     29  return 0;
     30 }
     31 
     32 AutoscrollAnimation::AutoscrollAnimation(AsyncPanZoomController& aApzc,
     33                                         const ScreenPoint& aAnchorLocation)
     34    : mApzc(aApzc), mAnchorLocation(aAnchorLocation) {}
     35 
     36 bool AutoscrollAnimation::DoSample(FrameMetrics& aFrameMetrics,
     37                                   const TimeDuration& aDelta) {
     38  APZCTreeManager* treeManager = mApzc.GetApzcTreeManager();
     39  if (!treeManager) {
     40    return false;
     41  }
     42 
     43  ScreenPoint mouseLocation = treeManager->GetCurrentMousePosition();
     44 
     45  // The implementation of this function closely mirrors that of its main-
     46  // thread equivalent, the autoscrollLoop() function in
     47  // toolkit/actors/AutoScrollChild.jsm.
     48 
     49  // Avoid long jumps when the browser hangs for more than |maxTimeDelta| ms.
     50  static const TimeDuration maxTimeDelta = TimeDuration::FromMilliseconds(100);
     51  TimeDuration timeDelta = TimeDuration::Min(aDelta, maxTimeDelta);
     52 
     53  float timeCompensation = timeDelta.ToMilliseconds() / 20;
     54 
     55  // Notes:
     56  //   - The main-thread implementation rounds the scroll delta to an integer,
     57  //     and keeps track of the fractional part as an "error". It does this
     58  //     because it uses Window.scrollBy() or Element.scrollBy() to perform
     59  //     the scrolling, and those functions truncate the fractional part of
     60  //     the offset. APZ does no such truncation, so there's no need to keep
     61  //     track of the fractional part separately.
     62  //   - The Accelerate() function takes Screen coordinates as inputs, but
     63  //     its output is interpreted as CSS coordinates. This is intentional,
     64  //     insofar as autoscrollLoop() does the same thing.
     65  CSSPoint scrollDelta{
     66      Accelerate(mouseLocation.x, mAnchorLocation.x) * timeCompensation,
     67      Accelerate(mouseLocation.y, mAnchorLocation.y) * timeCompensation};
     68 
     69  mApzc.ScrollByAndClamp(scrollDelta);
     70 
     71  // An autoscroll animation never ends of its own accord.
     72  // It can be stopped in response to various input events, in which case
     73  // AsyncPanZoomController::StopAutoscroll() will stop it via
     74  // CancelAnimation().
     75  return true;
     76 }
     77 
     78 void AutoscrollAnimation::Cancel(CancelAnimationFlags aFlags) {
     79  // The cancellation was initiated by browser.js, so there's no need to
     80  // notify it.
     81  if (aFlags & TriggeredExternally) {
     82    return;
     83  }
     84 
     85  if (RefPtr<GeckoContentController> controller =
     86          mApzc.GetGeckoContentController()) {
     87    controller->CancelAutoscroll(mApzc.GetGuid());
     88  }
     89 }
     90 
     91 }  // namespace layers
     92 }  // namespace mozilla