Add APZ support for mousewheel delta multiplier prefs. (bug 1214170 part 2, r=kats)
authorDavid Anderson <danderson@mozilla.com>
Tue, 01 Dec 2015 13:46:07 -0800
changeset 275121 81783ea8202490f831e6bf4db961cbcb42601c58
parent 275120 fffdbaaac8a1e76960816e02a08d673c2d59dc57
child 275122 608d89fa125b1fb9652774ca8192831775637402
push id29747
push usercbook@mozilla.com
push dateWed, 02 Dec 2015 14:21:19 +0000
treeherdermozilla-central@f6ac392322b3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1214170
milestone45.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Add APZ support for mousewheel delta multiplier prefs. (bug 1214170 part 2, r=kats)
dom/events/EventStateManager.cpp
dom/events/EventStateManager.h
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/AsyncPanZoomController.cpp
widget/InputData.cpp
widget/InputData.h
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -5711,37 +5711,42 @@ EventStateManager::WheelPrefs::NeedToCom
 {
   Index index = GetIndexFor(aEvent);
   Init(index);
 
   return (mMultiplierX[index] != 1.0 && mMultiplierX[index] != -1.0) ||
          (mMultiplierY[index] != 1.0 && mMultiplierY[index] != -1.0);
 }
 
-bool
-EventStateManager::WheelPrefs::HasUserPrefsForDelta(WidgetWheelEvent* aEvent)
+void
+EventStateManager::WheelPrefs::GetUserPrefsForEvent(WidgetWheelEvent* aEvent,
+                                                    double* aOutMultiplierX,
+                                                    double* aOutMultiplierY)
 {
   Index index = GetIndexFor(aEvent);
   Init(index);
 
-  return mMultiplierX[index] != 1.0 ||
-         mMultiplierY[index] != 1.0;
+  *aOutMultiplierX = mMultiplierX[index];
+  *aOutMultiplierY = mMultiplierY[index];
 }
 
 bool
 EventStateManager::WheelEventIsScrollAction(WidgetWheelEvent* aEvent)
 {
   return aEvent->mMessage == eWheel &&
          WheelPrefs::GetInstance()->ComputeActionFor(aEvent) == WheelPrefs::ACTION_SCROLL;
 }
 
