Bug 961280 - Prevent the APZ repaint request from clobbering a layout-driven async scroll. r=tn

This commit is contained in:
Kartikaya Gupta 2014-01-28 17:54:59 -05:00
parent b60f2a333a
commit 49a38a6b30
3 changed files with 17 additions and 2 deletions

View File

@ -270,6 +270,7 @@ public:
bool IsLTR() const; bool IsLTR() const;
bool IsScrollbarOnRight() const; bool IsScrollbarOnRight() const;
bool IsScrollingActive() const { return mScrollingActive || mShouldBuildScrollableLayer; } bool IsScrollingActive() const { return mScrollingActive || mShouldBuildScrollableLayer; }
bool IsProcessingAsyncScroll() const { return mAsyncScroll != nullptr; }
void ResetScrollPositionForLayerPixelAlignment() void ResetScrollPositionForLayerPixelAlignment()
{ {
mScrollPosForLayerPixelAlignment = GetScrollPosition(); mScrollPosForLayerPixelAlignment = GetScrollPosition();
@ -636,6 +637,9 @@ public:
virtual bool IsScrollingActive() MOZ_OVERRIDE { virtual bool IsScrollingActive() MOZ_OVERRIDE {
return mHelper.IsScrollingActive(); return mHelper.IsScrollingActive();
} }
virtual bool IsProcessingAsyncScroll() MOZ_OVERRIDE {
return mHelper.IsProcessingAsyncScroll();
}
virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE { virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE {
mHelper.ResetScrollPositionForLayerPixelAlignment(); mHelper.ResetScrollPositionForLayerPixelAlignment();
} }
@ -934,6 +938,9 @@ public:
virtual bool IsScrollingActive() MOZ_OVERRIDE { virtual bool IsScrollingActive() MOZ_OVERRIDE {
return mHelper.IsScrollingActive(); return mHelper.IsScrollingActive();
} }
virtual bool IsProcessingAsyncScroll() MOZ_OVERRIDE {
return mHelper.IsProcessingAsyncScroll();
}
virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE { virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE {
mHelper.ResetScrollPositionForLayerPixelAlignment(); mHelper.ResetScrollPositionForLayerPixelAlignment();
} }

View File

@ -250,6 +250,11 @@ public:
* expectation that scrolling is going to happen. * expectation that scrolling is going to happen.
*/ */
virtual bool IsScrollingActive() = 0; virtual bool IsScrollingActive() = 0;
/**
* Returns true if the scrollframe is currently processing an async
* or smooth scroll.
*/
virtual bool IsProcessingAsyncScroll() = 0;
/** /**
* Call this when the layer(s) induced by active scrolling are being * Call this when the layer(s) induced by active scrolling are being
* completely redrawn. * completely redrawn.

View File

@ -92,7 +92,9 @@ ScrollFrameTo(nsIScrollableFrame* aFrame, const CSSPoint& aPoint)
return CSSPoint(); return CSSPoint();
} }
// If the scrollable frame got a scroll request from something other than us // If the scrollable frame is currently in the middle of an async or smooth
// scroll then we don't want to interrupt it (see bug 961280).
// Also if the scrollable frame got a scroll request from something other than us
// since the last layers update, then we don't want to push our scroll request // since the last layers update, then we don't want to push our scroll request
// because we'll clobber that one, which is bad. // because we'll clobber that one, which is bad.
// Note that content may have just finished sending a layers update with a scroll // Note that content may have just finished sending a layers update with a scroll
@ -101,7 +103,8 @@ ScrollFrameTo(nsIScrollableFrame* aFrame, const CSSPoint& aPoint)
// scroll offset. This is unavoidable because of the async communication between // scroll offset. This is unavoidable because of the async communication between
// APZ and content; however the code in NotifyLayersUpdated should reissue a new // APZ and content; however the code in NotifyLayersUpdated should reissue a new
// repaint request to bring everything back into sync. // repaint request to bring everything back into sync.
if (!aFrame->OriginOfLastScroll() || aFrame->OriginOfLastScroll() == nsGkAtoms::apz) { if (!aFrame->IsProcessingAsyncScroll() &&
(!aFrame->OriginOfLastScroll() || aFrame->OriginOfLastScroll() == nsGkAtoms::apz)) {
aFrame->ScrollToCSSPixelsApproximate(aPoint, nsGkAtoms::apz); aFrame->ScrollToCSSPixelsApproximate(aPoint, nsGkAtoms::apz);
} }
// Return the final scroll position after setting it so that anything that relies // Return the final scroll position after setting it so that anything that relies