Bug 1153156 part.2 Make WidgetWheelEvent store if overriding system scroll speed is allowed and it shouldn't be allowed if scroll speed isn't system default settings on Windows r=smaug+jimm
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 27 Jan 2016 15:09:13 +0900
changeset 281878 0e3407fff0c1d255b216f3fe6dea5957c3c975a4
parent 281877 5c4d4ee8924ba418a132f87bebd3ea6932900730
child 281879 d3f1f3501ce23f10b472720b88d77e77128bd234
push id17275
push usercbook@mozilla.com
push dateThu, 28 Jan 2016 11:37:27 +0000
treeherderfx-team@e2d11e2d506c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1153156
milestone47.0a1
Bug 1153156 part.2 Make WidgetWheelEvent store if overriding system scroll speed is allowed and it shouldn't be allowed if scroll speed isn't system default settings on Windows r=smaug+jimm
widget/MouseEvents.h
widget/WidgetEventImpl.cpp
widget/nsGUIEventIPC.h
widget/windows/WinMouseScrollHandler.cpp
widget/windows/WinMouseScrollHandler.h
widget/windows/nsWindow.cpp
--- a/widget/MouseEvents.h
+++ b/widget/MouseEvents.h
@@ -457,16 +457,17 @@ private:
     , mIsNoLineOrPageDelta(false)
     , lineOrPageDeltaX(0)
     , lineOrPageDeltaY(0)
     , scrollType(SCROLL_DEFAULT)
     , overflowDeltaX(0.0)
     , overflowDeltaY(0.0)
     , mViewPortIsOverscrolled(false)
     , mCanTriggerSwipe(false)
+    , mAllowToOverrideSystemScrollSpeed(false)
   {
   }
 
 public:
   virtual WidgetWheelEvent* AsWheelEvent() override { return this; }
 
   WidgetWheelEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget)
     : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget, eWheelEventClass)
@@ -480,16 +481,17 @@ public:
     , mIsNoLineOrPageDelta(false)
     , lineOrPageDeltaX(0)
     , lineOrPageDeltaY(0)
     , scrollType(SCROLL_DEFAULT)
     , overflowDeltaX(0.0)
     , overflowDeltaY(0.0)
     , mViewPortIsOverscrolled(false)
     , mCanTriggerSwipe(false)
+    , mAllowToOverrideSystemScrollSpeed(true)
   {
   }
 
   virtual WidgetEvent* Duplicate() const override
   {
     MOZ_ASSERT(mClass == eWheelEventClass,
                "Duplicate() must be overridden by sub class");
     // Not copying widget, it is a weak reference.
@@ -594,16 +596,21 @@ public:
   // overscrolled (such as a text field), but true when the 'page' is being
   // overscrolled.
   bool mViewPortIsOverscrolled;
 
   // The wheel event can trigger a swipe to start if it's overscrolling the
   // 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;
+
   void AssignWheelEventData(const WidgetWheelEvent& aEvent, bool aCopyTargets)
   {
     AssignMouseEventBaseData(aEvent, aCopyTargets);
 
     deltaX = aEvent.deltaX;
     deltaY = aEvent.deltaY;
     deltaZ = aEvent.deltaZ;
     deltaMode = aEvent.deltaMode;
@@ -613,16 +620,18 @@ public:
     mIsNoLineOrPageDelta = aEvent.mIsNoLineOrPageDelta;
     lineOrPageDeltaX = aEvent.lineOrPageDeltaX;
     lineOrPageDeltaY = aEvent.lineOrPageDeltaY;
     scrollType = aEvent.scrollType;
     overflowDeltaX = aEvent.overflowDeltaX;
     overflowDeltaY = aEvent.overflowDeltaY;
     mViewPortIsOverscrolled = aEvent.mViewPortIsOverscrolled;
     mCanTriggerSwipe = aEvent.mCanTriggerSwipe;
+    mAllowToOverrideSystemScrollSpeed =
+      aEvent.mAllowToOverrideSystemScrollSpeed;
   }
 
   // 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/WidgetEventImpl.cpp
+++ b/widget/WidgetEventImpl.cpp
@@ -379,22 +379,28 @@ WidgetWheelEvent::ComputeOverriddenDelta
   }
   double factor = static_cast<double>(intFactor) / 100;
   return aDelta * factor;
 }
 
 double
 WidgetWheelEvent::OverriddenDeltaX() const
 {
+  if (!mAllowToOverrideSystemScrollSpeed) {
+    return deltaX;
+  }
   return ComputeOverriddenDelta(deltaX, false);
 }
 
 double
 WidgetWheelEvent::OverriddenDeltaY() const
 {
+  if (!mAllowToOverrideSystemScrollSpeed) {
+    return deltaY;
+  }
   return ComputeOverriddenDelta(deltaY, true);
 }
 
 /******************************************************************************
  * mozilla::WidgetKeyboardEvent (TextEvents.h)
  ******************************************************************************/
 
 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) MOZ_UTF16(aDOMKeyName),
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -170,16 +170,17 @@ struct ParamTraits<mozilla::WidgetWheelE
     WriteParam(aMsg, aParam.mIsNoLineOrPageDelta);
     WriteParam(aMsg, aParam.lineOrPageDeltaX);
     WriteParam(aMsg, aParam.lineOrPageDeltaY);
     WriteParam(aMsg, static_cast<int32_t>(aParam.scrollType));
     WriteParam(aMsg, aParam.overflowDeltaX);
     WriteParam(aMsg, aParam.overflowDeltaY);
     WriteParam(aMsg, aParam.mViewPortIsOverscrolled);
     WriteParam(aMsg, aParam.mCanTriggerSwipe);
