Bug 1358017 - Part 1: Adds some comments, renames some identifiers and refactors some other trivial things. r?masayuki, kats draft
authorZhang Junzhi <zjz@zjz.name>
Thu, 15 Mar 2018 16:31:07 +0800
changeset 780965 e9f269cc89888d18c0854fde5984ac9cb32551c9
parent 780873 2318adaec61f07eccf66c3f742497aa973b15f2f
child 780966 f082822071c1cb8f1fd7daf307be29c1dc465764
push id106174
push userbmo:zjz@zjz.name
push dateThu, 12 Apr 2018 10:18:30 +0000
reviewersmasayuki, kats
bugs1358017
milestone61.0a1
Bug 1358017 - Part 1: Adds some comments, renames some identifiers and refactors some other trivial things. r?masayuki, kats Do some work in preparation for implementing actual functionalities for this bug. No actual functionality change is involved in this commit. MozReview-Commit-ID: 5aLhr38n1N4
dom/events/EventStateManager.cpp
dom/events/EventStateManager.h
dom/events/WheelHandlingHelper.cpp
dom/events/WheelHandlingHelper.h
dom/events/test/window_wheel_default_action.html
gfx/layers/apz/src/APZInputBridge.cpp
gfx/layers/apz/src/AsyncPanZoomController.h
widget/InputData.h
widget/MouseEvents.h
widget/nsGUIEventIPC.h
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3384,39 +3384,46 @@ EventStateManager::PostHandleEvent(nsPre
 
       // When APZ is enabled, the actual scroll animation might be handled by
       // the compositor.
       WheelPrefs::Action action =
         wheelEvent->mFlags.mHandledByAPZ ?
           WheelPrefs::ACTION_NONE :
           WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent);
 
