Bug 1250050 Add a pref to disable supporting mouse wheel of windowless plugins on Windows r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 26 Feb 2016 09:41:59 +0900
changeset 321994 e7e8a495ded43f7ef0bf8e9dedc58ddc6c47c82c
parent 321993 f2f4c8ce77a3c6415ed55740be32dc75187eaaf0
child 321995 b9fce5b8b83cc086f98a103ce2837d3afb06689a
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1250050
milestone47.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
Bug 1250050 Add a pref to disable supporting mouse wheel of windowless plugins on Windows r=smaug
dom/events/EventStateManager.cpp
dom/events/EventStateManager.h
modules/libpref/init/all.js
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -273,16 +273,17 @@ nsWeakPtr EventStateManager::sPointerLoc
 // Reference to the document which requested pointer lock.
 nsWeakPtr EventStateManager::sPointerLockedDoc;
 nsCOMPtr<nsIContent> EventStateManager::sDragOverContent = nullptr;
 TimeStamp EventStateManager::sLatestUserInputStart;
 TimeStamp EventStateManager::sHandlingInputStart;
 
 EventStateManager::WheelPrefs*
   EventStateManager::WheelPrefs::sInstance = nullptr;
+bool EventStateManager::WheelPrefs::sWheelEventsEnabledOnPlugins = true;
 EventStateManager::DeltaAccumulator*
   EventStateManager::DeltaAccumulator::sInstance = nullptr;
 
 EventStateManager::EventStateManager()
   : mLockCursor(0)
   , mLastFrameConsumedSetCursor(false)
   , mPreLockPoint(0,0)
   , mCurrentTarget(nullptr)
