Bug 1458063 - Refactor WillHandleWheelEvent() to also indicate the type of action APZ should take. r=kats draft
authorBotond Ballo <botond@mozilla.com>
Mon, 30 Apr 2018 22:11:10 -0400
changeset 790824 2ea04360700530e1fbbbaaf94b484b6df2f79fe4
parent 790799 a2cc6fd9d6259071545ddbd48b738429bfa1c71f
child 790825 6e42ce08841c44b7c637ddbd878b5372d5d1225b
push id108607
push userbballo@mozilla.com
push dateWed, 02 May 2018 21:54:50 +0000
reviewerskats
bugs1458063
milestone61.0a1
Bug 1458063 - Refactor WillHandleWheelEvent() to also indicate the type of action APZ should take. r=kats MozReview-Commit-ID: LfinNZYqiwt
dom/events/EventStateManager.cpp
dom/events/EventStateManager.h
gfx/layers/apz/public/APZInputBridge.h
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZInputBridge.cpp
gfx/layers/apz/src/APZUtils.h
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -6240,26 +6240,31 @@ EventStateManager::WheelPrefs::HonoursRo
 {
   if (!sInstance) {
     GetInstance(); // initializing sHonoursRootForAutoDir
   }
   return sHonoursRootForAutoDir;
 }
 
 // static
