Bug 945584: Part 3 - Enable cancellation of OSX synthesized mousewheel scrolling events (v2 Patch),r=roc

- Mouse wheel events synthesized by OSX for momentum scrolling can now
  be interrupted by DOM triggered and CSS scroll snapping triggered scroll
  events for consistent behavior with the scrolling and fling gestures
  in the APZC.

--HG--
extra : rebase_source : 261d1f1b03bb29f722d04e0c48b0212d1c69cd1b
This commit is contained in:
Kearwood (Kip) Gilbert 2014-02-04 14:54:22 +13:00
Родитель 2d11a5911a
Коммит 5ded4eb336
5 изменённых файлов: 55 добавлений и 18 удалений

Просмотреть файл

@ -2476,10 +2476,14 @@ EventStateManager::DoScrollText(nsIScrollableFrame* aScrollableFrame,
MOZ_CRASH("Invalid scrollType value comes");
}
nsIScrollableFrame::ScrollMomentum momentum =
aEvent->isMomentum ? nsIScrollableFrame::SYNTHESIZED_MOMENTUM_EVENT
: nsIScrollableFrame::NOT_MOMENTUM;
nsIntPoint overflow;
aScrollableFrame->ScrollBy(actualDevPixelScrollAmount,
nsIScrollableFrame::DEVICE_PIXELS,
mode, &overflow, origin, aEvent->isMomentum);
mode, &overflow, origin, momentum);
if (!scrollFrameWeak.IsAlive()) {
// If the scroll causes changing the layout, we can think that the event

Просмотреть файл

@ -2390,7 +2390,9 @@ PresShell::ScrollPage(bool aForward)
if (scrollFrame) {
scrollFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1),
nsIScrollableFrame::PAGES,
nsIScrollableFrame::SMOOTH);
nsIScrollableFrame::SMOOTH,
nullptr, nullptr,
nsIScrollableFrame::NOT_MOMENTUM);
}
return NS_OK;
}
@ -2405,7 +2407,9 @@ PresShell::ScrollLine(bool aForward)
NS_DEFAULT_VERTICAL_SCROLL_DISTANCE);
scrollFrame->ScrollBy(nsIntPoint(0, aForward ? lineCount : -lineCount),
nsIScrollableFrame::LINES,
nsIScrollableFrame::SMOOTH);
nsIScrollableFrame::SMOOTH,
nullptr, nullptr,
nsIScrollableFrame::NOT_MOMENTUM);
}
return NS_OK;
}
@ -2420,7 +2424,9 @@ PresShell::ScrollCharacter(bool aRight)
NS_DEFAULT_HORIZONTAL_SCROLL_DISTANCE);
scrollFrame->ScrollBy(nsIntPoint(aRight ? h : -h, 0),
nsIScrollableFrame::LINES,
nsIScrollableFrame::SMOOTH);
nsIScrollableFrame::SMOOTH,
nullptr, nullptr,
nsIScrollableFrame::NOT_MOMENTUM);
}
return NS_OK;
}
@ -2433,7 +2439,9 @@ PresShell::CompleteScroll(bool aForward)
if (scrollFrame) {
scrollFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1),
nsIScrollableFrame::WHOLE,
nsIScrollableFrame::SMOOTH);
nsIScrollableFrame::SMOOTH,
nullptr, nullptr,
nsIScrollableFrame::NOT_MOMENTUM);
}
return NS_OK;
}

Просмотреть файл

