DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (c073e3faa76e)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
/* -*- 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_WheelHandlingHelper_h_
#define mozilla_WheelHandlingHelper_h_

#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "nsCoord.h"
#include "nsIFrame.h"
#include "nsPoint.h"

class nsIScrollableFrame;
class nsITimer;

namespace mozilla {

class EventStateManager;

/**
 * DeltaValues stores two delta values which are along X and Y axis.  This is
 * useful for arguments and results of some methods.
 */

struct DeltaValues {
  DeltaValues() : deltaX(0.0), deltaY(0.0) {}

  DeltaValues(double aDeltaX, double aDeltaY)
      : deltaX(aDeltaX), deltaY(aDeltaY) {}

  explicit DeltaValues(WidgetWheelEvent* aEvent);

  double deltaX;
  double deltaY;
};

/**
 * WheelHandlingUtils provides some static methods which are useful at handling
 * wheel events.
 */

class WheelHandlingUtils {
 public:
  /**
   * Returns true if aFrame is a scrollable frame and it can be scrolled to
   * either aDirectionX or aDirectionY along each axis.  Or if aFrame is a
   * plugin frame (in this case, aDirectionX and aDirectionY are ignored).
   * Otherwise, false.
   */
  static bool CanScrollOn(nsIFrame* aFrame, double aDirectionX,
                          double aDirectionY);
  /**
   * Returns true if the scrollable frame can be scrolled to either aDirectionX
   * or aDirectionY along each axis.  Otherwise, false.
   */
  static bool CanScrollOn(nsIScrollableFrame* aScrollFrame, double aDirectionX,
                          double aDirectionY);

  // For more details about the concept of a disregarded direction, refer to the
  // code in struct mozilla::layers::ScrollMetadata which defines
  // mDisregardedDirection.
  static Maybe<layers::ScrollDirection> GetDisregardedWheelScrollDirection(
      const nsIFrame* aFrame);

 private:
  static bool CanScrollInRange(nscoord aMin, nscoord aValue, nscoord aMax,
                               double aDirection);
};

/**
 * ScrollbarsForWheel manages scrollbars state during wheel operation.
 * E.g., on some platforms, scrollbars should show only while user attempts to
 * scroll.  At that time, scrollbars which may be possible to scroll by
 * operation of wheel at the point should show temporarily.
 */

class ScrollbarsForWheel {
 public:
  static void PrepareToScrollText(EventStateManager* aESM,
                                  nsIFrame* aTargetFrame,
                                  WidgetWheelEvent* aEvent);
  static void SetActiveScrollTarget(nsIScrollableFrame* aScrollTarget);
  // Hide all scrollbars (both mActiveOwner's and mActivatedScrollTargets')
  static void MayInactivate();
  static void Inactivate();
  static bool IsActive();
  static void OwnWheelTransaction(bool aOwn);

 protected:
  static const size_t kNumberOfTargets = 4;
  static const DeltaValues directions[kNumberOfTargets];
  static AutoWeakFrame sActiveOwner;
  static AutoWeakFrame sActivatedScrollTargets[kNumberOfTargets];
  static bool sHadWheelStart;
  static bool sOwnWheelTransaction;

  /**
   * These two methods are called upon eWheelOperationStart/eWheelOperationEnd
   * events to show/hide the right scrollbars.
   */
  static void TemporarilyActivateAllPossibleScrollTargets(
      EventStateManager* aESM, nsIFrame* aTargetFrame,
      WidgetWheelEvent* aEvent);
  static void DeactivateAllTemporarilyActivatedScrollTargets();
};

/**
 * WheelTransaction manages a series of wheel events as a transaction.
 * While in a transaction, every wheel event should scroll the same scrollable
 * element even if a different scrollable element is under the mouse cursor.
 *
 * Additionally, this class also manages wheel scroll speed acceleration.
 */