+    WriteParam(aMsg, aParam.mAllowToOverrideSystemScrollSpeed);
   }
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
     int32_t scrollType = 0;
     bool rv =
       ReadParam(aMsg, aIter,
                 static_cast<mozilla::WidgetMouseEventBase*>(aResult)) &&
@@ -192,17 +193,18 @@ struct ParamTraits<mozilla::WidgetWheelE
       ReadParam(aMsg, aIter, &aResult->isMomentum) &&
       ReadParam(aMsg, aIter, &aResult->mIsNoLineOrPageDelta) &&
       ReadParam(aMsg, aIter, &aResult->lineOrPageDeltaX) &&
       ReadParam(aMsg, aIter, &aResult->lineOrPageDeltaY) &&
       ReadParam(aMsg, aIter, &scrollType) &&
       ReadParam(aMsg, aIter, &aResult->overflowDeltaX) &&
       ReadParam(aMsg, aIter, &aResult->overflowDeltaY) &&
       ReadParam(aMsg, aIter, &aResult->mViewPortIsOverscrolled) &&
-      ReadParam(aMsg, aIter, &aResult->mCanTriggerSwipe);
+      ReadParam(aMsg, aIter, &aResult->mCanTriggerSwipe) &&
+      ReadParam(aMsg, aIter, &aResult->mAllowToOverrideSystemScrollSpeed);
     aResult->scrollType =
       static_cast<mozilla::WidgetWheelEvent::ScrollType>(scrollType);
     return rv;
   }
 };
 
 template<>
 struct ParamTraits<mozilla::WidgetMouseEvent>
--- a/widget/windows/WinMouseScrollHandler.cpp
+++ b/widget/windows/WinMouseScrollHandler.cpp
@@ -608,17 +608,17 @@ MouseScrollHandler::HandleMouseWheelMess
      "aMessage=MOZ_WM_MOUSE%sWHEEL, aWParam=0x%08X, aLParam=0x%08X",
      aWidget, aMessage == MOZ_WM_MOUSEVWHEEL ? "V" : "H",
      aWParam, aLParam));
 
   mIsWaitingInternalMessage = false;
 
   // If it's not allowed to cache system settings, we need to reset the cache
   // before handling the mouse wheel message.