@ -1896,6 +1896,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter,
, mShouldBuildScrollableLayer(false)
, mHasBeenScrolled(false)
, mIsResolutionSet(false)
, mIgnoreMomentumScroll(false)
, mScaleToResolution(false)
, mTransformingByAPZ(false)
{
@ -2091,6 +2092,7 @@ ScrollFrameHelper::ScrollToWithOrigin(nsPoint aScrollPosition,
if (gfxPrefs::ScrollBehaviorEnabled()) {
if (aMode == nsIScrollableFrame::SMOOTH_MSD) {
mIgnoreMomentumScroll = true;
if (!mAsyncSmoothMSDScroll) {
if (mAsyncScroll) {
if (mAsyncScroll->mIsSmoothScroll) {
@ -3321,18 +3323,25 @@ CalcRangeForScrollBy(int32_t aDelta, nscoord aPos,
void
ScrollFrameHelper::ScrollBy(nsIntPoint aDelta,
nsIScrollableFrame::ScrollUnit aUnit,
nsIScrollableFrame::ScrollMode aMode,
nsIntPoint* aOverflow,
nsIAtom *aOrigin,
bool aIsMomentum)
nsIScrollableFrame::ScrollUnit aUnit,
nsIScrollableFrame::ScrollMode aMode,
nsIntPoint* aOverflow,
nsIAtom *aOrigin,
nsIScrollableFrame::ScrollMomentum aMomentum)
{
// 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
// scroll animations, enabling Javascript that depends on them to be responsive
// without forcing the user to wait for the fling animations to completely stop.
if (aIsMomentum && IsProcessingAsyncScroll()) {
return;
switch (aMomentum) {
case nsIScrollableFrame::NOT_MOMENTUM:
mIgnoreMomentumScroll = false;
break;
case nsIScrollableFrame::SYNTHESIZED_MOMENTUM_EVENT:
if (mIgnoreMomentumScroll) {
return;
}
break;
}
if (mAsyncSmoothMSDScroll != nullptr) {

Просмотреть файл

@ -221,7 +221,8 @@ public:
*/
void ScrollBy(nsIntPoint aDelta, nsIScrollableFrame::ScrollUnit aUnit,
nsIScrollableFrame::ScrollMode aMode, nsIntPoint* aOverflow,
nsIAtom* aOrigin = nullptr, bool aIsMomentum = false);
nsIAtom* aOrigin = nullptr,
nsIScrollableFrame::ScrollMomentum aMomentum = nsIScrollableFrame::NOT_MOMENTUM);
/**
* @note This method might destroy the frame, pres shell and other objects.
*/
@ -479,6 +480,10 @@ public:
// SetResolutionAndScaleTo or restored via RestoreState.
bool mIsResolutionSet:1;
// True if the events synthesized by OSX to produce momentum scrolling should
// be ignored. Reset when the next real, non-synthesized scroll event occurs.
bool mIgnoreMomentumScroll:1;
// True if the frame's resolution has been set via SetResolutionAndScaleTo.
// Only meaningful for root scroll frames.
bool mScaleToResolution:1;
@ -708,8 +713,9 @@ public:
*/
virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode,
nsIntPoint* aOverflow, nsIAtom* aOrigin = nullptr,
bool aIsMomentum = false) MOZ_OVERRIDE {
mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aIsMomentum);
nsIScrollableFrame::ScrollMomentum aMomentum = nsIScrollableFrame::NOT_MOMENTUM)
MOZ_OVERRIDE {
mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum);
}
/**
* @note This method might destroy the frame, pres shell and other objects.
@ -1076,8 +1082,9 @@ public:
*/
virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode,
nsIntPoint* aOverflow, nsIAtom* aOrigin = nullptr,
bool aIsMomentum = false) MOZ_OVERRIDE {
mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aIsMomentum);
nsIScrollableFrame::ScrollMomentum aMomentum = nsIScrollableFrame::NOT_MOMENTUM)
MOZ_OVERRIDE {
mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum);
}
/**
* @note This method might destroy the frame, pres shell and other objects.

Просмотреть файл

@ -198,6 +198,15 @@ public:
* first scrolling to the destination.
*/
enum ScrollMode { INSTANT, SMOOTH, SMOOTH_MSD, NORMAL };
/**
* Some platforms (OSX) may generate additional scrolling events even
* after the user has stopped scrolling, simulating a momentum scrolling
* effect resulting from fling gestures.
* SYNTHESIZED_MOMENTUM_EVENT indicates that the scrolling is being requested
* by such a synthesized event and may be ignored if another scroll has
* been started since the last actual user input.
*/
enum ScrollMomentum { NOT_MOMENTUM, SYNTHESIZED_MOMENTUM_EVENT };
/**
* @note This method might destroy the frame, pres shell and other objects.
* Clamps aScrollPosition to GetScrollRange and sets the scroll position
@ -262,7 +271,7 @@ public:
virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode,
nsIntPoint* aOverflow = nullptr,
nsIAtom* aOrigin = nullptr,
bool aIsMomentum = false) = 0;
ScrollMomentum aMomentum = NOT_MOMENTUM) = 0;
/**
* @note This method might destroy the frame, pres shell and other objects.
* This tells the scroll frame to try scrolling to the scroll