@@ -2362,16 +2363,21 @@ EventStateManager::ComputeScrollTarget(n
 // and before any actual motion
 nsIFrame*
 EventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
                                        double aDirectionX,
                                        double aDirectionY,
                                        WidgetWheelEvent* aEvent,
                                        ComputeScrollTargetOptions aOptions)
 {
+  if ((aOptions & INCLUDE_PLUGIN_AS_TARGET) &&
+      !WheelPrefs::WheelEventsEnabledOnPlugins()) {
+    aOptions = RemovePluginFromTarget(aOptions);
+  }
+
   if (aOptions & PREFER_MOUSE_WHEEL_TRANSACTION) {
     // If the user recently scrolled with the mousewheel, then they probably
     // want to scroll the same view as before instead of the view under the
     // cursor.  WheelTransaction tracks the frame currently being
     // scrolled with the mousewheel. We consider the transaction ended when the
     // mouse moves more than "mousewheel.transaction.ignoremovedelay"
     // milliseconds after the last scroll operation, or any time the mouse moves
     // out of the frame, or when more than "mousewheel.transaction.timeout"
@@ -5510,16 +5516,19 @@ EventStateManager::WheelPrefs::OnPrefCha
   sInstance->Reset();
   DeltaAccumulator::GetInstance()->Reset();
 }
 
 EventStateManager::WheelPrefs::WheelPrefs()
 {
   Reset();
   Preferences::RegisterCallback(OnPrefChanged, "mousewheel.", nullptr);
+  Preferences::AddBoolVarCache(&sWheelEventsEnabledOnPlugins,
+                               "plugin.mousewheel.enabled",
+                               true);
 }
 
 EventStateManager::WheelPrefs::~WheelPrefs()
 {
   Preferences::UnregisterCallback(OnPrefChanged, "mousewheel.", nullptr);
 }
 
 void
@@ -5729,16 +5738,26 @@ EventStateManager::WheelPrefs::GetUserPr
 {
   Index index = GetIndexFor(aEvent);
   Init(index);
 
   *aOutMultiplierX = mMultiplierX[index];
   *aOutMultiplierY = mMultiplierY[index];
 }
 
+// static
+bool
+EventStateManager::WheelPrefs::WheelEventsEnabledOnPlugins()
+{
+  if (!sInstance) {
+    GetInstance(); // initializing sWheelEventsEnabledOnPlugins
+  }
+  return sWheelEventsEnabledOnPlugins;
+}
+
 bool
 EventStateManager::WheelEventIsScrollAction(WidgetWheelEvent* aEvent)
 {
   return aEvent->mMessage == eWheel &&
          WheelPrefs::GetInstance()->ComputeActionFor(aEvent) == WheelPrefs::ACTION_SCROLL;
 }
 
 void
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -504,16 +504,22 @@ protected:
 
     /**
      * IsOverOnePageScrollAllowed*() checks whether wheel scroll amount should
      * be rounded down to the page width/height (false) or not (true).
      */
     bool IsOverOnePageScrollAllowedX(WidgetWheelEvent* aEvent);
     bool IsOverOnePageScrollAllowedY(WidgetWheelEvent* aEvent);
 
+    /**
+     * WheelEventsEnabledOnPlugins() returns true if user wants to use mouse
+     * wheel on plugins.
+     */
+    static bool WheelEventsEnabledOnPlugins();
+
   private:
     WheelPrefs();
     ~WheelPrefs();
 
     static void OnPrefChanged(const char* aPrefName, void* aClosure);
 
     enum Index
     {
@@ -567,16 +573,18 @@ protected:
     /**
      * action values overridden by .override_x pref.
      * If an .override_x value is -1, same as the
      * corresponding mActions value.
      */
     Action mOverriddenActionsX[COUNT_OF_MULTIPLIERS];
 
     static WheelPrefs* sInstance;
+
+    static bool sWheelEventsEnabledOnPlugins;
   };
 
   /**
    * DeltaDirection is used for specifying whether the called method should
    * handle vertical delta or horizontal delta.
    * This is clearer than using bool.
    */
   enum DeltaDirection
@@ -657,30 +665,43 @@ protected:
   enum ComputeScrollTargetOptions
   {
     // At computing scroll target for legacy mouse events, we should return
     // first scrollable element even when it's not scrollable to the direction.
     COMPUTE_LEGACY_MOUSE_SCROLL_EVENT_TARGET     = 0,
     // Default action prefers the scrolled element immediately before if it's
     // still under the mouse cursor.  Otherwise, it prefers the nearest
     // scrollable ancestor which will be scrolled actually.
+    COMPUTE_DEFAULT_ACTION_TARGET_EXCEPT_PLUGIN  =
+      (PREFER_MOUSE_WHEEL_TRANSACTION |
+       PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS |
+       PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS),
     // When this is specified, the result may be nsPluginFrame.  In such case,
     // the frame doesn't have nsIScrollableFrame interface.
     COMPUTE_DEFAULT_ACTION_TARGET                =
-      (PREFER_MOUSE_WHEEL_TRANSACTION |
-       PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS |
-       PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS |
+      (COMPUTE_DEFAULT_ACTION_TARGET_EXCEPT_PLUGIN |
        INCLUDE_PLUGIN_AS_TARGET),
     // Look for the nearest scrollable ancestor which can be scrollable with
     // aEvent.
     COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS     =
       (PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS | START_FROM_PARENT),
     COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS     =
       (PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS | START_FROM_PARENT)
   };
+  static ComputeScrollTargetOptions RemovePluginFromTarget(
+                                      ComputeScrollTargetOptions aOptions)
+  {
+    switch (aOptions) {
+      case COMPUTE_DEFAULT_ACTION_TARGET:
+        return COMPUTE_DEFAULT_ACTION_TARGET_EXCEPT_PLUGIN;
+      default:
+        MOZ_ASSERT(!(aOptions & INCLUDE_PLUGIN_AS_TARGET));
+        return aOptions;
+    }
+  }
   nsIFrame* ComputeScrollTarget(nsIFrame* aTargetFrame,
                                 WidgetWheelEvent* aEvent,
                                 ComputeScrollTargetOptions aOptions);
 
   nsIFrame* ComputeScrollTarget(nsIFrame* aTargetFrame,
                                 double aDirectionX,
                                 double aDirectionY,
                                 WidgetWheelEvent* aEvent,
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -3228,16 +3228,19 @@ pref("plugin.scan.Quicktime", "5.0");
 
 // Locate and scan the Window Media Player installation directory for plugins with a minimum version
 pref("plugin.scan.WindowsMediaPlayer", "7.0");
 
 // Locate plugins by the directories specified in the Windows registry for PLIDs
 // Which is currently HKLM\Software\MozillaPlugins\xxxPLIDxxx\Path
 pref("plugin.scan.plid.all", true);
 
+// Whether sending WM_MOUSEWHEEL and WM_MOUSEHWHEEL to plugins on Windows.
+pref("plugin.mousewheel.enabled", true);
+
 // Help Windows NT, 2000, and XP dialup a RAS connection
 // when a network address is unreachable.
 pref("network.autodial-helper.enabled", true);
 
 // Switch the keyboard layout per window
 pref("intl.keyboard.per_window_layout", false);
 
 #ifdef NS_ENABLE_TSF