-  mSystemSettings.TrustedScrollSettingsDriver(aMessage == MOZ_WM_MOUSEVWHEEL);
+  mSystemSettings.TrustedScrollSettingsDriver();
 
   EventInfo eventInfo(aWidget, WinUtils::GetNativeMessage(aMessage),
                       aWParam, aLParam);
   if (!eventInfo.CanDispatchWheelEvent()) {
     MOZ_LOG(gMouseScrollLog, LogLevel::Info,
       ("MouseScroll::HandleMouseWheelMessage: Cannot dispatch the events"));
     mLastEventInfo.ResetTransaction();
     return;
@@ -858,29 +858,36 @@ MouseScrollHandler::LastEventInfo::InitW
 
   delta = static_cast<double>(mDelta) * orienter / nativeDeltaPerUnit;
   mAccumulatedDelta += mDelta;
   lineOrPageDelta =
     mAccumulatedDelta * orienter / RoundDelta(nativeDeltaPerUnit);
   mAccumulatedDelta -=
     lineOrPageDelta * orienter * RoundDelta(nativeDeltaPerUnit);
 
+  aWheelEvent.mAllowToOverrideSystemScrollSpeed =
+    MouseScrollHandler::sInstance->
+      mSystemSettings.IsOverridingSystemScrollSpeedAllowed();
+
   MOZ_LOG(gMouseScrollLog, LogLevel::Info,
     ("MouseScroll::LastEventInfo::InitWheelEvent: aWidget=%p, "
      "aWheelEvent { refPoint: { x: %d, y: %d }, deltaX: %f, deltaY: %f, "
      "lineOrPageDeltaX: %d, lineOrPageDeltaY: %d, "
-     "isShift: %s, isControl: %s, isAlt: %s, isMeta: %s }, "
+     "isShift: %s, isControl: %s, isAlt: %s, isMeta: %s, "
+     "mAllowToOverrideSystemScrollSpeed: %s }, "
      "mAccumulatedDelta: %d",
      aWidget, aWheelEvent.refPoint.x, aWheelEvent.refPoint.y,
      aWheelEvent.deltaX, aWheelEvent.deltaY,
      aWheelEvent.lineOrPageDeltaX, aWheelEvent.lineOrPageDeltaY,
      GetBoolName(aWheelEvent.IsShift()),
      GetBoolName(aWheelEvent.IsControl()),
      GetBoolName(aWheelEvent.IsAlt()),
-     GetBoolName(aWheelEvent.IsMeta()), mAccumulatedDelta));
+     GetBoolName(aWheelEvent.IsMeta()),
+     GetBoolName(aWheelEvent.mAllowToOverrideSystemScrollSpeed),
+     mAccumulatedDelta));
 
   return (delta != 0);
 }
 
 /******************************************************************************
  *
  * SystemSettings
  *
@@ -989,68 +996,77 @@ MouseScrollHandler::SystemSettings::Mark
   mInitialized = false;
   // When system settings are changed, we should reset current transaction.
   MOZ_ASSERT(sInstance,
     "Must not be called at initializing MouseScrollHandler");
   MouseScrollHandler::sInstance->mLastEventInfo.ResetTransaction();
 }
 
 void
-MouseScrollHandler::SystemSettings::RefreshCache(bool aForVertical)
+MouseScrollHandler::SystemSettings::RefreshCache()
 {
-  bool isChanged = aForVertical ? InitScrollLines() : InitScrollChars();
+  bool isChanged = InitScrollLines();
+  isChanged = InitScrollChars() || isChanged;
   if (!isChanged) {
     return;
   }
   // If the scroll amount is changed, we should reset current transaction.
   MOZ_ASSERT(sInstance,
     "Must not be called at initializing MouseScrollHandler");
   MouseScrollHandler::sInstance->mLastEventInfo.ResetTransaction();
 }
 
 void
-MouseScrollHandler::SystemSettings::TrustedScrollSettingsDriver(
-                                      bool aIsVertical)
+MouseScrollHandler::SystemSettings::TrustedScrollSettingsDriver()
 {
   if (!mInitialized) {
     return;
   }
 
   // if the cache is initialized with prefs, we don't need to refresh it.
-  if ((aIsVertical && mIsReliableScrollLines) ||
-      (!aIsVertical && mIsReliableScrollChars)) {
+  if (mIsReliableScrollLines && mIsReliableScrollChars) {
     return;
   }
 
   MouseScrollHandler::UserPrefs& userPrefs =
     MouseScrollHandler::sInstance->mUserPrefs;
 
   // If system settings cache is disabled, we should always refresh them.
   if (!userPrefs.IsSystemSettingCacheEnabled()) {
-    RefreshCache(aIsVertical);
+    RefreshCache();
     return;
   }
 
   // If pref is set to as "always trust the cache", we shouldn't refresh them
   // in any environments.
   if (userPrefs.IsSystemSettingCacheForciblyEnabled()) {
     return;
   }
 
   // If SynTP of Synaptics or Apoint of Alps is installed, it may hook
   // ::SystemParametersInfo() and returns different value from system settings.
   if (Device::SynTP::IsDriverInstalled() ||
       Device::Apoint::IsDriverInstalled()) {
-    RefreshCache(aIsVertical);
+    RefreshCache();
     return;
   }
 
   // XXX We're not sure about other touchpad drivers...
 }
 
+bool
+MouseScrollHandler::SystemSettings::IsOverridingSystemScrollSpeedAllowed()
+{
+  // The default vertical and horizontal scrolling speed is 3, this is defined
+  // on the document of SystemParametersInfo in MSDN.
+  const uint32_t kSystemDefaultScrollingSpeed = 3;
+  return mScrollLines == kSystemDefaultScrollingSpeed &&
+         (!IsVistaOrLater() || mScrollChars == kSystemDefaultScrollingSpeed);
+}
+
 /******************************************************************************
  *
  * UserPrefs
  *
  ******************************************************************************/
 
 MouseScrollHandler::UserPrefs::UserPrefs() :
   mInitialized(false)
