From aed23b285701dbfe461d69420b2d93c06db74dfa Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 3 Nov 2015 14:21:40 -0500 Subject: [PATCH] Bug 1141884 - Handle wheel events on the main thread if the frame has snapping. r=dvander,mstange --- dom/events/EventStateManager.cpp | 8 ++++++++ layout/base/nsDisplayList.cpp | 6 ++++++ layout/base/nsLayoutUtils.cpp | 12 ++++++++++++ layout/base/nsLayoutUtils.h | 6 ++++++ 4 files changed, 32 insertions(+) diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index c35493b67fd..c9ea91a6372 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -3119,6 +3119,14 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext, if (pluginFrame) { MOZ_ASSERT(pluginFrame->WantsToHandleWheelEventAsDefaultAction()); action = WheelPrefs::ACTION_SEND_TO_PLUGIN; + } else if (nsLayoutUtils::IsScrollFrameWithSnapping(frameToScroll)) { + // If the target has scroll-snapping points then we want to handle + // the wheel event on the main thread even if we have APZ enabled. Do + // so and let the APZ know that it should ignore this event. + if (wheelEvent->mFlags.mHandledByAPZ) { + wheelEvent->mFlags.mDefaultPrevented = true; + } + action = WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent); } else if (wheelEvent->mFlags.mHandledByAPZ) { action = WheelPrefs::ACTION_NONE; } else { diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index e8bd59fdb49..9250d8fba21 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -3281,6 +3281,12 @@ nsDisplayLayerEventRegions::AddFrame(nsDisplayListBuilder* aBuilder, if (pluginFrame && pluginFrame->WantsToHandleWheelEventAsDefaultAction()) { mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, borderBox); } + } else if (gfxPlatform::GetPlatform()->SupportsApzWheelInput() && + nsLayoutUtils::IsScrollFrameWithSnapping(aFrame->GetParent())) { + // If the frame is the inner content of a scrollable frame with snap-points + // then we want to handle wheel events for it on the main thread. Add it to + // the d-t-c region so that APZ waits for the main thread. + mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, borderBox); } // Touch action region diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 007e7867730..8b1255a1f52 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -8676,3 +8676,15 @@ nsLayoutUtils::GetSelectionBoundingRect(Selection* aSel) return res; } + +/* static */ bool +nsLayoutUtils::IsScrollFrameWithSnapping(nsIFrame* aFrame) +{ + nsIScrollableFrame* sf = do_QueryFrame(aFrame); + if (!sf) { + return false; + } + ScrollbarStyles styles = sf->GetScrollbarStyles(); + return styles.mScrollSnapTypeY != NS_STYLE_SCROLL_SNAP_TYPE_NONE || + styles.mScrollSnapTypeX != NS_STYLE_SCROLL_SNAP_TYPE_NONE; +} diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 9b2ce653025..3b4416dda69 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2773,6 +2773,12 @@ public: * @param aSel Selection to check */ static nsRect GetSelectionBoundingRect(mozilla::dom::Selection* aSel); + + /** + * Returns true if the given frame is a scrollframe and it has snap points. + */ + static bool IsScrollFrameWithSnapping(nsIFrame* aFrame); + private: static uint32_t sFontSizeInflationEmPerLine; static uint32_t sFontSizeInflationMinTwips;