-bool
-EventStateManager::WheelEventNeedsDeltaMultipliers(WidgetWheelEvent* aEvent)
+void
+EventStateManager::GetUserPrefsForWheelEvent(WidgetWheelEvent* aEvent,
+                                             double* aOutMultiplierX,
+                                             double* aOutMultiplierY)
 {
-  return WheelPrefs::GetInstance()->HasUserPrefsForDelta(aEvent);
+  WheelPrefs::GetInstance()->GetUserPrefsForEvent(
+    aEvent, aOutMultiplierX, aOutMultiplierY);
 }
 
 bool
 EventStateManager::WheelPrefs::IsOverOnePageScrollAllowedX(
                                  WidgetWheelEvent* aEvent)
 {
   Index index = GetIndexFor(aEvent);
   Init(index);
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -237,19 +237,20 @@ public:
   // Sets the full-screen event state on aElement to aIsFullScreen.
   static void SetFullScreenState(dom::Element* aElement, bool aIsFullScreen);
 
   static bool IsRemoteTarget(nsIContent* aTarget);
 
   // Returns true if the given WidgetWheelEvent will resolve to a scroll action.
   static bool WheelEventIsScrollAction(WidgetWheelEvent* aEvent);
 
-  // Returns true if user prefs for wheel deltas apply to the given
-  // WidgetWheelEvent.
-  static bool WheelEventNeedsDeltaMultipliers(WidgetWheelEvent* aEvent);
+  // Returns user-set multipliers for a wheel event.
+  static void GetUserPrefsForWheelEvent(WidgetWheelEvent* aEvent,
+                                        double* aOutMultiplierX,
+                                        double* aOutMultiplierY);
 
   // Returns whether or not a frame can be vertically scrolled with a mouse
   // wheel (as opposed to, say, a selection or touch scroll).
   static bool CanVerticallyScrollFrameWithWheel(nsIFrame* aFrame);
 
   // Holds the point in screen coords that a mouse event was dispatched to,
   // before we went into pointer lock mode. This is constantly updated while
   // the pointer is not locked, but we don't update it while the pointer is
@@ -444,17 +445,19 @@ protected:
      * user prefs.
      */
     void ApplyUserPrefsToDelta(WidgetWheelEvent* aEvent);
 
     /**
      * Returns whether or not ApplyUserPrefsToDelta() would change the delta
      * values of an event.
      */
-    bool HasUserPrefsForDelta(WidgetWheelEvent* aEvent);
+    void GetUserPrefsForEvent(WidgetWheelEvent* aEvent,
+                              double* aOutMultiplierX,
+                              double* aOutMultiplierY);
 
     /**
      * If ApplyUserPrefsToDelta() changed the delta values with customized
      * prefs, the overflowDelta values would be inflated.
      * CancelApplyingUserPrefsFromOverflowDelta() cancels the inflation.
      */
     void CancelApplyingUserPrefsFromOverflowDelta(WidgetWheelEvent* aEvent);
 
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -621,18 +621,17 @@ APZCTreeManager::UpdateHitTestingTree(Tr
 //
 // Even if this returns false, all wheel events in APZ-aware widgets must
 // be sent through APZ so they are transformed correctly for TabParent.
 static bool
 WillHandleWheelEvent(WidgetWheelEvent* aEvent)
 {
   return EventStateManager::WheelEventIsScrollAction(aEvent) &&
          (aEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_LINE ||
-          aEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL) &&
-         !EventStateManager::WheelEventNeedsDeltaMultipliers(aEvent);
+          aEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL);
 }
 
 static bool
 WillHandleMouseEvent(const WidgetMouseEventBase& aEvent)
 {
   if (!gfxPrefs::APZDragEnabled()) {
     return false;
   }
@@ -1085,18 +1084,27 @@ APZCTreeManager::ProcessWheelEvent(Widge
     scrollMode = ScrollWheelInput::SCROLLMODE_SMOOTH;
   }
 
   ScreenPoint origin(aEvent.refPoint.x, aEvent.refPoint.y);
   ScrollWheelInput input(aEvent.time, aEvent.timeStamp, 0,
                          scrollMode,
                          ScrollWheelInput::DeltaTypeForDeltaMode(aEvent.deltaMode),
                          origin,
-                         aEvent.deltaX,
-                         aEvent.deltaY);
+                         aEvent.deltaX, aEvent.deltaY);
+
+  // We add the user multiplier as a separate field, rather than premultiplying
+  // it, because if the input is converted back to a WidgetWheelEvent, then
+  // EventStateManager would apply the delta a second time. We could in theory
+  // work around this by asking ESM to customize the event much sooner, and
+  // then save the "customizedByUserPrefs" bit on ScrollWheelInput - but for
+  // now, this seems easier.
+  EventStateManager::GetUserPrefsForWheelEvent(&aEvent,
+    &input.mUserDeltaMultiplierX,
+    &input.mUserDeltaMultiplierY);
 
   nsEventStatus status = ReceiveInputEvent(input, aOutTargetGuid, aOutInputBlockId);
   aEvent.refPoint.x = input.mOrigin.x;
   aEvent.refPoint.y = input.mOrigin.y;
   aEvent.mFlags.mHandledByAPZ = input.mHandledByAPZ;
   return status;
 }
 
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -1599,17 +1599,28 @@ AsyncPanZoomController::GetScrollWheelDe
     case ScrollWheelInput::SCROLLDELTA_PIXEL: {
       delta = ToParentLayerCoordinates(ScreenPoint(aEvent.mDeltaX, aEvent.mDeltaY), aEvent.mOrigin);
       break;
     }
     default:
       MOZ_ASSERT_UNREACHABLE("unexpected scroll delta type");
   }
 
