diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index 9ec8d4533835..01ee68c09616 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -2430,7 +2430,7 @@ EventStateManager::DoScrollText(nsIScrollableFrame* aScrollableFrame, actualDevPixelScrollAmount.y = 0; } - nsIScrollableFrame::ScrollSnapMode snapMode = nsIScrollableFrame::DISABLE_SNAP; + nsIScrollbarMediator::ScrollSnapMode snapMode = nsIScrollbarMediator::DISABLE_SNAP; nsIAtom* origin = nullptr; switch (aEvent->deltaMode) { case nsIDOMWheelEvent::DOM_DELTA_LINE: diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index b2c263cd5488..d21e791ca627 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1126,21 +1126,24 @@ GetOnePixelRangeAroundPoint(nsPoint aPoint, bool aIsHorizontal) } void -ScrollFrameHelper::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) +ScrollFrameHelper::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap) { ScrollByUnit(aScrollbar, nsIScrollableFrame::SMOOTH, aDirection, - nsIScrollableFrame::PAGES); + nsIScrollableFrame::PAGES, aSnap); } void -ScrollFrameHelper::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) +ScrollFrameHelper::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap) { ScrollByUnit(aScrollbar, nsIScrollableFrame::INSTANT, aDirection, - nsIScrollableFrame::WHOLE); + nsIScrollableFrame::WHOLE, aSnap); } void -ScrollFrameHelper::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) +ScrollFrameHelper::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap) { bool isHorizontal = aScrollbar->IsHorizontal(); nsIntPoint delta; @@ -1157,7 +1160,8 @@ ScrollFrameHelper::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection } nsIntPoint overflow; ScrollBy(delta, nsIScrollableFrame::LINES, nsIScrollableFrame::SMOOTH, - &overflow, nsGkAtoms::other); + &overflow, nsGkAtoms::other, nsIScrollableFrame::NOT_MOMENTUM, + aSnap); } void @@ -1192,11 +1196,24 @@ ScrollFrameHelper::ThumbMoved(nsScrollbarFrame* aScrollbar, ScrollTo(dest, nsIScrollableFrame::INSTANT, &allowedRange); } +void +ScrollFrameHelper::ScrollbarReleased(nsScrollbarFrame* aScrollbar) +{ + // Scrollbar scrolling does not result in fling gestures, clear any + // accumulated velocity + mVelocityQueue.Reset(); + + // Perform scroll snapping, if needed. Scrollbar movement uses the same + // smooth scrolling animation as keyboard scrolling. + ScrollSnap(mDestination, nsIScrollableFrame::SMOOTH); +} + void ScrollFrameHelper::ScrollByUnit(nsScrollbarFrame* aScrollbar, nsIScrollableFrame::ScrollMode aMode, int32_t aDirection, - nsIScrollableFrame::ScrollUnit aUnit) + nsIScrollableFrame::ScrollUnit aUnit, + nsIScrollbarMediator::ScrollSnapMode aSnap) { MOZ_ASSERT(aScrollbar != nullptr); bool isHorizontal = aScrollbar->IsHorizontal(); @@ -1207,7 +1224,8 @@ ScrollFrameHelper::ScrollByUnit(nsScrollbarFrame* aScrollbar, delta.y = aDirection; } nsIntPoint overflow; - ScrollBy(delta, aUnit, aMode, &overflow, nsGkAtoms::other); + ScrollBy(delta, aUnit, aMode, &overflow, nsGkAtoms::other, + nsIScrollableFrame::NOT_MOMENTUM, aSnap); } nsresult @@ -2079,7 +2097,7 @@ ScrollFrameHelper::ScrollToWithOrigin(nsPoint aScrollPosition, nsIScrollableFrame::ScrollMode aMode, nsIAtom *aOrigin, const nsRect* aRange, - nsIScrollableFrame::ScrollSnapMode aSnap) + nsIScrollbarMediator::ScrollSnapMode aSnap) { if (aSnap == nsIScrollableFrame::ENABLE_SNAP) { @@ -3348,7 +3366,7 @@ ScrollFrameHelper::ScrollBy(nsIntPoint aDelta, nsIntPoint* aOverflow, nsIAtom *aOrigin, nsIScrollableFrame::ScrollMomentum aMomentum, - nsIScrollableFrame::ScrollSnapMode aSnap) + nsIScrollbarMediator::ScrollSnapMode aSnap) { // When a smooth scroll is being processed on a frame, mouse wheel and trackpad // momentum scroll event updates must notcancel the SMOOTH or SMOOTH_MSD @@ -3480,7 +3498,7 @@ ScrollFrameHelper::ScrollBy(nsIntPoint aDelta, } void -ScrollFrameHelper::ScrollSnap() +ScrollFrameHelper::ScrollSnap(nsIScrollableFrame::ScrollMode aMode) { float flingSensitivity = gfxPrefs::ScrollSnapPredictionSensitivity(); int maxVelocity = gfxPrefs::ScrollSnapPredictionMaxVelocity(); @@ -3493,7 +3511,7 @@ ScrollFrameHelper::ScrollSnap() predictedOffset.Clamp(maxOffset); nsPoint pos = GetScrollPosition(); nsPoint destinationPos = pos + predictedOffset; - ScrollSnap(destinationPos); + ScrollSnap(destinationPos, aMode); } void @@ -3503,7 +3521,8 @@ ScrollFrameHelper::FlingSnap(const mozilla::CSSPoint& aDestination) } void -ScrollFrameHelper::ScrollSnap(const nsPoint &aDestination) +ScrollFrameHelper::ScrollSnap(const nsPoint &aDestination, + nsIScrollableFrame::ScrollMode aMode) { nsRect scrollRange = GetScrollRangeForClamping(); nsPoint pos = GetScrollPosition(); @@ -3511,7 +3530,7 @@ ScrollFrameHelper::ScrollSnap(const nsPoint &aDestination) if (GetSnapPointForDestination(nsIScrollableFrame::DEVICE_PIXELS, pos, snapDestination)) { - ScrollTo(snapDestination, nsIScrollableFrame::SMOOTH_MSD); + ScrollTo(snapDestination, aMode); } } diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index cd4c4e996907..10838c38eb6c 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -181,8 +181,9 @@ public: void SetResolution(const gfxSize& aResolution); void SetResolutionAndScaleTo(const gfxSize& aResolution); void FlingSnap(const mozilla::CSSPoint& aDestination); - void ScrollSnap(); - void ScrollSnap(const nsPoint &aDestination); + void ScrollSnap(nsIScrollableFrame::ScrollMode aMode = nsIScrollableFrame::SMOOTH_MSD); + void ScrollSnap(const nsPoint &aDestination, + nsIScrollableFrame::ScrollMode aMode = nsIScrollableFrame::SMOOTH_MSD); protected: nsRect GetScrollRangeForClamping() const; @@ -200,7 +201,8 @@ public: */ void ScrollTo(nsPoint aScrollPosition, nsIScrollableFrame::ScrollMode aMode, const nsRect* aRange = nullptr, - nsIScrollableFrame::ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP) { + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) { ScrollToWithOrigin(aScrollPosition, aMode, nsGkAtoms::other, aRange, aSnap); } @@ -229,7 +231,8 @@ public: nsIScrollableFrame::ScrollMode aMode, nsIntPoint* aOverflow, nsIAtom* aOrigin = nullptr, nsIScrollableFrame::ScrollMomentum aMomentum = nsIScrollableFrame::NOT_MOMENTUM, - nsIScrollableFrame::ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP); + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP); /** * @note This method might destroy the frame, pres shell and other objects. */ @@ -380,17 +383,26 @@ public: nsTArray* aOutput) const; // nsIScrollbarMediator - void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection); - void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection); - void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection); + void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP); + void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP); + void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP); void RepeatButtonScroll(nsScrollbarFrame* aScrollbar); void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos, nscoord aNewPos); + void ScrollbarReleased(nsScrollbarFrame* aScrollbar); void ScrollByUnit(nsScrollbarFrame* aScrollbar, nsIScrollableFrame::ScrollMode aMode, int32_t aDirection, - nsIScrollableFrame::ScrollUnit aUnit); + nsIScrollableFrame::ScrollUnit aUnit, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP); // owning references to the nsIAnonymousContentCreator-built content nsCOMPtr mHScrollbarContent; @@ -520,7 +532,8 @@ protected: nsIScrollableFrame::ScrollMode aMode, nsIAtom *aOrigin, // nullptr indicates "other" origin const nsRect* aRange, - nsIScrollableFrame::ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP); + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP); void CompleteAsyncScroll(const nsRect &aRange, nsIAtom* aOrigin = nullptr); @@ -709,7 +722,8 @@ public: */ virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, const nsRect* aRange = nullptr, - nsIScrollableFrame::ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP) + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE { mHelper.ScrollTo(aScrollPosition, aMode, aRange, aSnap); } @@ -737,7 +751,8 @@ public: virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode, nsIntPoint* aOverflow, nsIAtom* aOrigin = nullptr, nsIScrollableFrame::ScrollMomentum aMomentum = nsIScrollableFrame::NOT_MOMENTUM, - nsIScrollableFrame::ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP) + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE { mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum, aSnap); } @@ -845,14 +860,20 @@ public: virtual nsIAtom* GetType() const MOZ_OVERRIDE; // nsIScrollbarMediator - virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { - mHelper.ScrollByPage(aScrollbar, aDirection); + virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE { + mHelper.ScrollByPage(aScrollbar, aDirection, aSnap); } - virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { - mHelper.ScrollByWhole(aScrollbar, aDirection); + virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE { + mHelper.ScrollByWhole(aScrollbar, aDirection, aSnap); } - virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { - mHelper.ScrollByLine(aScrollbar, aDirection); + virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE { + mHelper.ScrollByLine(aScrollbar, aDirection, aSnap); } virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE { mHelper.RepeatButtonScroll(aScrollbar); @@ -862,6 +883,9 @@ public: nscoord aNewPos) MOZ_OVERRIDE { mHelper.ThumbMoved(aScrollbar, aOldPos, aNewPos); } + virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE { + mHelper.ScrollbarReleased(aScrollbar); + } virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE {} virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE { return mHelper.GetScrollbarBox(aVertical); @@ -1090,7 +1114,8 @@ public: */ virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, const nsRect* aRange = nullptr, - ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP) MOZ_OVERRIDE { + ScrollSnapMode aSnap = nsIScrollbarMediator::DISABLE_SNAP) + MOZ_OVERRIDE { mHelper.ScrollTo(aScrollPosition, aMode, aRange, aSnap); } /** @@ -1114,7 +1139,8 @@ public: virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode, nsIntPoint* aOverflow, nsIAtom* aOrigin = nullptr, nsIScrollableFrame::ScrollMomentum aMomentum = nsIScrollableFrame::NOT_MOMENTUM, - nsIScrollableFrame::ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP) + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE { mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum, aSnap); } @@ -1229,14 +1255,20 @@ public: return nsBoxFrame::IsFrameOfType(aFlags); } - virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { - mHelper.ScrollByPage(aScrollbar, aDirection); + virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE { + mHelper.ScrollByPage(aScrollbar, aDirection, aSnap); } - virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { - mHelper.ScrollByWhole(aScrollbar, aDirection); + virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE { + mHelper.ScrollByWhole(aScrollbar, aDirection, aSnap); } - virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { - mHelper.ScrollByLine(aScrollbar, aDirection); + virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE { + mHelper.ScrollByLine(aScrollbar, aDirection, aSnap); } virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE { mHelper.RepeatButtonScroll(aScrollbar); @@ -1246,6 +1278,9 @@ public: nscoord aNewPos) MOZ_OVERRIDE { mHelper.ThumbMoved(aScrollbar, aOldPos, aNewPos); } + virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE { + mHelper.ScrollbarReleased(aScrollbar); + } virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE {} virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE { return mHelper.GetScrollbarBox(aVertical); diff --git a/layout/generic/nsIScrollableFrame.h b/layout/generic/nsIScrollableFrame.h index 20ae8638bf22..6a3cdc65a5ab 100644 --- a/layout/generic/nsIScrollableFrame.h +++ b/layout/generic/nsIScrollableFrame.h @@ -207,13 +207,6 @@ public: * been started since the last actual user input. */ enum ScrollMomentum { NOT_MOMENTUM, SYNTHESIZED_MOMENTUM_EVENT }; - /** - * When set to ENABLE_SNAP, additional scrolling will be performed after the - * scroll operation to maintain the constraints set by CSS Scroll snapping. - * The additional scrolling may include asynchronous smooth scrolls that - * continue to animate after the initial scroll position has been set. - */ - enum ScrollSnapMode { DISABLE_SNAP, ENABLE_SNAP }; /** * @note This method might destroy the frame, pres shell and other objects. * Clamps aScrollPosition to GetScrollRange and sets the scroll position @@ -225,7 +218,8 @@ public: */ virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, const nsRect* aRange = nullptr, - ScrollSnapMode aSnap = DISABLE_SNAP) = 0; + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) = 0; /** * @note This method might destroy the frame, pres shell and other objects. * Scrolls to a particular position in integer CSS pixels. @@ -280,7 +274,8 @@ public: nsIntPoint* aOverflow = nullptr, nsIAtom* aOrigin = nullptr, ScrollMomentum aMomentum = NOT_MOMENTUM, - ScrollSnapMode aSnap = DISABLE_SNAP) = 0; + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) = 0; /** * Perform scroll snapping, possibly resulting in a smooth scroll to diff --git a/layout/xul/nsIScrollbarMediator.h b/layout/xul/nsIScrollbarMediator.h index f6730081660f..e4de93cc79ad 100644 --- a/layout/xul/nsIScrollbarMediator.h +++ b/layout/xul/nsIScrollbarMediator.h @@ -24,14 +24,25 @@ public: * aDirection is either -1, 0, or 1. */ + /** + * When set to ENABLE_SNAP, additional scrolling will be performed after the + * scroll operation to maintain the constraints set by CSS Scroll snapping. + * The additional scrolling may include asynchronous smooth scrolls that + * continue to animate after the initial scroll position has been set. + */ + enum ScrollSnapMode { DISABLE_SNAP, ENABLE_SNAP }; + /** * One of the following three methods is called when the scrollbar's button is * clicked. * @note These methods might destroy the frame, pres shell, and other objects. */ - virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) = 0; - virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) = 0; - virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) = 0; + virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, + ScrollSnapMode aSnap = DISABLE_SNAP) = 0; + virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, + ScrollSnapMode aSnap = DISABLE_SNAP) = 0; + virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, + ScrollSnapMode aSnap = DISABLE_SNAP) = 0; /** * RepeatButtonScroll is called when the scrollbar's button is held down. When the * button is first clicked the increment is set; RepeatButtonScroll adds this @@ -49,6 +60,11 @@ public: virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos, nscoord aNewPos) = 0; + /** + * Called when the scroll bar thumb, slider, or any other component is + * released. + */ + virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) = 0; virtual void VisibilityChanged(bool aVisible) = 0; /** diff --git a/layout/xul/nsListBoxBodyFrame.cpp b/layout/xul/nsListBoxBodyFrame.cpp index 81d139af5fcd..5d867b3317dc 100644 --- a/layout/xul/nsListBoxBodyFrame.cpp +++ b/layout/xul/nsListBoxBodyFrame.cpp @@ -326,8 +326,10 @@ nsListBoxBodyFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState) ///////////// nsIScrollbarMediator /////////////// void -nsListBoxBodyFrame::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) +nsListBoxBodyFrame::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap) { + // CSS Scroll Snapping is not enabled for XUL, aSnap is ignored MOZ_ASSERT(aScrollbar != nullptr); aScrollbar->SetIncrementToPage(aDirection); nsWeakFrame weakFrame(this); @@ -339,8 +341,10 @@ nsListBoxBodyFrame::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirectio } void -nsListBoxBodyFrame::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) +nsListBoxBodyFrame::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap) { + // CSS Scroll Snapping is not enabled for XUL, aSnap is ignored MOZ_ASSERT(aScrollbar != nullptr); aScrollbar->SetIncrementToWhole(aDirection); nsWeakFrame weakFrame(this); @@ -352,8 +356,10 @@ nsListBoxBodyFrame::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirecti } void -nsListBoxBodyFrame::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) +nsListBoxBodyFrame::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap) { + // CSS Scroll Snapping is not enabled for XUL, aSnap is ignored MOZ_ASSERT(aScrollbar != nullptr); aScrollbar->SetIncrementToLine(aDirection); nsWeakFrame weakFrame(this); diff --git a/layout/xul/nsListBoxBodyFrame.h b/layout/xul/nsListBoxBodyFrame.h index a5e20f7efa57..41e4ac170f7d 100644 --- a/layout/xul/nsListBoxBodyFrame.h +++ b/layout/xul/nsListBoxBodyFrame.h @@ -54,13 +54,20 @@ public: virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) MOZ_OVERRIDE; // nsIScrollbarMediator - virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; - virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; - virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; + virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode snapMode + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE; + virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode snapMode + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE; + virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode snapMode + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE; virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE; virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, int32_t aOldPos, int32_t aNewPos) MOZ_OVERRIDE; + virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE {} virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE; virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE; virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE {} diff --git a/layout/xul/nsScrollbarButtonFrame.cpp b/layout/xul/nsScrollbarButtonFrame.cpp index 52ccaf488889..193a477f233f 100644 --- a/layout/xul/nsScrollbarButtonFrame.cpp +++ b/layout/xul/nsScrollbarButtonFrame.cpp @@ -141,19 +141,19 @@ nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext, case 0: sb->SetIncrementToLine(direction); if (m) { - m->ScrollByLine(sb, direction); + m->ScrollByLine(sb, direction, nsIScrollbarMediator::ENABLE_SNAP); } break; case 1: sb->SetIncrementToPage(direction); if (m) { - m->ScrollByPage(sb, direction); + m->ScrollByPage(sb, direction, nsIScrollbarMediator::ENABLE_SNAP); } break; case 2: sb->SetIncrementToWhole(direction); if (m) { - m->ScrollByWhole(sb, direction); + m->ScrollByWhole(sb, direction, nsIScrollbarMediator::ENABLE_SNAP); } break; case 3: @@ -187,6 +187,15 @@ nsScrollbarButtonFrame::HandleRelease(nsPresContext* aPresContext, // we're not active anymore mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true); StopRepeat(); + nsIFrame* scrollbar; + GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar); + nsScrollbarFrame* sb = do_QueryFrame(scrollbar); + if (sb) { + nsIScrollbarMediator* m = sb->GetScrollbarMediator(); + if (m) { + m->ScrollbarReleased(sb); + } + } return NS_OK; } diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index 4093da5c8061..2736dc48dede 100644 --- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -264,7 +264,8 @@ nsSliderFrame::AttributeChanged(int32_t aNameSpaceID, nsIScrollbarMediator* mediator = scrollbarFrame->GetScrollbarMediator(); scrollbarFrame->SetIncrementToWhole(direction); if (mediator) { - mediator->ScrollByWhole(scrollbarFrame, direction); + mediator->ScrollByWhole(scrollbarFrame, direction, + nsIScrollbarMediator::ENABLE_SNAP); } } // 'this' might be destroyed here @@ -1153,6 +1154,14 @@ nsSliderFrame::HandleRelease(nsPresContext* aPresContext, { StopRepeat(); + nsIFrame* scrollbar = GetScrollbar(); + nsScrollbarFrame* sb = do_QueryFrame(scrollbar); + if (sb) { + nsIScrollbarMediator* m = sb->GetScrollbarMediator(); + if (m) { + m->ScrollbarReleased(sb); + } + } return NS_OK; } @@ -1261,7 +1270,7 @@ nsSliderFrame::PageScroll(nscoord aChange) nsIScrollbarMediator* m = sb->GetScrollbarMediator(); sb->SetIncrementToPage(aChange); if (m) { - m->ScrollByPage(sb, aChange); + m->ScrollByPage(sb, aChange, nsIScrollbarMediator::ENABLE_SNAP); return; } } diff --git a/layout/xul/tree/nsTreeBodyFrame.cpp b/layout/xul/tree/nsTreeBodyFrame.cpp index 5f5389426ba3..246ab07a8e47 100644 --- a/layout/xul/tree/nsTreeBodyFrame.cpp +++ b/layout/xul/tree/nsTreeBodyFrame.cpp @@ -4200,23 +4200,29 @@ nsTreeBodyFrame::ScrollHorzInternal(const ScrollParts& aParts, int32_t aPosition } void -nsTreeBodyFrame::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) +nsTreeBodyFrame::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap) { + // CSS Scroll Snapping is not enabled for XUL, aSnap is ignored MOZ_ASSERT(aScrollbar != nullptr); ScrollByPages(aDirection); } void -nsTreeBodyFrame::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) +nsTreeBodyFrame::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap) { + // CSS Scroll Snapping is not enabled for XUL, aSnap is ignored MOZ_ASSERT(aScrollbar != nullptr); int32_t newIndex = aDirection < 0 ? 0 : mTopRowIndex; ScrollToRow(newIndex); } void -nsTreeBodyFrame::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) +nsTreeBodyFrame::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap) { + // CSS Scroll Snapping is not enabled for XUL, aSnap is ignored MOZ_ASSERT(aScrollbar != nullptr); ScrollByLines(aDirection); } diff --git a/layout/xul/tree/nsTreeBodyFrame.h b/layout/xul/tree/nsTreeBodyFrame.h index 8f8c29d18e44..4b9fa16beac6 100644 --- a/layout/xul/tree/nsTreeBodyFrame.h +++ b/layout/xul/tree/nsTreeBodyFrame.h @@ -133,13 +133,20 @@ public: virtual bool PseudoMatches(nsCSSSelector* aSelector) MOZ_OVERRIDE; // nsIScrollbarMediator - virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; - virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; - virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; + virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE; + virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE; + virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode aSnap + = nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE; virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE; virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos, nscoord aNewPos) MOZ_OVERRIDE; + virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE {} virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE { Invalidate(); } virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE { ScrollParts parts = GetScrollParts();