summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/mac/ScrollAnimatorMac.mm')
-rw-r--r--Source/WebCore/platform/mac/ScrollAnimatorMac.mm161
1 files changed, 116 insertions, 45 deletions
diff --git a/Source/WebCore/platform/mac/ScrollAnimatorMac.mm b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
index 67c0904..5725880 100644
--- a/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
+++ b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
@@ -141,7 +141,7 @@ static NSSize abs(NSSize size)
@end
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
@interface ScrollbarPainterControllerDelegate : NSObject
{
@@ -240,6 +240,13 @@ static NSSize abs(NSSize size)
verticalScrollbar->controlSize(),
false);
macTheme->setNewPainterForScrollbar(verticalScrollbar, newVerticalPainter);
+ wkSetPainterForPainterController(painterController, newVerticalPainter, false);
+
+ // The different scrollbar styles have different thicknesses, so we must re-set the
+ // frameRect to the new thickness, and the re-layout below will ensure the position
+ // and length are properly updated.
+ int thickness = macTheme->scrollbarThickness(verticalScrollbar->controlSize());
+ verticalScrollbar->setFrameRect(WebCore::IntRect(0, 0, thickness, thickness));
}
WKScrollbarPainterRef oldHorizontalPainter = wkHorizontalScrollbarPainterForController(painterController);
@@ -250,9 +257,19 @@ static NSSize abs(NSSize size)
horizontalScrollbar->controlSize(),
true);
macTheme->setNewPainterForScrollbar(horizontalScrollbar, newHorizontalPainter);
+ wkSetPainterForPainterController(painterController, newHorizontalPainter, true);
+
+ // The different scrollbar styles have different thicknesses, so we must re-set the
+ // frameRect to the new thickness, and the re-layout below will ensure the position
+ // and length are properly updated.
+ int thickness = macTheme->scrollbarThickness(horizontalScrollbar->controlSize());
+ horizontalScrollbar->setFrameRect(WebCore::IntRect(0, 0, thickness, thickness));
}
wkSetScrollbarPainterControllerStyle(painterController, newRecommendedScrollerStyle);
+
+ // The different scrollbar styles affect layout, so we must re-layout everything.
+ _animator->scrollableArea()->scrollbarStyleChanged();
}
@end
@@ -329,6 +346,7 @@ static NSSize abs(NSSize size)
RetainPtr<ScrollbarPartAnimation> _horizontalTrackAnimation;
}
- (id)initWithScrollAnimator:(WebCore::ScrollAnimatorMac*)scrollAnimator;
+- (void)cancelAnimations;
@end
@implementation ScrollbarPainterDelegate
@@ -343,6 +361,14 @@ static NSSize abs(NSSize size)
return self;
}
+- (void)cancelAnimations
+{
+ [_verticalKnobAnimation.get() stopAnimation];
+ [_horizontalKnobAnimation.get() stopAnimation];
+ [_verticalTrackAnimation.get() stopAnimation];
+ [_horizontalTrackAnimation.get() stopAnimation];
+}
+
- (NSRect)convertRectToBacking:(NSRect)aRect
{
return aRect;
@@ -367,12 +393,29 @@ static NSSize abs(NSSize size)
- (void)setUpAnimation:(RetainPtr<ScrollbarPartAnimation>&)scrollbarPartAnimation scrollerPainter:(WKScrollbarPainterRef)scrollerPainter part:(WebCore::ScrollbarPart)part animateAlphaTo:(CGFloat)newAlpha duration:(NSTimeInterval)duration
{
+ // If the user has scrolled the page, then the scrollbars must be animated here.
+ // This overrides the early returns.
+ bool mustAnimate = _animator->haveScrolledSincePageLoad();
+
+ if (_animator->scrollbarPaintTimerIsActive() && !mustAnimate)
+ return;
+
+ if (_animator->scrollableArea()->shouldSuspendScrollAnimations() && !mustAnimate) {
+ _animator->startScrollbarPaintTimer();
+ return;
+ }
+
+ // At this point, we are definitely going to animate now, so stop the timer.
+ _animator->stopScrollbarPaintTimer();
+
// If we are currently animating, stop
if (scrollbarPartAnimation) {
[scrollbarPartAnimation.get() stopAnimation];
scrollbarPartAnimation = nil;
}
-
+
+ [NSAnimationContext beginGrouping];
+ [[NSAnimationContext currentContext] setDuration:duration];
scrollbarPartAnimation.adoptNS([[ScrollbarPartAnimation alloc] initWithScrollbarPainter:scrollerPainter
part:part
scrollAnimator:_animator
@@ -380,6 +423,7 @@ static NSSize abs(NSSize size)
duration:duration]);
[scrollbarPartAnimation.get() setAnimationBlockingMode:NSAnimationNonblocking];
[scrollbarPartAnimation.get() startAnimation];
+ [NSAnimationContext endGrouping];
}
- (void)scrollerImp:(id)scrollerImp animateKnobAlphaTo:(CGFloat)newKnobAlpha duration:(NSTimeInterval)duration
@@ -388,9 +432,6 @@ static NSSize abs(NSSize size)
return;
WKScrollbarPainterRef scrollerPainter = (WKScrollbarPainterRef)scrollerImp;
- if (newKnobAlpha == wkScrollbarPainterKnobAlpha(scrollerPainter))
- return;
-
if (wkScrollbarPainterIsHorizontal(scrollerPainter))
[self setUpAnimation:_horizontalKnobAnimation scrollerPainter:scrollerPainter part:WebCore::ThumbPart animateAlphaTo:newKnobAlpha duration:duration];
else
@@ -403,9 +444,6 @@ static NSSize abs(NSSize size)
return;
WKScrollbarPainterRef scrollerPainter = (WKScrollbarPainterRef)scrollerImp;
- if (newTrackAlpha == wkScrollbarPainterTrackAlpha(scrollerPainter))
- return;
-
if (wkScrollbarPainterIsHorizontal(scrollerPainter))
[self setUpAnimation:_horizontalTrackAnimation scrollerPainter:scrollerPainter part:WebCore::BackTrackPart animateAlphaTo:newTrackAlpha duration:duration];
else
@@ -414,20 +452,8 @@ static NSSize abs(NSSize size)
- (void)scrollerImp:(id)scrollerImp overlayScrollerStateChangedTo:(NSUInteger)newOverlayScrollerState
{
- if (!_animator)
- return;
-
- WKScrollbarPainterRef scrollbarPainter = (WKScrollbarPainterRef)scrollerImp;
- wkScrollbarPainterSetOverlayState(scrollbarPainter, newOverlayScrollerState);
-
- if (wkScrollbarPainterIsHorizontal(scrollbarPainter)) {
- WebCore::Scrollbar* horizontalScrollbar = _animator->scrollableArea()->horizontalScrollbar();
- _animator->scrollableArea()->invalidateScrollbarRect(horizontalScrollbar, WebCore::IntRect(0, 0, horizontalScrollbar->width(), horizontalScrollbar->height()));
- } else {
- WebCore::Scrollbar* verticalScrollbar = _animator->scrollableArea()->verticalScrollbar();
- _animator->scrollableArea()->invalidateScrollbarRect(verticalScrollbar, WebCore::IntRect(0, 0, verticalScrollbar->width(), verticalScrollbar->height()));
-
- }
+ UNUSED_PARAM(scrollerImp);
+ UNUSED_PARAM(newOverlayScrollerState);
}
- (void)scrollAnimatorDestroyed
@@ -440,7 +466,8 @@ static NSSize abs(NSSize size)
}
@end
-#endif // #if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+
+#endif // USE(WK_SCROLLBAR_PAINTER)
namespace WebCore {
@@ -451,6 +478,9 @@ PassOwnPtr<ScrollAnimator> ScrollAnimator::create(ScrollableArea* scrollableArea
ScrollAnimatorMac::ScrollAnimatorMac(ScrollableArea* scrollableArea)
: ScrollAnimator(scrollableArea)
+#if USE(WK_SCROLLBAR_PAINTER)
+ , m_initialScrollbarPaintTimer(this, &ScrollAnimatorMac::initialScrollbarPaintTimerFired)
+#endif
#if ENABLE(RUBBER_BANDING)
, m_inScrollGesture(false)
, m_momentumScrollInProgress(false)
@@ -460,11 +490,12 @@ ScrollAnimatorMac::ScrollAnimatorMac(ScrollableArea* scrollableArea)
, m_snapRubberBandTimer(this, &ScrollAnimatorMac::snapRubberBandTimerFired)
#endif
, m_drawingIntoLayer(false)
+ , m_haveScrolledSincePageLoad(false)
{
m_scrollAnimationHelperDelegate.adoptNS([[ScrollAnimationHelperDelegate alloc] initWithScrollAnimator:this]);
m_scrollAnimationHelper.adoptNS([[NSClassFromString(@"NSScrollAnimationHelper") alloc] initWithDelegate:m_scrollAnimationHelperDelegate.get()]);
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
m_scrollbarPainterControllerDelegate.adoptNS([[ScrollbarPainterControllerDelegate alloc] initWithScrollAnimator:this]);
m_scrollbarPainterController = wkMakeScrollbarPainterController(m_scrollbarPainterControllerDelegate.get());
m_scrollbarPainterDelegate.adoptNS([[ScrollbarPainterDelegate alloc] initWithScrollAnimator:this]);
@@ -473,7 +504,7 @@ ScrollAnimatorMac::ScrollAnimatorMac(ScrollableArea* scrollableArea)
ScrollAnimatorMac::~ScrollAnimatorMac()
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
[m_scrollbarPainterControllerDelegate.get() scrollAnimatorDestroyed];
[(id)m_scrollbarPainterController.get() setDelegate:nil];
[m_scrollbarPainterDelegate.get() scrollAnimatorDestroyed];
@@ -483,6 +514,8 @@ ScrollAnimatorMac::~ScrollAnimatorMac()
bool ScrollAnimatorMac::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier)
{
+ m_haveScrolledSincePageLoad = true;
+
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"AppleScrollAnimationEnabled"])
return ScrollAnimator::scroll(orientation, granularity, step, multiplier);
@@ -561,7 +594,7 @@ void ScrollAnimatorMac::immediateScrollByDeltaY(float deltaY)
void ScrollAnimatorMac::notityPositionChanged()
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
wkContentAreaScrolled(m_scrollbarPainterController.get());
#endif
ScrollAnimator::notityPositionChanged();
@@ -569,70 +602,70 @@ void ScrollAnimatorMac::notityPositionChanged()
void ScrollAnimatorMac::contentAreaWillPaint() const
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
wkContentAreaWillPaint(m_scrollbarPainterController.get());
#endif
}
void ScrollAnimatorMac::mouseEnteredContentArea() const
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
wkMouseEnteredContentArea(m_scrollbarPainterController.get());
#endif
}
void ScrollAnimatorMac::mouseExitedContentArea() const
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
wkMouseExitedContentArea(m_scrollbarPainterController.get());
#endif
}
void ScrollAnimatorMac::mouseMovedInContentArea() const
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
wkMouseMovedInContentArea(m_scrollbarPainterController.get());
#endif
}
void ScrollAnimatorMac::willStartLiveResize()
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
wkWillStartLiveResize(m_scrollbarPainterController.get());
#endif
}
void ScrollAnimatorMac::contentsResized() const
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
wkContentAreaResized(m_scrollbarPainterController.get());
#endif
}
void ScrollAnimatorMac::willEndLiveResize()
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
wkWillEndLiveResize(m_scrollbarPainterController.get());
#endif
}
void ScrollAnimatorMac::contentAreaDidShow() const
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
wkContentAreaDidShow(m_scrollbarPainterController.get());
#endif
}
void ScrollAnimatorMac::contentAreaDidHide() const
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
wkContentAreaDidHide(m_scrollbarPainterController.get());
#endif
}
void ScrollAnimatorMac::didAddVerticalScrollbar(Scrollbar* scrollbar)
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
WKScrollbarPainterRef painter = static_cast<WebCore::ScrollbarThemeMac*>(WebCore::ScrollbarTheme::nativeTheme())->painterForScrollbar(scrollbar);
wkScrollbarPainterSetDelegate(painter, m_scrollbarPainterDelegate.get());
wkSetPainterForPainterController(m_scrollbarPainterController.get(), painter, false);
@@ -645,7 +678,7 @@ void ScrollAnimatorMac::didAddVerticalScrollbar(Scrollbar* scrollbar)
void ScrollAnimatorMac::willRemoveVerticalScrollbar(Scrollbar* scrollbar)
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
WKScrollbarPainterRef painter = static_cast<WebCore::ScrollbarThemeMac*>(WebCore::ScrollbarTheme::nativeTheme())->painterForScrollbar(scrollbar);
wkScrollbarPainterSetDelegate(painter, nil);
wkSetPainterForPainterController(m_scrollbarPainterController.get(), nil, false);
@@ -656,7 +689,7 @@ void ScrollAnimatorMac::willRemoveVerticalScrollbar(Scrollbar* scrollbar)
void ScrollAnimatorMac::didAddHorizontalScrollbar(Scrollbar* scrollbar)
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
WKScrollbarPainterRef painter = static_cast<WebCore::ScrollbarThemeMac*>(WebCore::ScrollbarTheme::nativeTheme())->painterForScrollbar(scrollbar);
wkScrollbarPainterSetDelegate(painter, m_scrollbarPainterDelegate.get());
wkSetPainterForPainterController(m_scrollbarPainterController.get(), painter, true);
@@ -669,7 +702,7 @@ void ScrollAnimatorMac::didAddHorizontalScrollbar(Scrollbar* scrollbar)
void ScrollAnimatorMac::willRemoveHorizontalScrollbar(Scrollbar* scrollbar)
{
-#if defined(USE_WK_SCROLLBAR_PAINTER_AND_CONTROLLER)
+#if USE(WK_SCROLLBAR_PAINTER)
WKScrollbarPainterRef painter = static_cast<WebCore::ScrollbarThemeMac*>(WebCore::ScrollbarTheme::nativeTheme())->painterForScrollbar(scrollbar);
wkScrollbarPainterSetDelegate(painter, nil);
wkSetPainterForPainterController(m_scrollbarPainterController.get(), nil, true);
@@ -678,6 +711,17 @@ void ScrollAnimatorMac::willRemoveHorizontalScrollbar(Scrollbar* scrollbar)
#endif
}
+void ScrollAnimatorMac::cancelAnimations()
+{
+ m_haveScrolledSincePageLoad = false;
+
+#if USE(WK_SCROLLBAR_PAINTER)
+ if (scrollbarPaintTimerIsActive())
+ stopScrollbarPaintTimer();
+ [m_scrollbarPainterDelegate.get() cancelAnimations];
+#endif
+}
+
#if ENABLE(RUBBER_BANDING)
static const float scrollVelocityZeroingTimeout = 0.10f;
@@ -720,6 +764,8 @@ static float scrollWheelMultiplier()
void ScrollAnimatorMac::handleWheelEvent(PlatformWheelEvent& wheelEvent)
{
+ m_haveScrolledSincePageLoad = true;
+
if (!wheelEvent.hasPreciseScrollingDeltas()) {
ScrollAnimator::handleWheelEvent(wheelEvent);
return;
@@ -751,18 +797,18 @@ bool ScrollAnimatorMac::pinnedInDirection(float deltaX, float deltaY)
if (fabsf(deltaY) >= fabsf(deltaX)) {
if (deltaY < 0) {
// We are trying to scroll up. Make sure we are not pinned to the top
- limitDelta.setHeight(m_scrollableArea->visibleContentRect().y());
+ limitDelta.setHeight(m_scrollableArea->visibleContentRect().y() + + m_scrollableArea->scrollOrigin().y());
} else {
// We are trying to scroll down. Make sure we are not pinned to the bottom
- limitDelta.setHeight(m_scrollableArea->contentsSize().height() - m_scrollableArea->visibleContentRect().maxY());
+ limitDelta.setHeight(m_scrollableArea->contentsSize().height() - (m_scrollableArea->visibleContentRect().maxY() + m_scrollableArea->scrollOrigin().y()));
}
} else if (deltaX != 0) {
if (deltaX < 0) {
// We are trying to scroll left. Make sure we are not pinned to the left
- limitDelta.setWidth(m_scrollableArea->visibleContentRect().x());
+ limitDelta.setWidth(m_scrollableArea->visibleContentRect().x() + m_scrollableArea->scrollOrigin().x());
} else {
// We are trying to scroll right. Make sure we are not pinned to the right
- limitDelta.setWidth(m_scrollableArea->contentsSize().width() - m_scrollableArea->visibleContentRect().maxX());
+ limitDelta.setWidth(m_scrollableArea->contentsSize().width() - (m_scrollableArea->visibleContentRect().maxX() + m_scrollableArea->scrollOrigin().x()));
}
}
@@ -793,6 +839,8 @@ bool ScrollAnimatorMac::allowsHorizontalStretching() const
void ScrollAnimatorMac::smoothScrollWithEvent(PlatformWheelEvent& wheelEvent)
{
+ m_haveScrolledSincePageLoad = true;
+
float deltaX = m_overflowScrollDelta.width();
float deltaY = m_overflowScrollDelta.height();
@@ -925,7 +973,7 @@ void ScrollAnimatorMac::smoothScrollWithEvent(PlatformWheelEvent& wheelEvent)
m_stretchScrollForce.setHeight(m_stretchScrollForce.height() + deltaY);
FloatSize dampedDelta(ceilf(elasticDeltaForReboundDelta(m_stretchScrollForce.width())), ceilf(elasticDeltaForReboundDelta(m_stretchScrollForce.height())));
- FloatPoint origOrigin = m_scrollableArea->visibleContentRect().location() - stretchAmount;
+ FloatPoint origOrigin = (m_scrollableArea->visibleContentRect().location() + m_scrollableArea->scrollOrigin()) - stretchAmount;
FloatPoint newOrigin = origOrigin + dampedDelta;
if (origOrigin != newOrigin) {
@@ -945,6 +993,7 @@ void ScrollAnimatorMac::smoothScrollWithEvent(PlatformWheelEvent& wheelEvent)
void ScrollAnimatorMac::beginScrollGesture()
{
+ m_haveScrolledSincePageLoad = true;
m_inScrollGesture = true;
m_momentumScrollInProgress = false;
m_ignoreMomentumScrolls = false;
@@ -1017,7 +1066,7 @@ void ScrollAnimatorMac::snapRubberBandTimerFired(Timer<ScrollAnimatorMac>*)
return;
}
- m_origOrigin = m_scrollableArea->visibleContentRect().location() - m_startStretch;
+ m_origOrigin = (m_scrollableArea->visibleContentRect().location() + m_scrollableArea->scrollOrigin()) - m_startStretch;
m_origVelocity = m_momentumVelocity;
// Just like normal scrolling, prefer vertical rubberbanding
@@ -1069,6 +1118,28 @@ void ScrollAnimatorMac::snapRubberBandTimerFired(Timer<ScrollAnimatorMac>*)
}
#endif
+#if USE(WK_SCROLLBAR_PAINTER)
+void ScrollAnimatorMac::startScrollbarPaintTimer()
+{
+ m_initialScrollbarPaintTimer.startOneShot(0.1);
+}
+
+bool ScrollAnimatorMac::scrollbarPaintTimerIsActive() const
+{
+ return m_initialScrollbarPaintTimer.isActive();
+}
+
+void ScrollAnimatorMac::stopScrollbarPaintTimer()
+{
+ m_initialScrollbarPaintTimer.stop();
+}
+
+void ScrollAnimatorMac::initialScrollbarPaintTimerFired(Timer<ScrollAnimatorMac>*)
+{
+ wkScrollbarPainterForceFlashScrollers(m_scrollbarPainterController.get());
+}
+#endif
+
} // namespace WebCore
#endif // ENABLE(SMOOTH_SCROLLING)