-  if (isRootContent && gfxPrefs::MouseWheelHasRootScrollDeltaOverride()) {
+  // Apply user-set multipliers.
+  delta.x *= aEvent.mUserDeltaMultiplierX;
+  delta.y *= aEvent.mUserDeltaMultiplierY;
+
+  // For the conditions under which we allow system scroll overrides, see
+  // EventStateManager::DeltaAccumulator::ComputeScrollAmountForDefaultAction
+  // and WheelTransaction::OverrideSystemScrollSpeed.
+  if (isRootContent &&
+      gfxPrefs::MouseWheelHasRootScrollDeltaOverride() &&
+      !aEvent.IsCustomizedByUserPrefs() &&
+      aEvent.mDeltaType == ScrollWheelInput::SCROLLDELTA_LINE)
+  {
     // Only apply delta multipliers if we're increasing the delta.
     double hfactor = double(gfxPrefs::MouseWheelRootHScrollDeltaFactor()) / 100;
     double vfactor = double(gfxPrefs::MouseWheelRootVScrollDeltaFactor()) / 100;
     if (vfactor > 1.0) {
       delta.x *= hfactor;
     }
     if (hfactor > 1.0) {
       delta.y *= vfactor;
--- a/widget/InputData.cpp
+++ b/widget/InputData.cpp
@@ -371,16 +371,18 @@ ScrollWheelInput::ScrollWheelInput(const
   InputData(SCROLLWHEEL_INPUT, aWheelEvent.time, aWheelEvent.timeStamp, aWheelEvent.modifiers),
   mDeltaType(DeltaTypeForDeltaMode(aWheelEvent.deltaMode)),
   mScrollMode(SCROLLMODE_INSTANT),
   mHandledByAPZ(aWheelEvent.mFlags.mHandledByAPZ),
   mDeltaX(aWheelEvent.deltaX),
   mDeltaY(aWheelEvent.deltaY),
   mLineOrPageDeltaX(aWheelEvent.lineOrPageDeltaX),
   mLineOrPageDeltaY(aWheelEvent.lineOrPageDeltaY),
+  mUserDeltaMultiplierX(1.0),
+  mUserDeltaMultiplierY(1.0),
   mIsMomentum(aWheelEvent.isMomentum)
 {
   mOrigin =
     ScreenPoint(ViewAs<ScreenPixel>(aWheelEvent.refPoint,
       PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
 }
 
 WidgetWheelEvent
@@ -410,9 +412,16 @@ ScrollWheelInput::TransformToLocal(const
   Maybe<ParentLayerPoint> point = UntransformTo<ParentLayerPixel>(aTransform, mOrigin);
   if (!point) {
     return false;
   }
   mLocalOrigin = *point;
   return true;
 }
 
+bool
+ScrollWheelInput::IsCustomizedByUserPrefs() const
+{
+  return mUserDeltaMultiplierX != 1.0 ||
+         mUserDeltaMultiplierY != 1.0;
+}
+
 } // namespace mozilla
--- a/widget/InputData.h
+++ b/widget/InputData.h
@@ -578,24 +578,28 @@ public:
      mScrollMode(aScrollMode),
      mOrigin(aOrigin),
      mHandledByAPZ(false),
      mDeltaX(aDeltaX),
      mDeltaY(aDeltaY),
      mLineOrPageDeltaX(0),
      mLineOrPageDeltaY(0),
      mScrollSeriesNumber(0),
+     mUserDeltaMultiplierX(1.0),
+     mUserDeltaMultiplierY(1.0),
      mIsMomentum(false)
   {}
 
   explicit ScrollWheelInput(const WidgetWheelEvent& aEvent);
 
   WidgetWheelEvent ToWidgetWheelEvent(nsIWidget* aWidget) const;
   bool TransformToLocal(const gfx::Matrix4x4& aTransform);
 
+  bool IsCustomizedByUserPrefs() const;
+
   ScrollDeltaType mDeltaType;
   ScrollMode mScrollMode;
   ScreenPoint mOrigin;
 
   bool mHandledByAPZ;
 
   // Deltas are in units corresponding to the delta type. For line deltas, they
   // are the number of line units to scroll. The number of device pixels for a
@@ -615,14 +619,18 @@ public:
   // See lineOrPageDeltaX/Y on WidgetWheelEvent.
   int32_t mLineOrPageDeltaX;
   int32_t mLineOrPageDeltaY;
 
   // Indicates the order in which this event was added to a transaction. The
   // first event is 1; if not a member of a transaction, this is 0.
   uint32_t mScrollSeriesNumber;
 
+  // User-set delta multipliers.
+  double mUserDeltaMultiplierX;
+  double mUserDeltaMultiplierY;
+
   bool mIsMomentum;
 };
 
 } // namespace mozilla
 
 #endif // InputData_h__