-      // Make the wheel event a horizontal scroll event.  I.e., deltaY values
-      // are set to deltaX and deltaY and deltaZ values are set to 0.
-      // When AutoWheelDeltaAdjuster instance is destroyed, the delta values
-      // are restored and make overflow deltaX becomes 0.
-      AutoWheelDeltaAdjuster adjuster(*wheelEvent);
+      WheelDeltaAdjustmentStrategy strategy =
+        GetWheelDeltaAdjustmentStrategy(*wheelEvent);
+      // Adjust the delta values of the wheel event if the current default
+      // action is to horizontalize scrolling. I.e., deltaY values are set to
+      // deltaX and deltaY and deltaZ values are set to 0.
+      // If horizontalized, the delta values will be restored and its overflow
+      // deltaX will become 0 when the WheelDeltaHorizontalizer instance is
+      // being destroyed.
+      WheelDeltaHorizontalizer horizontalizer(*wheelEvent);
+      if (WheelDeltaAdjustmentStrategy::eHorizontalize == strategy) {
+        horizontalizer.Horizontalize();
+      }
 
       // Check if the frame to scroll before checking the default action
       // because if the scroll target is a plugin, the default action should be
       // chosen by the plugin rather than by our prefs.
       nsIFrame* frameToScroll =
         ComputeScrollTarget(mCurrentTarget, wheelEvent,
                             COMPUTE_DEFAULT_ACTION_TARGET);
       nsPluginFrame* pluginFrame = do_QueryFrame(frameToScroll);
       if (pluginFrame) {
         MOZ_ASSERT(pluginFrame->WantsToHandleWheelEventAsDefaultAction());
         // Plugins should receive original values instead of adjusted values.
-        adjuster.CancelAdjustment();
+        horizontalizer.CancelHorizontalization();
         action = WheelPrefs::ACTION_SEND_TO_PLUGIN;
       }
 
       switch (action) {
         case WheelPrefs::ACTION_SCROLL:
-        case WheelPrefs::ACTION_HORIZONTAL_SCROLL: {
+        case WheelPrefs::ACTION_HORIZONTALIZED_SCROLL: {
           // For scrolling of default action, we should honor the mouse wheel
           // transaction.
 
           ScrollbarsForWheel::PrepareToScrollText(this, mCurrentTarget, wheelEvent);
 
           if (aEvent->mMessage != eWheel ||
               (!wheelEvent->mDeltaX && !wheelEvent->mDeltaY)) {
             break;
@@ -5926,45 +5933,45 @@ EventStateManager::WheelPrefs::Init(Even
     NS_WARNING("Unsupported action pref value, replaced with 'Scroll'.");
     action = ACTION_SCROLL;
   }
   mActions[aIndex] = static_cast<Action>(action);
 
   // Compute action values overridden by .override_x pref.
   // At present, override is possible only for the x-direction
   // because this pref is introduced mainly for tilt wheels.
-  // Note that ACTION_HORIZONTAL_SCROLL isn't a valid value for this pref
+  // Note that ACTION_HORIZONTALIZED_SCROLL isn't a valid value for this pref
   // because it affects only to deltaY.
   prefNameAction.AppendLiteral(".override_x");
   int32_t actionOverrideX = Preferences::GetInt(prefNameAction.get(), -1);
   if (actionOverrideX < -1 || actionOverrideX > int32_t(ACTION_LAST) ||
-      actionOverrideX == ACTION_HORIZONTAL_SCROLL) {
+      actionOverrideX == ACTION_HORIZONTALIZED_SCROLL) {
     NS_WARNING("Unsupported action override pref value, didn't override.");
     actionOverrideX = -1;
   }
   mOverriddenActionsX[aIndex] = (actionOverrideX == -1)
                               ? static_cast<Action>(action)
                               : static_cast<Action>(actionOverrideX);
 }
 
 void
 EventStateManager::WheelPrefs::GetMultiplierForDeltaXAndY(
                                  const WidgetWheelEvent* aEvent,
                                  Index aIndex,
                                  double* aMultiplierForDeltaX,
                                  double* aMultiplierForDeltaY)
 {
-  // If the event should be treated as horizontal wheel operation, deltaY
-  // should be multiplied by mMultiplierY, however, it might be moved to
-  // deltaX for handling default action.  In such case, we need to treat
-  // mMultiplierX and mMultiplierY as swapped.
   *aMultiplierForDeltaX = mMultiplierX[aIndex];
   *aMultiplierForDeltaY = mMultiplierY[aIndex];
-  if (aEvent->mDeltaValuesAdjustedForDefaultHandler &&
-      ComputeActionFor(aEvent) == ACTION_HORIZONTAL_SCROLL) {
+  // If the event has been horizontalized(I.e. treated as a horizontal wheel
+  // scroll for a vertical wheel scroll), then we should swap mMultiplierX and
+  // mMultiplierY. By doing this, multipliers will still apply to the delta
+  // values they origianlly corresponded to.
+  if (aEvent->mDeltaValuesHorizontalizedForDefaultHandler &&
+      ComputeActionFor(aEvent) == ACTION_HORIZONTALIZED_SCROLL) {
     std::swap(*aMultiplierForDeltaX, *aMultiplierForDeltaY);
   }
 }
 
 void
 EventStateManager::WheelPrefs::ApplyUserPrefsToDelta(WidgetWheelEvent* aEvent)
 {
   if (aEvent->mCustomizedByUserPrefs) {
@@ -6028,26 +6035,26 @@ EventStateManager::WheelPrefs::ComputeAc
   Init(index);
 
   bool deltaXPreferred =
     (Abs(aEvent->mDeltaX) > Abs(aEvent->mDeltaY) &&
      Abs(aEvent->mDeltaX) > Abs(aEvent->mDeltaZ));
   Action* actions = deltaXPreferred ? mOverriddenActionsX : mActions;
   if (actions[index] == ACTION_NONE ||
       actions[index] == ACTION_SCROLL ||
-      actions[index] == ACTION_HORIZONTAL_SCROLL) {
+      actions[index] == ACTION_HORIZONTALIZED_SCROLL) {
     return actions[index];
   }
 
   // Momentum events shouldn't run special actions.
   if (aEvent->mIsMomentum) {
     // Use the default action.  Note that user might kill the wheel scrolling.
     Init(INDEX_DEFAULT);
     if (actions[INDEX_DEFAULT] == ACTION_SCROLL ||
-        actions[INDEX_DEFAULT] == ACTION_HORIZONTAL_SCROLL) {
+        actions[INDEX_DEFAULT] == ACTION_HORIZONTALIZED_SCROLL) {
       return actions[INDEX_DEFAULT];
     }
     return ACTION_NONE;
   }
 
   return actions[index];
 }
 
@@ -6093,30 +6100,36 @@ bool
 EventStateManager::WheelEventIsScrollAction(const WidgetWheelEvent* aEvent)
 {
   if (aEvent->mMessage != eWheel) {
     return false;
   }
   WheelPrefs::Action action =
     WheelPrefs::GetInstance()->ComputeActionFor(aEvent);
   return action == WheelPrefs::ACTION_SCROLL ||
-         action == WheelPrefs::ACTION_HORIZONTAL_SCROLL;
+         action == WheelPrefs::ACTION_HORIZONTALIZED_SCROLL;
 }
 
 // static
-bool
-EventStateManager::WheelEventIsHorizontalScrollAction(
-                     const WidgetWheelEvent* aEvent)
+WheelDeltaAdjustmentStrategy
+EventStateManager::GetWheelDeltaAdjustmentStrategy(
+                     const WidgetWheelEvent& aEvent)
 {
-  if (aEvent->mMessage != eWheel) {
-    return false;
-  }
-  WheelPrefs::Action action =
-    WheelPrefs::GetInstance()->ComputeActionFor(aEvent);
-  return action == WheelPrefs::ACTION_HORIZONTAL_SCROLL;
+  if (aEvent.mMessage != eWheel) {
+    return WheelDeltaAdjustmentStrategy::eNone;
+  }
+  switch (WheelPrefs::GetInstance()->ComputeActionFor(&aEvent)) {
+    case WheelPrefs::ACTION_HORIZONTALIZED_SCROLL:
+      return WheelDeltaAdjustmentStrategy::eHorizontalize;
+    // TODO Auto-dir scrolling is going to be handled here while implementing it
+    default:
+      // Prevent compilation errors generated by -Werror=switch
+      break;
+  }
+  return WheelDeltaAdjustmentStrategy::eNone;
 }
 
 void
 EventStateManager::GetUserPrefsForWheelEvent(const WidgetWheelEvent* aEvent,
                                              double* aOutMultiplierX,
                                              double* aOutMultiplierY)
 {
   WheelPrefs::GetInstance()->GetUserPrefsForEvent(
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -12,16 +12,17 @@
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/TimeStamp.h"
 #include "nsIFrame.h"
 #include "Units.h"
+#include "WheelHandlingHelper.h"          // for WheelDeltaAdjustmentStrategy
 
 #define NS_USER_INTERACTION_INTERVAL 5000 // ms
 
 class nsFrameLoader;
 class nsIContent;
 class nsIDocument;
 class nsIDocShell;
 class nsIDocShellTreeItem;
@@ -303,19 +304,29 @@ 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(const WidgetWheelEvent* aEvent);
 
-  // Returns true if the given WidgetWheelEvent will resolve to a horizontal
-  // scroll action but it's a vertical wheel operation.
-  static bool WheelEventIsHorizontalScrollAction(const WidgetWheelEvent* aEvet);
+  // For some kinds of scrollings, the delta values of WidgetWheelEvent are
+  // possbile to be adjusted. This function is used to detect such scrollings
+  // and returns a wheel delta adjustment strategy to use, which is corresponded
+  // to the kind of the scrolling.
+  // It returns WheelDeltaAdjustmentStrategy::eHorizontalize if the current
+  // default action is horizontalized scrolling.
+  // TODO Insert new comment words about the returned value for auto-dir
+  // scrolling while implementing it.
+  // It returns WheelDeltaAdjustmentStrategy::eNone to mean no delta adjustment
+  // strategy should be used if the scrolling is just a tranditional scrolling
+  // whose delta values are never possible to be adjusted.
+  static WheelDeltaAdjustmentStrategy
+  GetWheelDeltaAdjustmentStrategy(const WidgetWheelEvent& aEvent);
 
   // Returns user-set multipliers for a wheel event.
   static void GetUserPrefsForWheelEvent(const WidgetWheelEvent* aEvent,
                                         double* aOutMultiplierX,
                                         double* aOutMultiplierY);
 
   // 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
@@ -558,18 +569,24 @@ protected:
      * Computes the default action for the aEvent with the prefs.
      */
     enum Action : uint8_t
     {
       ACTION_NONE = 0,
       ACTION_SCROLL,
       ACTION_HISTORY,
       ACTION_ZOOM,
-      ACTION_HORIZONTAL_SCROLL,
-      ACTION_LAST = ACTION_HORIZONTAL_SCROLL,
+      // Horizontalized scrolling means treating vertical wheel scrolling as
+      // horizontal scrolling during the process of its default action and
+      // plugins handling scrolling. Note that delta values as the event object
+      // in a DOM event listener won't be affected, and will be still the
+      // original values. For more details, refer to
+      // mozilla::WheelDeltaAdjustmentStrategy::eHorizontalize
+      ACTION_HORIZONTALIZED_SCROLL,
+      ACTION_LAST = ACTION_HORIZONTALIZED_SCROLL,
       // Following actions are used only by internal processing.  So, cannot
       // specified by prefs.
       ACTION_SEND_TO_PLUGIN,
     };
     Action ComputeActionFor(const WidgetWheelEvent* aEvent);
 
     /**
      * NeedToComputeLineOrPageDelta() returns if the aEvent needs to be
@@ -628,19 +645,22 @@ protected:
     void GetBasePrefName(Index aIndex, nsACString& aBasePrefName);
 
     void Init(Index aIndex);
 
     void Reset();
 
     /**
      * Retrieve multiplier for aEvent->mDeltaX and aEvent->mDeltaY.
-     * If the default action is ACTION_HORIZONTAL_SCROLL and the delta values
-     * are adjusted by AutoWheelDeltaAdjuster(), this treats mMultiplierX as
-     * multiplier for deltaY and mMultiplierY as multiplier for deltaY.
+     *
+     * Note that if the default action is ACTION_HORIZONTALIZED_SCROLL and the
+     * delta values have been adjusted by WheelDeltaHorizontalizer() before this
+     * function is called, this function will swap the X and Y multipliers. By
+     * doing this, multipliers will still apply to the delta values they
+     * originally corresponded to.
      *
      * @param aEvent    The event which is being handled.
      * @param aIndex    The index of mMultiplierX and mMultiplierY.
      *                  Should be result of GetIndexFor(aEvent).
      * @param aMultiplierForDeltaX      Will be set to multiplier for
      *                                  aEvent->mDeltaX.
      * @param aMultiplierForDeltaY      Will be set to multiplier for
      *                                  aEvent->mDeltaY.
--- a/dom/events/WheelHandlingHelper.cpp
+++ b/dom/events/WheelHandlingHelper.cpp
@@ -579,57 +579,62 @@ WheelTransaction::Prefs::InitializeStati
     Preferences::AddUintVarCache(&sMouseWheelTransactionIgnoreMoveDelay,
                                  "mousewheel.transaction.ignoremovedelay", 100);
     Preferences::AddBoolVarCache(&sTestMouseScroll, "test.mousescroll", false);
     sIsInitialized = true;
   }
 }
 
 /******************************************************************/
-/* mozilla::AutoWheelDeltaAdjuster                                */
+/* mozilla::WheelDeltaHorizontalizer                              */
 /******************************************************************/
 
-AutoWheelDeltaAdjuster::AutoWheelDeltaAdjuster(WidgetWheelEvent& aWheelEvent)
-  : mWheelEvent(aWheelEvent)
-  , mOldDeltaX(aWheelEvent.mDeltaX)
-  , mOldDeltaZ(aWheelEvent.mDeltaZ)
-  , mOldOverflowDeltaX(aWheelEvent.mOverflowDeltaX)
-  , mOldLineOrPageDeltaX(aWheelEvent.mLineOrPageDeltaX)
-  , mTreatedVerticalWheelAsHorizontalScroll(false)
+void
+WheelDeltaHorizontalizer::Horizontalize()
 {
-  MOZ_ASSERT(!aWheelEvent.mDeltaValuesAdjustedForDefaultHandler);
+  MOZ_ASSERT(!mWheelEvent.mDeltaValuesHorizontalizedForDefaultHandler,
+             "Wheel delta values in one wheel scroll event are being adjusted "
+             "a second time");
+
+  // Log the old values.
+  mOldDeltaX = mWheelEvent.mDeltaX;
+  mOldDeltaZ = mWheelEvent.mDeltaZ;
+  mOldOverflowDeltaX = mWheelEvent.mOverflowDeltaX;
+  mOldLineOrPageDeltaX = mWheelEvent.mLineOrPageDeltaX;
 
-  if (EventStateManager::WheelEventIsHorizontalScrollAction(&aWheelEvent)) {
-    // Move deltaY values to deltaX and set both deltaY and deltaZ to 0.
-    mWheelEvent.mDeltaX = mWheelEvent.mDeltaY;
-    mWheelEvent.mDeltaY = 0.0;
-    mWheelEvent.mDeltaZ = 0.0;
-    mWheelEvent.mOverflowDeltaX = mWheelEvent.mOverflowDeltaY;
-    mWheelEvent.mOverflowDeltaY = 0.0;
-    mWheelEvent.mLineOrPageDeltaX = mWheelEvent.mLineOrPageDeltaY;
-    mWheelEvent.mLineOrPageDeltaY = 0;
-    mWheelEvent.mDeltaValuesAdjustedForDefaultHandler = true;
-    mTreatedVerticalWheelAsHorizontalScroll = true;
-  }
+  // Move deltaY values to deltaX and set both deltaY and deltaZ to 0.
+  mWheelEvent.mDeltaX = mWheelEvent.mDeltaY;
+  mWheelEvent.mDeltaY = 0.0;
+  mWheelEvent.mDeltaZ = 0.0;
+  mWheelEvent.mOverflowDeltaX = mWheelEvent.mOverflowDeltaY;
+  mWheelEvent.mOverflowDeltaY = 0.0;
+  mWheelEvent.mLineOrPageDeltaX = mWheelEvent.mLineOrPageDeltaY;
+  mWheelEvent.mLineOrPageDeltaY = 0;
+
+  // Mark it horizontalized in order to restore the delta values when this
+  // instance is being destroyed.
+  mWheelEvent.mDeltaValuesHorizontalizedForDefaultHandler = true;
+  mHorizontalized = true;
 }
 
-void AutoWheelDeltaAdjuster::CancelAdjustment()
+void WheelDeltaHorizontalizer::CancelHorizontalization()
 {
-  if (mTreatedVerticalWheelAsHorizontalScroll &&
-      mWheelEvent.mDeltaValuesAdjustedForDefaultHandler) {
+  // Restore the horizontalized delta.
+  if (mHorizontalized &&
+      mWheelEvent.mDeltaValuesHorizontalizedForDefaultHandler) {
     mWheelEvent.mDeltaY = mWheelEvent.mDeltaX;
     mWheelEvent.mDeltaX = mOldDeltaX;
     mWheelEvent.mDeltaZ = mOldDeltaZ;
     mWheelEvent.mOverflowDeltaY = mWheelEvent.mOverflowDeltaX;
     mWheelEvent.mOverflowDeltaX = mOldOverflowDeltaX;
     mWheelEvent.mLineOrPageDeltaY = mWheelEvent.mLineOrPageDeltaX;
     mWheelEvent.mLineOrPageDeltaX = mOldLineOrPageDeltaX;
-    mWheelEvent.mDeltaValuesAdjustedForDefaultHandler = false;
-    mTreatedVerticalWheelAsHorizontalScroll = false;
+    mWheelEvent.mDeltaValuesHorizontalizedForDefaultHandler = false;
+    mHorizontalized = false;
   }
 }
 
-AutoWheelDeltaAdjuster::~AutoWheelDeltaAdjuster()
+WheelDeltaHorizontalizer::~WheelDeltaHorizontalizer()
 {
-  CancelAdjustment();
+  CancelHorizontalization();
 }
 
 } // namespace mozilla
--- a/dom/events/WheelHandlingHelper.h
+++ b/dom/events/WheelHandlingHelper.h
@@ -205,41 +205,73 @@ protected:
     static int32_t sMouseWheelAccelerationStart;
     static int32_t sMouseWheelAccelerationFactor;
     static uint32_t sMouseWheelTransactionTimeout;
     static uint32_t sMouseWheelTransactionIgnoreMoveDelay;
     static bool sTestMouseScroll;
   };
 };
 
+// For some kinds of scrollings, the delta values of WidgetWheelEvent are
+// possbile to be adjusted. For example, the user has configured the pref to let
+// [vertical wheel + Shift key] to perform horizontal scrolling instead of
+// vertical scrolling.
+// The values in this enumeration list all kinds of scrollings whose delta
+// values are possible to be adjusted.
+enum class WheelDeltaAdjustmentStrategy : uint8_t
+{
+  // There is no strategy, don't adjust delta values in any cases.
+  eNone,
+  // This strategy means we're receiving a horizontalized scroll, so we should
+  // apply horizontalization strategy for its delta values.
+  // Horizontalized scrolling means treating vertical wheel scrolling as
+  // horizontal scrolling by adjusting delta values.
+  // It's important to keep in mind with the percise concept of horizontalized
+  // scrolling: Delta values are *ONLY* going to be adjusted during the process
+  // of its default action handling; in views of any programmes other than the
+  // default action handler, such as a DOM event listener or a plugin, delta
+  // values are never going to be adjusted, they will still retrive original
+  // delta values when horizontalization occured for default actions.
+  eHorizontalize,
+  // TODO A new value for auto-dir scrolling is going to be added while
+  // implementing such scrolling.
+};
+
 /**
- * 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.
+ * When a *pure* vertical wheel event should be treated as if it was a
+ * horizontal scroll because the user wants to horizontalize the wheel scroll,
+ * an instance of this class will adjust the delta values upon calling
+ * Horizontalize(). And the horizontalized delta values will be restored
+ * automatically when the instance of this class is being destructed. Or you can
+ * restore them in advance by calling CancelHorizontalization().
  */
-class MOZ_STACK_CLASS AutoWheelDeltaAdjuster final
+class MOZ_STACK_CLASS WheelDeltaHorizontalizer 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.
+   * @param aWheelEvent        A wheel event whose delta values will be adjusted
+   *                           upon calling Horizontalize().
    */
-  explicit AutoWheelDeltaAdjuster(WidgetWheelEvent& aWheelEvent);
-  ~AutoWheelDeltaAdjuster();
-  void CancelAdjustment();
+  explicit WheelDeltaHorizontalizer(WidgetWheelEvent& aWheelEvent)
+    : mWheelEvent(aWheelEvent)
+    , mHorizontalized(false)
+  {
+  }
+  /**
+   * Converts vertical scrolling into horizontal scrolling by adjusting the
+   * its delta values.
+   */
+  void Horizontalize();
+  ~WheelDeltaHorizontalizer();
+  void CancelHorizontalization();
 
 private:
   WidgetWheelEvent& mWheelEvent;
   double mOldDeltaX;
   double mOldDeltaZ;
   double mOldOverflowDeltaX;
   int32_t mOldLineOrPageDeltaX;
-  bool mTreatedVerticalWheelAsHorizontalScroll;
+  bool mHorizontalized;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_WheelHandlingHelper_h_
--- a/dom/events/test/window_wheel_default_action.html
+++ b/dom/events/test/window_wheel_default_action.html
@@ -73,21 +73,21 @@ SimpleTest.requestFlakyTimeout("untriage
 var winUtils = SpecialPowers.getDOMWindowUtils(window);
 // grab refresh driver
 winUtils.advanceTimeAndRefresh(100);
 
 var gScrollableElement = document.getElementById("scrollable");
 var gScrolledElement = document.getElementById("scrolled");
 var gSpacerForBodyElement = document.getElementById("spacerForBody");
 
-const kDefaultActionNone             = 0;
-const kDefaultActionScroll           = 1;
-const kDefaultActionHistory          = 2;
-const kDefaultActionZoom             = 3;
-const kDefaultActionHorizontalScroll = 4;
+const kDefaultActionNone                 = 0;
+const kDefaultActionScroll               = 1;
+const kDefaultActionHistory              = 2;
+const kDefaultActionZoom                 = 3;
+const kDefaultActionHorizontalizedScroll = 4;
 
 const kDefaultActionOverrideXNoOverride = -1;
 const kDefaultActionOverrideXNone       = kDefaultActionNone;
 const kDefaultActionOverrideXScroll     = kDefaultActionScroll;
 const kDefaultActionOverrideXHistory    = kDefaultActionHistory;
 const kDefaultActionOverrideXZoom       = kDefaultActionZoom;
 
 function is()
@@ -953,17 +953,17 @@ function doTestScroll(aSettings, aCallba
         winUtils.advanceTimeAndRefresh(100);
         doNextTest();
       }
     });
   }
   doNextTest();
 }
 
-function doTestHorizontalScroll(aSettings, aCallback)
+function doTestHorizontalizedScroll(aSettings, aCallback)
 {
   const kNoScroll    = 0x00;
   const kScrollLeft  = 0x01;
   const kScrollRight = 0x02;
 
   const kTests = [
     { description: "Scroll to right by pixel scroll even if lineOrPageDelta is 0",
       event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
@@ -1255,17 +1255,17 @@ function doTestHorizontalScroll(aSetting
       SimpleTest.executeSoon(aCallback);
       return;
     }
 
     gScrollableElement.scrollTop = 1000;
     gScrollableElement.scrollLeft = 1000;
 
     var currentTest = kTests[currentTestIndex];
-    description = "doTestHorizontalScroll(aSettings=" + aSettings.description + "), " + currentTest.description + ": ";
+    description = "doTestHorizontalizedScroll(aSettings=" + aSettings.description + "), " + currentTest.description + ": ";
     if (currentTest.prepare) {
       currentTest.prepare(doTestCurrentScroll);
     } else {
       doTestCurrentScroll();
     }
   }
 
   function doTestCurrentScroll() {
@@ -2173,17 +2173,17 @@ function doTestActionOverride(aCallback)
 
 function runTests()
 {
   SpecialPowers.pushPrefEnv({"set": [
     ["test.events.async.enabled", true],
     ["general.smoothScroll", false],
     ["mousewheel.default.action", kDefaultActionScroll],
     ["mousewheel.default.action.override_x", kDefaultActionOverrideXNoOverride],
-    ["mousewheel.with_shift.action", kDefaultActionHorizontalScroll],
+    ["mousewheel.with_shift.action", kDefaultActionHorizontalizedScroll],
     ["mousewheel.with_shift.action.override_x", kDefaultActionOverrideXNoOverride],
     ["mousewheel.with_control.action", kDefaultActionZoom],
     ["mousewheel.with_control.action.override_x", kDefaultActionOverrideXNoOverride],
     ["mousewheel.with_alt.action", kDefaultActionHistory],
     ["mousewheel.with_alt.action.override_x", kDefaultActionOverrideXNoOverride]]},
     runTests2);
 }
 
@@ -2212,17 +2212,17 @@ function runTests2()
       deltaMultiplierX:  1.0, deltaMultiplierY:  1.0, deltaMultiplierZ: -2.0 },
   ];
 
   var index = 0;
 
   function doTest() {
     setDeltaMultiplierSettings(kSettings[index], function () {
       doTestScroll(kSettings[index], function () {
-        doTestHorizontalScroll(kSettings[index], function() {
+        doTestHorizontalizedScroll(kSettings[index], function() {
           doTestZoom(kSettings[index], function() {
             if (++index == kSettings.length) {
               setDeltaMultiplierSettings(kSettings[0], function() {
                 doTestZoomedScroll(function() {
                   doTestWholeScroll(function() {
                     doTestActionOverride(function() {
                       finishTests();
                     });
--- a/gfx/layers/apz/src/APZInputBridge.cpp
+++ b/gfx/layers/apz/src/APZInputBridge.cpp
@@ -3,23 +3,24 @@
 /* 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/. */
 
 #include "mozilla/layers/APZInputBridge.h"
 
 #include "gfxPrefs.h"                       // for gfxPrefs
 #include "InputData.h"                      // for MouseInput, etc
+#include "mozilla/dom/WheelEventBinding.h"  // for WheelEvent constants
 #include "mozilla/EventStateManager.h"      // for EventStateManager
 #include "mozilla/layers/APZThreadUtils.h"  // for AssertOnControllerThread, etc
 #include "mozilla/MouseEvents.h"            // for WidgetMouseEvent
 #include "mozilla/TextEvents.h"             // for WidgetKeyboardEvent
 #include "mozilla/TouchEvents.h"            // for WidgetTouchEvent
-#include "mozilla/WheelHandlingHelper.h"    // for AutoWheelDeltaAdjuster
-#include "mozilla/dom/WheelEventBinding.h"  // for WheelEvent constants
+#include "mozilla/WheelHandlingHelper.h"    // for WheelDeltaHorizontalizer,
+                                            //     WheelDeltaAdjustmentStrategy
 
 namespace mozilla {
 namespace layers {
 
 static bool
 WillHandleMouseEvent(const WidgetMouseEventBase& aEvent)
 {
   return aEvent.mMessage == eMouseMove ||
@@ -111,20 +112,28 @@ APZInputBridge::ReceiveInputEvent(
             ((wheelEvent.mDeltaMode == dom::WheelEventBinding::DOM_DELTA_LINE &&
               gfxPrefs::WheelSmoothScrollEnabled()) ||
              (wheelEvent.mDeltaMode == dom::WheelEventBinding::DOM_DELTA_PAGE &&
               gfxPrefs::PageSmoothScrollEnabled())))
         {
           scrollMode = ScrollWheelInput::SCROLLMODE_SMOOTH;
         }
 
-        // AutoWheelDeltaAdjuster may adjust the delta values for default
-        // action hander.  The delta values will be restored automatically
-        // when its instance is destroyed.
-        AutoWheelDeltaAdjuster adjuster(wheelEvent);
+        WheelDeltaAdjustmentStrategy strategy =
+          EventStateManager::GetWheelDeltaAdjustmentStrategy(wheelEvent);
+        // Adjust the delta values of the wheel event if the current default
+        // action is to horizontalize scrolling. I.e., deltaY values are set to
+        // deltaX and deltaY and deltaZ values are set to 0.
+        // If horizontalized, the delta values will be restored and its overflow
+        // deltaX will become 0 when the WheelDeltaHorizontalizer instance is
+        // being destroyed.
+        WheelDeltaHorizontalizer horizontalizer(wheelEvent);
+        if (WheelDeltaAdjustmentStrategy::eHorizontalize == strategy) {
+          horizontalizer.Horizontalize();
+        }
 
         // If the wheel event becomes no-op event, don't handle it as scroll.
         if (wheelEvent.mDeltaX || wheelEvent.mDeltaY) {
           ScreenPoint origin(wheelEvent.mRefPoint.x, wheelEvent.mRefPoint.y);
           ScrollWheelInput input(wheelEvent.mTime, wheelEvent.mTimeStamp, 0,
                                  scrollMode,
                                  ScrollWheelInput::DeltaTypeForDeltaMode(
                                                      wheelEvent.mDeltaMode),
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -825,16 +825,29 @@ protected:
 
   // Protects |mFrameMetrics|, |mLastContentPaintMetrics|, and |mState|.
   // Before manipulating |mFrameMetrics| or |mLastContentPaintMetrics|, the
   // monitor should be held. When setting |mState|, either the SetState()
   // function can be used, or the monitor can be held and then |mState| updated.
   // IMPORTANT: See the note about lock ordering at the top of APZCTreeManager.h.
   // This is mutable to allow entering it from 'const' methods; doing otherwise
   // would significantly limit what methods could be 'const'.
+  // FIXME: Please keep in mind that due to some existing coupled relationships
+  // among the class members, we should be aware of indirect usage of the
+  // monitor-protected members. That is, although this monitor isn't required to
+  // be held before manipulating non-protected class members, some functions on
+  // those members might indirectly manipulate the protected members; in such
+  // cases, the monitor should still be held. Let's take mX.CanScroll for
+  // example:
+  // Axis::CanScroll(ParentLayerCoord) calls Axis::CanScroll() which calls
+  // Axis::GetPageLength() which calls Axis::GetFrameMetrics() which calls
+  // AsyncPanZoomController::GetFrameMetrics(), therefore, this monitor should
+  // be held before calling the CanScroll function of |mX| and |mY|. These
+  // coupled relationships bring us the burden of taking care of when the
+  // monitor should be held, so they should be decoupled in the future.
   mutable RecursiveMutex mRecursiveMutex;
 
 private:
   // Metadata of the container layer corresponding to this APZC. This is
   // stored here so that it is accessible from the UI/controller thread.
   // These are the metrics at last content paint, the most recent
   // values we were notified of in NotifyLayersUpdate(). Since it represents
   // the Gecko state, it should be used as a basis for untransformation when
--- a/widget/InputData.h
+++ b/widget/InputData.h
@@ -584,16 +584,20 @@ public:
   bool mAllowToOverrideSystemScrollSpeed;
 };
 
 class KeyboardInput : public InputData
 {
 public:
   typedef mozilla::layers::KeyboardScrollAction KeyboardScrollAction;
 
+  // Note that if you change the first member in this enum(I.e. KEY_DOWN) to one
+  // other member, don't forget to update the minimum value in
+  // ContiguousEnumSerializer for KeyboardEventType in widget/nsGUIEventIPC
+  // accordingly.
   enum KeyboardEventType
   {
     KEY_DOWN,
     KEY_PRESS,
     KEY_UP,
     // Any other key event such as eKeyDownOnPlugin
     KEY_OTHER,
 
--- a/widget/MouseEvents.h
+++ b/widget/MouseEvents.h
@@ -513,17 +513,17 @@ private:
     , mScrollType(SCROLL_DEFAULT)
     , mCustomizedByUserPrefs(false)
     , mMayHaveMomentum{ false }
     , mIsMomentum(false)
     , mIsNoLineOrPageDelta(false)
     , mViewPortIsOverscrolled(false)
     , mCanTriggerSwipe(false)
     , mAllowToOverrideSystemScrollSpeed(false)
-    , mDeltaValuesAdjustedForDefaultHandler(false)
+    , mDeltaValuesHorizontalizedForDefaultHandler(false)
   {
   }
 
 public:
   virtual WidgetWheelEvent* AsWheelEvent() override { return this; }
 
   WidgetWheelEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget)
     : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget, eWheelEventClass)
@@ -540,17 +540,17 @@ public:
     , mScrollType(SCROLL_DEFAULT)
     , mCustomizedByUserPrefs(false)
     , mMayHaveMomentum(false)
     , mIsMomentum(false)
     , mIsNoLineOrPageDelta(false)
     , mViewPortIsOverscrolled(false)
     , mCanTriggerSwipe(false)
     , mAllowToOverrideSystemScrollSpeed(true)
-    , mDeltaValuesAdjustedForDefaultHandler(false)
+    , mDeltaValuesHorizontalizedForDefaultHandler(false)
   {
   }
 
   virtual WidgetEvent* Duplicate() const override
   {
     MOZ_ASSERT(mClass == eWheelEventClass,
                "Duplicate() must be overridden by sub class");
     // Not copying widget, it is a weak reference.
@@ -574,18 +574,18 @@ public:
   //       mousewheel.*.delta_multiplier_* prefs which are applied by
   //       EventStateManager.  So, after widget dispatches this event,
   //       these delta values may have different values than before.
   double mDeltaX;
   double mDeltaY;
   double mDeltaZ;
 
   // overflowed delta values for scroll, these values are set by
-  // nsEventStateManger.  If the default action of the wheel event isn't scroll,
-  // these values always zero.  Otherwise, remaning delta values which are
+  // EventStateManger.  If the default action of the wheel event isn't scroll,
+  // these values are always zero.  Otherwise, remaining delta values which are
   // not used by scroll are set.
   // NOTE: mDeltaX, mDeltaY and mDeltaZ may be modified by EventStateManager.
   //       However, mOverflowDeltaX and mOverflowDeltaY indicate unused original
   //       delta values which are not applied the delta_multiplier prefs.
   //       So, if widget wanted to know the actual direction to be scrolled,
   //       it would need to check the mDeltaX and mDeltaY.
   double mOverflowDeltaX;
   double mOverflowDeltaY;
@@ -658,19 +658,20 @@ public:
   // viewport.
   bool mCanTriggerSwipe;
 
   // If mAllowToOverrideSystemScrollSpeed is true, the scroll speed may be
   // overridden.  Otherwise, the scroll speed won't be overridden even if
   // it's enabled by the pref.
   bool mAllowToOverrideSystemScrollSpeed;
 
-  // While default handler handles a wheel event specially (e.g., treating
-  // mDeltaY as horizontal scroll), this is set to true.
-  bool mDeltaValuesAdjustedForDefaultHandler;
+  // After the event's default action handler has adjusted its delta's values
+  // for horizontalizing a vertical wheel scroll, this variable will be set to
+  // true.
+  bool mDeltaValuesHorizontalizedForDefaultHandler;
 
   void AssignWheelEventData(const WidgetWheelEvent& aEvent, bool aCopyTargets)
   {
     AssignMouseEventBaseData(aEvent, aCopyTargets);
 
     mDeltaX = aEvent.mDeltaX;
     mDeltaY = aEvent.mDeltaY;
     mDeltaZ = aEvent.mDeltaZ;
@@ -683,18 +684,18 @@ public:
     mLineOrPageDeltaY = aEvent.mLineOrPageDeltaY;
     mScrollType = aEvent.mScrollType;
     mOverflowDeltaX = aEvent.mOverflowDeltaX;
     mOverflowDeltaY = aEvent.mOverflowDeltaY;
     mViewPortIsOverscrolled = aEvent.mViewPortIsOverscrolled;
     mCanTriggerSwipe = aEvent.mCanTriggerSwipe;
     mAllowToOverrideSystemScrollSpeed =
       aEvent.mAllowToOverrideSystemScrollSpeed;
-    mDeltaValuesAdjustedForDefaultHandler =
-      aEvent.mDeltaValuesAdjustedForDefaultHandler;
+    mDeltaValuesHorizontalizedForDefaultHandler =
+      aEvent.mDeltaValuesHorizontalizedForDefaultHandler;
   }
 
   // System scroll speed settings may be too slow at using Gecko.  In such
   // case, we should override the scroll speed computed with system settings.
   // Following methods return preferred delta values which are multiplied by
   // factors specified by prefs.  If system scroll speed shouldn't be
   // overridden (e.g., this feature is disabled by pref), they return raw
   // delta values.
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -182,17 +182,17 @@ struct ParamTraits<mozilla::WidgetWheelE
     WriteParam(aMsg, aParam.mLineOrPageDeltaX);
     WriteParam(aMsg, aParam.mLineOrPageDeltaY);
     WriteParam(aMsg, static_cast<uint8_t>(aParam.mScrollType));
     WriteParam(aMsg, aParam.mOverflowDeltaX);
     WriteParam(aMsg, aParam.mOverflowDeltaY);
     WriteParam(aMsg, aParam.mViewPortIsOverscrolled);
     WriteParam(aMsg, aParam.mCanTriggerSwipe);
     WriteParam(aMsg, aParam.mAllowToOverrideSystemScrollSpeed);
-    WriteParam(aMsg, aParam.mDeltaValuesAdjustedForDefaultHandler);
+    WriteParam(aMsg, aParam.mDeltaValuesHorizontalizedForDefaultHandler);
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     uint8_t scrollType = 0;
     bool rv =
       ReadParam(aMsg, aIter,
                 static_cast<mozilla::WidgetMouseEventBase*>(aResult)) &&
@@ -207,17 +207,18 @@ struct ParamTraits<mozilla::WidgetWheelE
       ReadParam(aMsg, aIter, &aResult->mLineOrPageDeltaX) &&
       ReadParam(aMsg, aIter, &aResult->mLineOrPageDeltaY) &&
       ReadParam(aMsg, aIter, &scrollType) &&
       ReadParam(aMsg, aIter, &aResult->mOverflowDeltaX) &&
       ReadParam(aMsg, aIter, &aResult->mOverflowDeltaY) &&
       ReadParam(aMsg, aIter, &aResult->mViewPortIsOverscrolled) &&
       ReadParam(aMsg, aIter, &aResult->mCanTriggerSwipe) &&
       ReadParam(aMsg, aIter, &aResult->mAllowToOverrideSystemScrollSpeed) &&
-      ReadParam(aMsg, aIter, &aResult->mDeltaValuesAdjustedForDefaultHandler);
+      ReadParam(aMsg, aIter,
+                &aResult->mDeltaValuesHorizontalizedForDefaultHandler);
     aResult->mScrollType =
       static_cast<mozilla::WidgetWheelEvent::ScrollType>(scrollType);
     return rv;
   }
 };
 
 template<>
 struct ParamTraits<mozilla::WidgetPointerHelper>