-bool
-EventStateManager::WheelEventIsScrollAction(const WidgetWheelEvent* aEvent)
+Maybe<layers::APZWheelAction> 
+EventStateManager::APZWheelActionFor(const WidgetWheelEvent* aEvent)
 {
   if (aEvent->mMessage != eWheel) {
-    return false;
+    return Nothing();
   }
   WheelPrefs::Action action =
     WheelPrefs::GetInstance()->ComputeActionFor(aEvent);
-  return action == WheelPrefs::ACTION_SCROLL ||
-         action == WheelPrefs::ACTION_HORIZONTALIZED_SCROLL;
+  switch (action) {
+  case WheelPrefs::ACTION_SCROLL:
+  case WheelPrefs::ACTION_HORIZONTALIZED_SCROLL:
+    return Some(layers::APZWheelAction::Scroll);
+  default:
+    return Nothing();
+  }
 }
 
 // static
 WheelDeltaAdjustmentStrategy
 EventStateManager::GetWheelDeltaAdjustmentStrategy(
                      const WidgetWheelEvent& aEvent)
 {
   if (aEvent.mMessage != eWheel) {
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -10,16 +10,17 @@
 #include "mozilla/EventForwards.h"
 
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/TimeStamp.h"
+#include "mozilla/layers/APZUtils.h"
 #include "nsIFrame.h"
 #include "Units.h"
 #include "WheelHandlingHelper.h"          // for WheelDeltaAdjustmentStrategy
 
 #define NS_USER_INTERACTION_INTERVAL 5000 // ms
 
 class nsFrameLoader;
 class nsIContent;
@@ -301,18 +302,18 @@ public:
   static void SetActiveManager(EventStateManager* aNewESM,
                                nsIContent* aContent);
 
   // 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 the kind of APZ action the given WidgetWheelEvent will perform.
+  static Maybe<layers::APZWheelAction> APZWheelActionFor(const WidgetWheelEvent* aEvent);
 
   // 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::eAutoDir if the current default
   // action is auto-dir scrolling which honours the scrolling target(The
   // comments in WheelDeltaAdjustmentStrategy describes the concept in detail).
--- a/gfx/layers/apz/public/APZInputBridge.h
+++ b/gfx/layers/apz/public/APZInputBridge.h
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #ifndef mozilla_layers_APZInputBridge_h
 #define mozilla_layers_APZInputBridge_h
 
+#include "APZUtils.h"                   // for APZWheelAction
 #include "mozilla/EventForwards.h"      // for WidgetInputEvent, nsEventStatus
 #include "Units.h"                      // for LayoutDeviceIntPoint
 
 namespace mozilla {
 
 class InputData;
 
 namespace layers {
@@ -85,23 +86,23 @@ public:
    *
    * See documentation for other ReceiveInputEvent above.
    */
   nsEventStatus ReceiveInputEvent(
       WidgetInputEvent& aEvent,
       ScrollableLayerGuid* aOutTargetGuid,
       uint64_t* aOutInputBlockId);
 
-  // Returns whether or not a wheel event action will be (or was) performed by
-  // APZ. If this returns true, the event must not perform a synchronous
-  // scroll.
+  // Returns the kind of wheel event action, if any, that will be (or was)
+  // performed by APZ. If this returns true, the event must not perform a
+  // synchronous scroll.
   //
-  // Even if this returns false, all wheel events in APZ-aware widgets must
+  // Even if this returns Nothing(), all wheel events in APZ-aware widgets must
   // be sent through APZ so they are transformed correctly for TabParent.
-  static bool WillHandleWheelEvent(WidgetWheelEvent* aEvent);
+  static Maybe<APZWheelAction> ActionForWheelEvent(WidgetWheelEvent* aEvent);
 
 protected:
   friend class APZInputBridgeParent;
 
   // Methods to help process WidgetInputEvents (or manage conversion to/from InputData)
 
   virtual void ProcessUnhandledEvent(
       LayoutDeviceIntPoint* aRefPoint,
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1106,17 +1106,17 @@ template<typename PanGestureOrScrollWhee
 static bool
 WillHandleInput(const PanGestureOrScrollWheelInput& aPanInput)
 {
   if (!XRE_IsParentProcess() || !NS_IsMainThread()) {
     return true;
   }
 
   WidgetWheelEvent wheelEvent = aPanInput.ToWidgetWheelEvent(nullptr);
-  return APZInputBridge::WillHandleWheelEvent(&wheelEvent);
+  return APZInputBridge::ActionForWheelEvent(&wheelEvent).isSome();
 }
 
 void
 APZCTreeManager::FlushApzRepaints(LayersId aLayersId)
 {
   // Previously, paints were throttled and therefore this method was used to
   // ensure any pending paints were flushed. Now, paints are flushed
   // immediately, so it is safe to simply send a notification now.
--- a/gfx/layers/apz/src/APZInputBridge.cpp
+++ b/gfx/layers/apz/src/APZInputBridge.cpp
@@ -25,23 +25,25 @@ WillHandleMouseEvent(const WidgetMouseEv
 {
   return aEvent.mMessage == eMouseMove ||
          aEvent.mMessage == eMouseDown ||
          aEvent.mMessage == eMouseUp ||
          aEvent.mMessage == eDragEnd ||
          (gfxPrefs::TestEventsAsyncEnabled() && aEvent.mMessage == eMouseHitTest);
 }
 
-/* static */ bool
-APZInputBridge::WillHandleWheelEvent(WidgetWheelEvent* aEvent)
+/* static */ Maybe<APZWheelAction>
+APZInputBridge::ActionForWheelEvent(WidgetWheelEvent* aEvent)
 {
-  return EventStateManager::WheelEventIsScrollAction(aEvent) &&
-         (aEvent->mDeltaMode == dom::WheelEventBinding::DOM_DELTA_LINE ||
-          aEvent->mDeltaMode == dom::WheelEventBinding::DOM_DELTA_PIXEL ||
-          aEvent->mDeltaMode == dom::WheelEventBinding::DOM_DELTA_PAGE);
+  if (!(aEvent->mDeltaMode == dom::WheelEventBinding::DOM_DELTA_LINE ||
+        aEvent->mDeltaMode == dom::WheelEventBinding::DOM_DELTA_PIXEL ||
+        aEvent->mDeltaMode == dom::WheelEventBinding::DOM_DELTA_PAGE)) {
+    return Nothing();
+  }
+  return EventStateManager::APZWheelActionFor(aEvent);
 }
 
 nsEventStatus
 APZInputBridge::ReceiveInputEvent(
     WidgetInputEvent& aEvent,
     ScrollableLayerGuid* aOutTargetGuid,
     uint64_t* aOutInputBlockId)
 {
@@ -100,17 +102,17 @@ APZInputBridge::ReceiveInputEvent(
       touchEvent.mFlags.mHandledByAPZ = touchInput.mHandledByAPZ;
       touchEvent.mFocusSequenceNumber = touchInput.mFocusSequenceNumber;
       return result;
 
     }
     case eWheelEventClass: {
       WidgetWheelEvent& wheelEvent = *aEvent.AsWheelEvent();
 
-      if (WillHandleWheelEvent(&wheelEvent)) {
+      if (Maybe<APZWheelAction> action = ActionForWheelEvent(&wheelEvent)) {
 
         ScrollWheelInput::ScrollMode scrollMode = ScrollWheelInput::SCROLLMODE_INSTANT;
         if (gfxPrefs::SmoothScrollEnabled() &&
             ((wheelEvent.mDeltaMode == dom::WheelEventBinding::DOM_DELTA_LINE &&
               gfxPrefs::WheelSmoothScrollEnabled()) ||
              (wheelEvent.mDeltaMode == dom::WheelEventBinding::DOM_DELTA_PAGE &&
               gfxPrefs::PageSmoothScrollEnabled())))
         {
--- a/gfx/layers/apz/src/APZUtils.h
+++ b/gfx/layers/apz/src/APZUtils.h
@@ -8,16 +8,17 @@
 #define mozilla_layers_APZUtils_h
 
 #include <stdint.h>                     // for uint32_t
 #include "FrameMetrics.h"
 #include "LayersTypes.h"
 #include "UnitTransforms.h"
 #include "mozilla/gfx/CompositorHitTestInfo.h"
 #include "mozilla/gfx/Point.h"
+#include "mozilla/DefineEnum.h"
 #include "mozilla/EnumSet.h"
 #include "mozilla/FloatingPoint.h"
 
 namespace mozilla {
 namespace layers {
 
 enum CancelAnimationFlags : uint32_t {
   Default = 0x0,             /* Cancel all animations */
@@ -46,16 +47,20 @@ enum class ScrollSource {
 
   // Mouse wheel.
   Wheel,
 
   // Keyboard
   Keyboard,
 };
 
+MOZ_DEFINE_ENUM_CLASS_WITH_BASE(APZWheelAction, uint8_t, (
+    Scroll
+))
+
 // Epsilon to be used when comparing 'float' coordinate values
 // with FuzzyEqualsAdditive. The rationale is that 'float' has 7 decimal
 // digits of precision, and coordinate values should be no larger than in the
 // ten thousands. Note also that the smallest legitimate difference in page
 // coordinates is 1 app unit, which is 1/60 of a (CSS pixel), so this epsilon
 // isn't too large.
 const float COORDINATE_EPSILON = 0.01f;