--- a/widget/windows/WinMouseScrollHandler.h
+++ b/widget/windows/WinMouseScrollHandler.h
@@ -274,17 +274,23 @@ private:
     void NotifyUserPrefsMayOverrideSystemSettings();
 
     // On some environments, SystemParametersInfo() may be hooked by touchpad
     // utility or something.  In such case, when user changes active pointing
     // device to another one, the result of SystemParametersInfo() may be
     // changed without WM_SETTINGCHANGE message.  For avoiding this trouble,
     // we need to modify cache of system settings at every wheel message
     // handling if we meet known device whose utility may hook the API.
-    void TrustedScrollSettingsDriver(bool aIsVertical);
+    void TrustedScrollSettingsDriver();
+
+    // Returns true if the system scroll may be overridden for faster scroll.
+    // Otherwise, false.  For example, if the user maybe uses an expensive
+    // mouse which supports acceleration of scroll speed, faster scroll makes
+    // the user inconvenient.
+    bool IsOverridingSystemScrollSpeedAllowed();
 
     int32_t GetScrollAmount(bool aForVertical) const
     {
       MOZ_ASSERT(mInitialized, "SystemSettings must be initialized");
       return aForVertical ? mScrollLines : mScrollChars;
     }
 
     bool IsPageScroll(bool aForVertical) const
@@ -305,17 +311,17 @@ private:
 
     int32_t mScrollLines;
     int32_t mScrollChars;
 
     // Returns true if cached value is changed.
     bool InitScrollLines();
     bool InitScrollChars();
 
-    void RefreshCache(bool aForVertical);
+    void RefreshCache();
   };
 
   SystemSettings mSystemSettings;
 
   class UserPrefs {
   public:
     UserPrefs();
     ~UserPrefs();
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -3721,62 +3721,16 @@ nsWindow::OverrideSystemMouseScrollSpeed
                                          double aOriginalDeltaY,
                                          double& aOverriddenDeltaX,
                                          double& aOverriddenDeltaY)
 {
   // The default vertical and horizontal scrolling speed is 3, this is defined
   // on the document of SystemParametersInfo in MSDN.
   const uint32_t kSystemDefaultScrollingSpeed = 3;
 
-  double absOriginDeltaX = Abs(aOriginalDeltaX);
-  double absOriginDeltaY = Abs(aOriginalDeltaY);
-
-  // Compute the simple overridden speed.
-  double absComputedOverriddenDeltaX, absComputedOverriddenDeltaY;
-  nsresult rv =
-    nsBaseWidget::OverrideSystemMouseScrollSpeed(absOriginDeltaX,
-                                                 absOriginDeltaY,
-                                                 absComputedOverriddenDeltaX,
-                                                 absComputedOverriddenDeltaY);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  aOverriddenDeltaX = aOriginalDeltaX;
-  aOverriddenDeltaY = aOriginalDeltaY;
-
-  if (absComputedOverriddenDeltaX == absOriginDeltaX &&
-      absComputedOverriddenDeltaY == absOriginDeltaY) {
-    // We don't override now.
-    return NS_OK;
-  }
-
-  // Otherwise, we should check whether the user customized the system settings
-  // or not.  If the user did it, we should respect the will.
-  UINT systemSpeed;
-  if (!::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &systemSpeed, 0)) {
-    return NS_ERROR_FAILURE;
-  }
-  // The default vertical scrolling speed is 3, this is defined on the document
-  // of SystemParametersInfo in MSDN.
-  if (systemSpeed != kSystemDefaultScrollingSpeed) {
-    return NS_OK;
-  }
-
-  // Only Vista and later, Windows has the system setting of horizontal
-  // scrolling by the mouse wheel.
-  if (IsVistaOrLater()) {
-    if (!::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &systemSpeed, 0)) {
-      return NS_ERROR_FAILURE;
-    }
-    // The default horizontal scrolling speed is 3, this is defined on the
-    // document of SystemParametersInfo in MSDN.
-    if (systemSpeed != kSystemDefaultScrollingSpeed) {
-      return NS_OK;
-    }
-  }
-
   // Limit the overridden delta value from the system settings.  The mouse
   // driver might accelerate the scrolling speed already.  If so, we shouldn't
   // override the scrolling speed for preventing the unexpected high speed
   // scrolling.
   double absDeltaLimitX, absDeltaLimitY;
   rv =
     nsBaseWidget::OverrideSystemMouseScrollSpeed(kSystemDefaultScrollingSpeed,
                                                  kSystemDefaultScrollingSpeed,