class WheelTransaction {
 public:
  static nsIFrame* GetTargetFrame() { return sTargetFrame; }
  static void EndTransaction();
  /**
   * WillHandleDefaultAction() is called before handling aWheelEvent on
   * aTargetFrame.
   *
   * @return    false if the caller cannot continue to handle the default
   *            action.  Otherwise, true.
   */
  static bool WillHandleDefaultAction(WidgetWheelEvent* aWheelEvent,
                                      AutoWeakFrame& aTargetWeakFrame);
  static bool WillHandleDefaultAction(WidgetWheelEvent* aWheelEvent,
                                      nsIFrame* aTargetFrame) {
    AutoWeakFrame targetWeakFrame(aTargetFrame);
    return WillHandleDefaultAction(aWheelEvent, targetWeakFrame);
  }
  static void OnEvent(WidgetEvent* aEvent);
  static void Shutdown();
  static uint32_t GetTimeoutTime() {
    return Prefs::sMouseWheelTransactionTimeout;
  }

  static void OwnScrollbars(bool aOwn);

  static DeltaValues AccelerateWheelDelta(WidgetWheelEvent* aEvent,
                                          bool aAllowScrollSpeedOverride);
  static void InitializeStatics() { Prefs::InitializeStatics(); }

 protected:
  static void BeginTransaction(nsIFrame* aTargetFrame,
                               const WidgetWheelEvent* aEvent);
  // Be careful, UpdateTransaction may fire a DOM event, therefore, the target
  // frame might be destroyed in the event handler.
  static bool UpdateTransaction(const WidgetWheelEvent* aEvent);
  static void MayEndTransaction();

  static LayoutDeviceIntPoint GetScreenPoint(WidgetGUIEvent* aEvent);
  static void OnFailToScrollTarget();
  static void OnTimeout(nsITimer* aTimer, void* aClosure);
  static void SetTimeout();
  static uint32_t GetIgnoreMoveDelayTime() {
    return Prefs::sMouseWheelTransactionIgnoreMoveDelay;
  }
  static int32_t GetAccelerationStart() {
    return Prefs::sMouseWheelAccelerationStart;
  }
  static int32_t GetAccelerationFactor() {
    return Prefs::sMouseWheelAccelerationFactor;
  }
  static DeltaValues OverrideSystemScrollSpeed(WidgetWheelEvent* aEvent);
  static double ComputeAcceleratedWheelDelta(double aDelta, int32_t aFactor);
  static bool OutOfTime(uint32_t aBaseTime, uint32_t aThreshold);

  static AutoWeakFrame sTargetFrame;
  static uint32_t sTime;        // in milliseconds
  static uint32_t sMouseMoved;  // in milliseconds
  static nsITimer* sTimer;
  static int32_t sScrollSeriesCounter;
  static bool sOwnScrollbars;

  class Prefs {
   public:
    static void InitializeStatics();
    static int32_t sMouseWheelAccelerationStart;
    static int32_t sMouseWheelAccelerationFactor;
    static uint32_t sMouseWheelTransactionTimeout;
    static uint32_t sMouseWheelTransactionIgnoreMoveDelay;
    static bool sTestMouseScroll;
  };
};

/**
 * When a wheel event should be treated as specially, e.g., it's a vertical
 * wheel operation but user wants to scroll the target horizontally, this
 * class adjust the delta values automatically.  Then, restores the original
 * value when the instance is destroyed.
 */
class MOZ_STACK_CLASS AutoWheelDeltaAdjuster final {
 public:
  /**
   * @param aWheelEvent        A wheel event.  The delta values may be
   *                           modified for default handler.
   *                           Its mDeltaValuesAdjustedForDefaultHandler
   *                           must not be true because if it's true,
   *                           the event has already been adjusted the
   *                           delta values for default handler.
   */
  explicit AutoWheelDeltaAdjuster(WidgetWheelEvent& aWheelEvent);
  ~AutoWheelDeltaAdjuster();

 private:
  WidgetWheelEvent& mWheelEvent;
  double mOldDeltaX;
  double mOldDeltaZ;
  double mOldOverflowDeltaX;
  int32_t mOldLineOrPageDeltaX;
  bool mTreatedVerticalWheelAsHorizontalScroll;
};

}  // namespace mozilla

#endif  // mozilla_WheelHandlingHelper_h_