Bug 969250 - Part 1: Implement scroll snapping for scrollbars (v5 Patch). r=roc

This commit is contained in:
Kearwood (Kip) Gilbert
2015-03-03 17:40:00 +01:00
parent d52a16a476
commit c1456fb0f3
11 changed files with 178 additions and 69 deletions

View File

@@ -2430,7 +2430,7 @@ EventStateManager::DoScrollText(nsIScrollableFrame* aScrollableFrame,
actualDevPixelScrollAmount.y = 0; actualDevPixelScrollAmount.y = 0;
} }
nsIScrollableFrame::ScrollSnapMode snapMode = nsIScrollableFrame::DISABLE_SNAP; nsIScrollbarMediator::ScrollSnapMode snapMode = nsIScrollbarMediator::DISABLE_SNAP;
nsIAtom* origin = nullptr; nsIAtom* origin = nullptr;
switch (aEvent->deltaMode) { switch (aEvent->deltaMode) {
case nsIDOMWheelEvent::DOM_DELTA_LINE: case nsIDOMWheelEvent::DOM_DELTA_LINE:

View File

@@ -1126,21 +1126,24 @@ GetOnePixelRangeAroundPoint(nsPoint aPoint, bool aIsHorizontal)
} }
void void
ScrollFrameHelper::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) ScrollFrameHelper::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
nsIScrollbarMediator::ScrollSnapMode aSnap)
{ {
ScrollByUnit(aScrollbar, nsIScrollableFrame::SMOOTH, aDirection, ScrollByUnit(aScrollbar, nsIScrollableFrame::SMOOTH, aDirection,
nsIScrollableFrame::PAGES); nsIScrollableFrame::PAGES, aSnap);
} }
void void
ScrollFrameHelper::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) ScrollFrameHelper::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection,
nsIScrollbarMediator::ScrollSnapMode aSnap)
{ {
ScrollByUnit(aScrollbar, nsIScrollableFrame::INSTANT, aDirection, ScrollByUnit(aScrollbar, nsIScrollableFrame::INSTANT, aDirection,
nsIScrollableFrame::WHOLE); nsIScrollableFrame::WHOLE, aSnap);
} }
void void
ScrollFrameHelper::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) ScrollFrameHelper::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection,
nsIScrollbarMediator::ScrollSnapMode aSnap)
{ {
bool isHorizontal = aScrollbar->IsHorizontal(); bool isHorizontal = aScrollbar->IsHorizontal();
nsIntPoint delta; nsIntPoint delta;
@@ -1157,7 +1160,8 @@ ScrollFrameHelper::ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection
} }
nsIntPoint overflow; nsIntPoint overflow;
ScrollBy(delta, nsIScrollableFrame::LINES, nsIScrollableFrame::SMOOTH, ScrollBy(delta, nsIScrollableFrame::LINES, nsIScrollableFrame::SMOOTH,
&overflow, nsGkAtoms::other); &overflow, nsGkAtoms::other, nsIScrollableFrame::NOT_MOMENTUM,
aSnap);
} }
void void
@@ -1192,11 +1196,24 @@ ScrollFrameHelper::ThumbMoved(nsScrollbarFrame* aScrollbar,
ScrollTo(dest, nsIScrollableFrame::INSTANT, &allowedRange); 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 void
ScrollFrameHelper::ScrollByUnit(nsScrollbarFrame* aScrollbar, ScrollFrameHelper::ScrollByUnit(nsScrollbarFrame* aScrollbar,
nsIScrollableFrame::ScrollMode aMode, nsIScrollableFrame::ScrollMode aMode,
int32_t aDirection, int32_t aDirection,
nsIScrollableFrame::ScrollUnit aUnit) nsIScrollableFrame::ScrollUnit aUnit,
nsIScrollbarMediator::ScrollSnapMode aSnap)
{ {
MOZ_ASSERT(aScrollbar != nullptr); MOZ_ASSERT(aScrollbar != nullptr);
bool isHorizontal = aScrollbar->IsHorizontal(); bool isHorizontal = aScrollbar->IsHorizontal();
@@ -1207,7 +1224,8 @@ ScrollFrameHelper::ScrollByUnit(nsScrollbarFrame* aScrollbar,
delta.y = aDirection; delta.y = aDirection;
} }
nsIntPoint overflow; nsIntPoint overflow;
ScrollBy(delta, aUnit, aMode, &overflow, nsGkAtoms::other); ScrollBy(delta, aUnit, aMode, &overflow, nsGkAtoms::other,
nsIScrollableFrame::NOT_MOMENTUM, aSnap);
} }
nsresult nsresult
@@ -2079,7 +2097,7 @@ ScrollFrameHelper::ScrollToWithOrigin(nsPoint aScrollPosition,
nsIScrollableFrame::ScrollMode aMode, nsIScrollableFrame::ScrollMode aMode,
nsIAtom *aOrigin, nsIAtom *aOrigin,
const nsRect* aRange, const nsRect* aRange,
nsIScrollableFrame::ScrollSnapMode aSnap) nsIScrollbarMediator::ScrollSnapMode aSnap)
{ {
if (aSnap == nsIScrollableFrame::ENABLE_SNAP) { if (aSnap == nsIScrollableFrame::ENABLE_SNAP) {
@@ -3348,7 +3366,7 @@ ScrollFrameHelper::ScrollBy(nsIntPoint aDelta,
nsIntPoint* aOverflow, nsIntPoint* aOverflow,
nsIAtom *aOrigin, nsIAtom *aOrigin,
nsIScrollableFrame::ScrollMomentum aMomentum, nsIScrollableFrame::ScrollMomentum aMomentum,
nsIScrollableFrame::ScrollSnapMode aSnap) nsIScrollbarMediator::ScrollSnapMode aSnap)
{ {
// When a smooth scroll is being processed on a frame, mouse wheel and trackpad // 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 // momentum scroll event updates must notcancel the SMOOTH or SMOOTH_MSD
@@ -3480,7 +3498,7 @@ ScrollFrameHelper::ScrollBy(nsIntPoint aDelta,
} }
void void
ScrollFrameHelper::ScrollSnap() ScrollFrameHelper::ScrollSnap(nsIScrollableFrame::ScrollMode aMode)
{ {
float flingSensitivity = gfxPrefs::ScrollSnapPredictionSensitivity(); float flingSensitivity = gfxPrefs::ScrollSnapPredictionSensitivity();
int maxVelocity = gfxPrefs::ScrollSnapPredictionMaxVelocity(); int maxVelocity = gfxPrefs::ScrollSnapPredictionMaxVelocity();
@@ -3493,7 +3511,7 @@ ScrollFrameHelper::ScrollSnap()
predictedOffset.Clamp(maxOffset); predictedOffset.Clamp(maxOffset);
nsPoint pos = GetScrollPosition(); nsPoint pos = GetScrollPosition();
nsPoint destinationPos = pos + predictedOffset; nsPoint destinationPos = pos + predictedOffset;
ScrollSnap(destinationPos); ScrollSnap(destinationPos, aMode);
} }
void void
@@ -3503,7 +3521,8 @@ ScrollFrameHelper::FlingSnap(const mozilla::CSSPoint& aDestination)
} }
void void
ScrollFrameHelper::ScrollSnap(const nsPoint &aDestination) ScrollFrameHelper::ScrollSnap(const nsPoint &aDestination,
nsIScrollableFrame::ScrollMode aMode)
{ {
nsRect scrollRange = GetScrollRangeForClamping(); nsRect scrollRange = GetScrollRangeForClamping();
nsPoint pos = GetScrollPosition(); nsPoint pos = GetScrollPosition();
@@ -3511,7 +3530,7 @@ ScrollFrameHelper::ScrollSnap(const nsPoint &aDestination)
if (GetSnapPointForDestination(nsIScrollableFrame::DEVICE_PIXELS, if (GetSnapPointForDestination(nsIScrollableFrame::DEVICE_PIXELS,
pos, pos,
snapDestination)) { snapDestination)) {
ScrollTo(snapDestination, nsIScrollableFrame::SMOOTH_MSD); ScrollTo(snapDestination, aMode);
} }
} }

View File

@@ -181,8 +181,9 @@ public:
void SetResolution(const gfxSize& aResolution); void SetResolution(const gfxSize& aResolution);
void SetResolutionAndScaleTo(const gfxSize& aResolution); void SetResolutionAndScaleTo(const gfxSize& aResolution);
void FlingSnap(const mozilla::CSSPoint& aDestination); void FlingSnap(const mozilla::CSSPoint& aDestination);
void ScrollSnap(); void ScrollSnap(nsIScrollableFrame::ScrollMode aMode = nsIScrollableFrame::SMOOTH_MSD);
void ScrollSnap(const nsPoint &aDestination); void ScrollSnap(const nsPoint &aDestination,
nsIScrollableFrame::ScrollMode aMode = nsIScrollableFrame::SMOOTH_MSD);
protected: protected:
nsRect GetScrollRangeForClamping() const; nsRect GetScrollRangeForClamping() const;
@@ -200,7 +201,8 @@ public:
*/ */
void ScrollTo(nsPoint aScrollPosition, nsIScrollableFrame::ScrollMode aMode, void ScrollTo(nsPoint aScrollPosition, nsIScrollableFrame::ScrollMode aMode,
const nsRect* aRange = nullptr, const nsRect* aRange = nullptr,
nsIScrollableFrame::ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP) { nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP) {
ScrollToWithOrigin(aScrollPosition, aMode, nsGkAtoms::other, aRange, ScrollToWithOrigin(aScrollPosition, aMode, nsGkAtoms::other, aRange,
aSnap); aSnap);
} }
@@ -229,7 +231,8 @@ public:
nsIScrollableFrame::ScrollMode aMode, nsIntPoint* aOverflow, nsIScrollableFrame::ScrollMode aMode, nsIntPoint* aOverflow,
nsIAtom* aOrigin = nullptr, nsIAtom* aOrigin = nullptr,
nsIScrollableFrame::ScrollMomentum aMomentum = nsIScrollableFrame::NOT_MOMENTUM, 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. * @note This method might destroy the frame, pres shell and other objects.
*/ */
@@ -380,17 +383,26 @@ public:
nsTArray<FrameMetrics>* aOutput) const; nsTArray<FrameMetrics>* aOutput) const;
// nsIScrollbarMediator // nsIScrollbarMediator
void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection); void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection); nsIScrollbarMediator::ScrollSnapMode aSnap
void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection); = 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 RepeatButtonScroll(nsScrollbarFrame* aScrollbar);
void ThumbMoved(nsScrollbarFrame* aScrollbar, void ThumbMoved(nsScrollbarFrame* aScrollbar,
nscoord aOldPos, nscoord aOldPos,
nscoord aNewPos); nscoord aNewPos);
void ScrollbarReleased(nsScrollbarFrame* aScrollbar);
void ScrollByUnit(nsScrollbarFrame* aScrollbar, void ScrollByUnit(nsScrollbarFrame* aScrollbar,
nsIScrollableFrame::ScrollMode aMode, nsIScrollableFrame::ScrollMode aMode,
int32_t aDirection, int32_t aDirection,
nsIScrollableFrame::ScrollUnit aUnit); nsIScrollableFrame::ScrollUnit aUnit,
nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP);
// owning references to the nsIAnonymousContentCreator-built content // owning references to the nsIAnonymousContentCreator-built content
nsCOMPtr<nsIContent> mHScrollbarContent; nsCOMPtr<nsIContent> mHScrollbarContent;
@@ -520,7 +532,8 @@ protected:
nsIScrollableFrame::ScrollMode aMode, nsIScrollableFrame::ScrollMode aMode,
nsIAtom *aOrigin, // nullptr indicates "other" origin nsIAtom *aOrigin, // nullptr indicates "other" origin
const nsRect* aRange, const nsRect* aRange,
nsIScrollableFrame::ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP); nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP);
void CompleteAsyncScroll(const nsRect &aRange, nsIAtom* aOrigin = nullptr); void CompleteAsyncScroll(const nsRect &aRange, nsIAtom* aOrigin = nullptr);
@@ -709,7 +722,8 @@ public:
*/ */
virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode,
const nsRect* aRange = nullptr, const nsRect* aRange = nullptr,
nsIScrollableFrame::ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP) nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP)
MOZ_OVERRIDE { MOZ_OVERRIDE {
mHelper.ScrollTo(aScrollPosition, aMode, aRange, aSnap); mHelper.ScrollTo(aScrollPosition, aMode, aRange, aSnap);
} }
@@ -737,7 +751,8 @@ public:
virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode, virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode,
nsIntPoint* aOverflow, nsIAtom* aOrigin = nullptr, nsIntPoint* aOverflow, nsIAtom* aOrigin = nullptr,
nsIScrollableFrame::ScrollMomentum aMomentum = nsIScrollableFrame::NOT_MOMENTUM, nsIScrollableFrame::ScrollMomentum aMomentum = nsIScrollableFrame::NOT_MOMENTUM,
nsIScrollableFrame::ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP) nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP)
MOZ_OVERRIDE { MOZ_OVERRIDE {
mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum, aSnap); mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum, aSnap);
} }
@@ -845,14 +860,20 @@ public:
virtual nsIAtom* GetType() const MOZ_OVERRIDE; virtual nsIAtom* GetType() const MOZ_OVERRIDE;
// nsIScrollbarMediator // nsIScrollbarMediator
virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
mHelper.ScrollByPage(aScrollbar, aDirection); nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE {
mHelper.ScrollByPage(aScrollbar, aDirection, aSnap);
} }
virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection,
mHelper.ScrollByWhole(aScrollbar, aDirection); nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE {
mHelper.ScrollByWhole(aScrollbar, aDirection, aSnap);
} }
virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection,
mHelper.ScrollByLine(aScrollbar, aDirection); nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE {
mHelper.ScrollByLine(aScrollbar, aDirection, aSnap);
} }
virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE { virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE {
mHelper.RepeatButtonScroll(aScrollbar); mHelper.RepeatButtonScroll(aScrollbar);
@@ -862,6 +883,9 @@ public:
nscoord aNewPos) MOZ_OVERRIDE { nscoord aNewPos) MOZ_OVERRIDE {
mHelper.ThumbMoved(aScrollbar, aOldPos, aNewPos); mHelper.ThumbMoved(aScrollbar, aOldPos, aNewPos);
} }
virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE {
mHelper.ScrollbarReleased(aScrollbar);
}
virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE {} virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE {}
virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE { virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
return mHelper.GetScrollbarBox(aVertical); return mHelper.GetScrollbarBox(aVertical);
@@ -1090,7 +1114,8 @@ public:
*/ */
virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode,
const nsRect* aRange = nullptr, const nsRect* aRange = nullptr,
ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP) MOZ_OVERRIDE { ScrollSnapMode aSnap = nsIScrollbarMediator::DISABLE_SNAP)
MOZ_OVERRIDE {
mHelper.ScrollTo(aScrollPosition, aMode, aRange, aSnap); mHelper.ScrollTo(aScrollPosition, aMode, aRange, aSnap);
} }
/** /**
@@ -1114,7 +1139,8 @@ public:
virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode, virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode,
nsIntPoint* aOverflow, nsIAtom* aOrigin = nullptr, nsIntPoint* aOverflow, nsIAtom* aOrigin = nullptr,
nsIScrollableFrame::ScrollMomentum aMomentum = nsIScrollableFrame::NOT_MOMENTUM, nsIScrollableFrame::ScrollMomentum aMomentum = nsIScrollableFrame::NOT_MOMENTUM,
nsIScrollableFrame::ScrollSnapMode aSnap = nsIScrollableFrame::DISABLE_SNAP) nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP)
MOZ_OVERRIDE { MOZ_OVERRIDE {
mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum, aSnap); mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum, aSnap);
} }
@@ -1229,14 +1255,20 @@ public:
return nsBoxFrame::IsFrameOfType(aFlags); return nsBoxFrame::IsFrameOfType(aFlags);
} }
virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
mHelper.ScrollByPage(aScrollbar, aDirection); nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE {
mHelper.ScrollByPage(aScrollbar, aDirection, aSnap);
} }
virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection,
mHelper.ScrollByWhole(aScrollbar, aDirection); nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE {
mHelper.ScrollByWhole(aScrollbar, aDirection, aSnap);
} }
virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE { virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection,
mHelper.ScrollByLine(aScrollbar, aDirection); nsIScrollbarMediator::ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP) MOZ_OVERRIDE {
mHelper.ScrollByLine(aScrollbar, aDirection, aSnap);
} }
virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE { virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE {
mHelper.RepeatButtonScroll(aScrollbar); mHelper.RepeatButtonScroll(aScrollbar);
@@ -1246,6 +1278,9 @@ public:
nscoord aNewPos) MOZ_OVERRIDE { nscoord aNewPos) MOZ_OVERRIDE {
mHelper.ThumbMoved(aScrollbar, aOldPos, aNewPos); mHelper.ThumbMoved(aScrollbar, aOldPos, aNewPos);
} }
virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE {
mHelper.ScrollbarReleased(aScrollbar);
}
virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE {} virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE {}
virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE { virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
return mHelper.GetScrollbarBox(aVertical); return mHelper.GetScrollbarBox(aVertical);

View File

@@ -207,13 +207,6 @@ public:
* been started since the last actual user input. * been started since the last actual user input.
*/ */
enum ScrollMomentum { NOT_MOMENTUM, SYNTHESIZED_MOMENTUM_EVENT }; 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. * @note This method might destroy the frame, pres shell and other objects.
* Clamps aScrollPosition to GetScrollRange and sets the scroll position * Clamps aScrollPosition to GetScrollRange and sets the scroll position
@@ -225,7 +218,8 @@ public:
*/ */
virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode,
const nsRect* aRange = nullptr, 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. * @note This method might destroy the frame, pres shell and other objects.
* Scrolls to a particular position in integer CSS pixels. * Scrolls to a particular position in integer CSS pixels.
@@ -280,7 +274,8 @@ public:
nsIntPoint* aOverflow = nullptr, nsIntPoint* aOverflow = nullptr,
nsIAtom* aOrigin = nullptr, nsIAtom* aOrigin = nullptr,
ScrollMomentum aMomentum = NOT_MOMENTUM, 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 * Perform scroll snapping, possibly resulting in a smooth scroll to

