diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index 0e267f35804d..68e4eaed0a6e 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -87,6 +87,7 @@ #include "mozilla/LookAndFeel.h" #include "GeckoProfiler.h" #include "Units.h" +#include "mozilla/layers/APZCTreeManager.h" #ifdef XP_MACOSX #import @@ -3007,7 +3008,18 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext, } WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent(); - switch (WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent)) { + + // When APZ is enabled, the actual scroll animation might be handled by + // the compositor. + WheelPrefs::Action action; + if (gfxPrefs::AsyncPanZoomEnabled() && + layers::APZCTreeManager::WillHandleWheelEvent(wheelEvent)) + { + action = WheelPrefs::ACTION_NONE; + } else { + action = WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent); + } + switch (action) { case WheelPrefs::ACTION_SCROLL: { // For scrolling of default action, we should honor the mouse wheel // transaction. diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 58425fb7b4d4..7523975eab5f 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -854,6 +854,13 @@ APZCTreeManager::ProcessWheelEvent(WidgetWheelEvent& aEvent, return status; } +bool +APZCTreeManager::WillHandleWheelEvent(WidgetWheelEvent* aEvent) +{ + return EventStateManager::WheelEventIsScrollAction(aEvent) && + aEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_LINE; +} + nsEventStatus APZCTreeManager::ReceiveInputEvent(WidgetInputEvent& aEvent, ScrollableLayerGuid* aOutTargetGuid, @@ -891,9 +898,7 @@ APZCTreeManager::ReceiveInputEvent(WidgetInputEvent& aEvent, } case eWheelEventClass: { WidgetWheelEvent& wheelEvent = *aEvent.AsWheelEvent(); - if (wheelEvent.deltaMode != nsIDOMWheelEvent::DOM_DELTA_LINE || - !EventStateManager::WheelEventIsScrollAction(&wheelEvent)) - { + if (!WillHandleWheelEvent(&wheelEvent)) { // Don't send through APZ if we're not scrolling or if the delta mode // is not line-based. return ProcessEvent(aEvent, aOutTargetGuid, aOutInputBlockId); diff --git a/gfx/layers/apz/src/APZCTreeManager.h b/gfx/layers/apz/src/APZCTreeManager.h index eec35caa351f..a33903cc59b8 100644 --- a/gfx/layers/apz/src/APZCTreeManager.h +++ b/gfx/layers/apz/src/APZCTreeManager.h @@ -382,6 +382,15 @@ public: */ nsRefPtr BuildOverscrollHandoffChain(const nsRefPtr& aInitialTarget); +public: + // 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. + // + // Even if this returns false, all wheel events in APZ-aware widgets must + // be sent through APZ so they are transformed correctly for TabParent. + static bool WillHandleWheelEvent(WidgetWheelEvent* aEvent); + protected: // Protected destructor, to discourage deletion outside of Release(): virtual ~APZCTreeManager();