Bug 1215434 part.1 If scroll target is a plugin frame, EventStateManager::PostHandleEvent() should send the wheel event to the plugin frame even if APZC already handled it r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Sat, 17 Oct 2015 15:50:09 +0900
changeset 268174 e99568ffca32090c9a761240d85c9a7ae033e348
parent 268143 1266f78145c44e6652a6c55288f70e8449dc1822
child 268175 380f6425759c35716dd0382859c8a15b74f186b8
push id29543
push userphilringnalda@gmail.com
push dateSun, 18 Oct 2015 02:55:22 +0000
treeherdermozilla-central@e8c7dfe727cd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1215434
milestone44.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 1215434 part.1 If scroll target is a plugin frame, EventStateManager::PostHandleEvent() should send the wheel event to the plugin frame even if APZC already handled it r=smaug
dom/events/EventStateManager.cpp
layout/generic/nsPluginFrame.cpp
widget/BasicEvents.h
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3104,34 +3104,31 @@ EventStateManager::PostHandleEvent(nsPre
         break;
       }
 
       WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent();
 
       // 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 = nullptr;
-      nsPluginFrame* pluginFrame = nullptr;
+      nsIFrame* frameToScroll =
+        ComputeScrollTarget(aTargetFrame, wheelEvent,
+                            COMPUTE_DEFAULT_ACTION_TARGET);
+      nsPluginFrame* pluginFrame = do_QueryFrame(frameToScroll);
 
       // When APZ is enabled, the actual scroll animation might be handled by
       // the compositor.
       WheelPrefs::Action action;
-      if (wheelEvent->mFlags.mHandledByAPZ) {
+      if (pluginFrame) {
+        MOZ_ASSERT(pluginFrame->WantsToHandleWheelEventAsDefaultAction());
+        action = WheelPrefs::ACTION_SEND_TO_PLUGIN;
+      } else if (wheelEvent->mFlags.mHandledByAPZ) {
         action = WheelPrefs::ACTION_NONE;
       } else {
-        frameToScroll = ComputeScrollTarget(aTargetFrame, wheelEvent,
-                                            COMPUTE_DEFAULT_ACTION_TARGET);
-        pluginFrame = do_QueryFrame(frameToScroll);
-        if (pluginFrame) {
-          MOZ_ASSERT(pluginFrame->WantsToHandleWheelEventAsDefaultAction());
-          action = WheelPrefs::ACTION_SEND_TO_PLUGIN;
-        } else {
-          action = WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent);
-        }
+        action = WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent);
       }
       switch (action) {
         case WheelPrefs::ACTION_SCROLL: {
           // For scrolling of default action, we should honor the mouse wheel
           // transaction.
 
           ScrollbarsForWheel::PrepareToScrollText(this, aTargetFrame, wheelEvent);
 
--- a/layout/generic/nsPluginFrame.cpp
+++ b/layout/generic/nsPluginFrame.cpp
@@ -1865,16 +1865,18 @@ nsPluginFrame::HandleWheelEventAsDefault
   }
 
   mInstanceOwner->ProcessEvent(*aWheelEvent);
   // We need to assume that the event is always consumed/handled by the
   // plugin.  There is no way to know if it's actually consumed/handled.
   aWheelEvent->mViewPortIsOverscrolled = false;
   aWheelEvent->overflowDeltaX = 0;
   aWheelEvent->overflowDeltaY = 0;
+  // Consume the event explicitly.
+  aWheelEvent->PreventDefault();
 }
 
 bool
 nsPluginFrame::WantsToHandleWheelEventAsDefaultAction() const
 {
 #ifdef XP_WIN
   if (!mInstanceOwner) {
     return false;
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -269,16 +269,22 @@ public:
     // mFlags should be copied manually if it's necessary.
     userType = aEvent.userType;
     // typeString should be copied manually if it's necessary.
     target = aCopyTargets ? aEvent.target : nullptr;
     currentTarget = aCopyTargets ? aEvent.currentTarget : nullptr;
     originalTarget = aCopyTargets ? aEvent.originalTarget : nullptr;
   }
 
+  void PreventDefault()
+  {
+    mFlags.mDefaultPrevented = true;
+    mFlags.mDefaultPreventedByChrome = true;
+  }
+
   /**
    * Utils for checking event types
    */
 
   /**
    * As*Event() returns the pointer of the instance only when the instance is
    * the class or one of its derived class.
    */