View File

@@ -24,14 +24,25 @@ public:
* aDirection is either -1, 0, or 1. * 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 * One of the following three methods is called when the scrollbar's button is
* clicked. * clicked.
* @note These methods might destroy the frame, pres shell, and other objects. * @note These methods might destroy the frame, pres shell, and other objects.
*/ */
virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) = 0; virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) = 0; ScrollSnapMode aSnap = DISABLE_SNAP) = 0;
virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) = 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 * RepeatButtonScroll is called when the scrollbar's button is held down. When the
* button is first clicked the increment is set; RepeatButtonScroll adds this * button is first clicked the increment is set; RepeatButtonScroll adds this
@@ -49,6 +60,11 @@ public:
virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, virtual void ThumbMoved(nsScrollbarFrame* aScrollbar,
nscoord aOldPos, nscoord aOldPos,
nscoord aNewPos) = 0; 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; virtual void VisibilityChanged(bool aVisible) = 0;
/** /**

View File

@@ -326,8 +326,10 @@ nsListBoxBodyFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState)
///////////// nsIScrollbarMediator /////////////// ///////////// nsIScrollbarMediator ///////////////
void 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); MOZ_ASSERT(aScrollbar != nullptr);
aScrollbar->SetIncrementToPage(aDirection); aScrollbar->SetIncrementToPage(aDirection);
nsWeakFrame weakFrame(this); nsWeakFrame weakFrame(this);
@@ -339,8 +341,10 @@ nsListBoxBodyFrame::ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirectio
} }
void 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); MOZ_ASSERT(aScrollbar != nullptr);
aScrollbar->SetIncrementToWhole(aDirection); aScrollbar->SetIncrementToWhole(aDirection);
nsWeakFrame weakFrame(this); nsWeakFrame weakFrame(this);
@@ -352,8 +356,10 @@ nsListBoxBodyFrame::ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirecti
} }
void 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); MOZ_ASSERT(aScrollbar != nullptr);
aScrollbar->SetIncrementToLine(aDirection); aScrollbar->SetIncrementToLine(aDirection);
nsWeakFrame weakFrame(this); nsWeakFrame weakFrame(this);

View File

@@ -54,13 +54,20 @@ public:
virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) MOZ_OVERRIDE; virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) MOZ_OVERRIDE;
// nsIScrollbarMediator // nsIScrollbarMediator
virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; nsIScrollbarMediator::ScrollSnapMode snapMode
virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; = 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 RepeatButtonScroll(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE;
virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, virtual void ThumbMoved(nsScrollbarFrame* aScrollbar,
int32_t aOldPos, int32_t aOldPos,
int32_t aNewPos) MOZ_OVERRIDE; int32_t aNewPos) MOZ_OVERRIDE;
virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE {}
virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE; virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE;
virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE; virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE;
virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE {} virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE {}

View File

@@ -141,19 +141,19 @@ nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext,
case 0: case 0:
sb->SetIncrementToLine(direction); sb->SetIncrementToLine(direction);
if (m) { if (m) {
m->ScrollByLine(sb, direction); m->ScrollByLine(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
} }
break; break;
case 1: case 1:
sb->SetIncrementToPage(direction); sb->SetIncrementToPage(direction);
if (m) { if (m) {
m->ScrollByPage(sb, direction); m->ScrollByPage(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
} }
break; break;
case 2: case 2:
sb->SetIncrementToWhole(direction); sb->SetIncrementToWhole(direction);
if (m) { if (m) {
m->ScrollByWhole(sb, direction); m->ScrollByWhole(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
} }
break; break;
case 3: case 3:
@@ -187,6 +187,15 @@ nsScrollbarButtonFrame::HandleRelease(nsPresContext* aPresContext,
// we're not active anymore // we're not active anymore
mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true); mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true);
StopRepeat(); 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; return NS_OK;
} }

View File

@@ -264,7 +264,8 @@ nsSliderFrame::AttributeChanged(int32_t aNameSpaceID,
nsIScrollbarMediator* mediator = scrollbarFrame->GetScrollbarMediator(); nsIScrollbarMediator* mediator = scrollbarFrame->GetScrollbarMediator();
scrollbarFrame->SetIncrementToWhole(direction); scrollbarFrame->SetIncrementToWhole(direction);
if (mediator) { if (mediator) {
mediator->ScrollByWhole(scrollbarFrame, direction); mediator->ScrollByWhole(scrollbarFrame, direction,
nsIScrollbarMediator::ENABLE_SNAP);
} }
} }
// 'this' might be destroyed here // 'this' might be destroyed here
@@ -1153,6 +1154,14 @@ nsSliderFrame::HandleRelease(nsPresContext* aPresContext,
{ {
StopRepeat(); StopRepeat();
nsIFrame* scrollbar = GetScrollbar();
nsScrollbarFrame* sb = do_QueryFrame(scrollbar);
if (sb) {
nsIScrollbarMediator* m = sb->GetScrollbarMediator();
if (m) {
m->ScrollbarReleased(sb);
}
}
return NS_OK; return NS_OK;
} }
@@ -1261,7 +1270,7 @@ nsSliderFrame::PageScroll(nscoord aChange)
nsIScrollbarMediator* m = sb->GetScrollbarMediator(); nsIScrollbarMediator* m = sb->GetScrollbarMediator();
sb->SetIncrementToPage(aChange); sb->SetIncrementToPage(aChange);
if (m) { if (m) {
m->ScrollByPage(sb, aChange); m->ScrollByPage(sb, aChange, nsIScrollbarMediator::ENABLE_SNAP);
return; return;
} }
} }

View File

@@ -4200,23 +4200,29 @@ nsTreeBodyFrame::ScrollHorzInternal(const ScrollParts& aParts, int32_t aPosition
} }
void 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); MOZ_ASSERT(aScrollbar != nullptr);
ScrollByPages(aDirection); ScrollByPages(aDirection);
} }
void 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); MOZ_ASSERT(aScrollbar != nullptr);
int32_t newIndex = aDirection < 0 ? 0 : mTopRowIndex; int32_t newIndex = aDirection < 0 ? 0 : mTopRowIndex;
ScrollToRow(newIndex); ScrollToRow(newIndex);
} }
void 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); MOZ_ASSERT(aScrollbar != nullptr);
ScrollByLines(aDirection); ScrollByLines(aDirection);
} }

View File

@@ -133,13 +133,20 @@ public:
virtual bool PseudoMatches(nsCSSSelector* aSelector) MOZ_OVERRIDE; virtual bool PseudoMatches(nsCSSSelector* aSelector) MOZ_OVERRIDE;
// nsIScrollbarMediator // nsIScrollbarMediator
virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; nsIScrollbarMediator::ScrollSnapMode aSnap
virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection) MOZ_OVERRIDE; = 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 RepeatButtonScroll(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE;
virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, virtual void ThumbMoved(nsScrollbarFrame* aScrollbar,
nscoord aOldPos, nscoord aOldPos,
nscoord aNewPos) MOZ_OVERRIDE; nscoord aNewPos) MOZ_OVERRIDE;
virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) MOZ_OVERRIDE {}
virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE { Invalidate(); } virtual void VisibilityChanged(bool aVisible) MOZ_OVERRIDE { Invalidate(); }
virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE { virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
ScrollParts parts = GetScrollParts(); ScrollParts parts = GetScrollParts();