[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

weinig at apple.com weinig at apple.com
Sun Feb 20 23:29:04 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit 2a13aa81835058316269e98f58b6b06c8d1655b8
Author: weinig at apple.com <weinig at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Jan 20 23:14:47 2011 +0000

    Cleanup Scrollbar/ScrollbarClient relationship
    https://bugs.webkit.org/show_bug.cgi?id=52779
    
    Reviewed by Dave Hyatt.
    
    Source/WebCore:
    
    Pipe all scrolling through the ScrollbarClient/ScrollAnimator
    rather than through the Scrollbar. The Scrollbar now is just
    a "view" on the scroll position of the scrollable area it is
    attached to.
    
    There are now two ways to scroll a scrollable area:
    - ScrollbarClient::scroll()
    - ScrollbarClient::scrollToOffsetWithoutAnimation()
    
    Both of these go through the ScrollAnimator (updating its state
    or starting an animation). The ScrollAnimator, in turn, now calls
    ScrollbarClient::setScrollOffsetFromAnimation, which tells the
    Scrollbars to pull a new offset (via Scrollbar::offsetDidChange)
    and tells the class that derives from ScrollbarClient to scroll
    its contents (via ScrollbarClient::setScrollOffset).
    
    * WebCore.xcodeproj/project.pbxproj:
    Move Scrollbar.cpp to the right place.
    
    * accessibility/AccessibilityScrollbar.cpp:
    (WebCore::AccessibilityScrollbar::setValue):
    Initiate the scroll through the scrollbar client, rather than the
    scrollbar itself.
    
    * page/FrameView.cpp:
    (WebCore::FrameView::scrollTo):
    * page/FrameView.h:
    Condense the two valueChanged overrides to a single override of the
    scrollTo function.
    
    * platform/ScrollAnimator.cpp:
    (WebCore::ScrollAnimator::scroll):
    (WebCore::ScrollAnimator::scrollToOffsetWithoutAnimation):
    (WebCore::ScrollAnimator::currentPosition):
    (WebCore::ScrollAnimator::notityPositionChanged):
    * platform/ScrollAnimator.h:
    * platform/ScrollAnimatorWin.cpp:
    (WebCore::ScrollAnimatorWin::scrollToOffsetWithoutAnimation):
    (WebCore::ScrollAnimatorWin::animateScroll):
    * platform/ScrollAnimatorWin.h:
    * platform/mac/ScrollAnimatorMac.h:
    * platform/mac/ScrollAnimatorMac.mm:
    (WebCore::ScrollAnimatorMac::scrollToOffsetWithoutAnimation):
    (WebCore::ScrollAnimatorMac::immediateScrollToPoint):
    Change setScrollPositionAndStopAnimation to scrollToOffsetWithoutAnimation
    and bottleneck all client notification of changed position through a new
    notityPositionChanged() function.
    
    * platform/ScrollView.cpp:
    (WebCore::ScrollView::setScrollOffset):
    (WebCore::ScrollView::scrollTo):
    (WebCore::ScrollView::scrollPosition):
    (WebCore::ScrollView::scroll):
    (WebCore::ScrollView::updateScrollbars):
    (WebCore::ScrollView::wheelEvent):
    * platform/ScrollView.h:
    (WebCore::ScrollView::horizontalScrollbar):
    (WebCore::ScrollView::verticalScrollbar):
    Update to scroll via the ScrollbarClient rather than the Scrollbar.
    
    * platform/Scrollbar.cpp:
    (WebCore::Scrollbar::offsetDidChange):
    (WebCore::Scrollbar::autoscrollPressedPart):
    (WebCore::Scrollbar::moveThumb):
    (WebCore::Scrollbar::mouseMoved):
    * platform/Scrollbar.h:
    (WebCore::Scrollbar::setPressedPos):
    Change the scrollbar to only updates its offset in response to
    an offsetDidChange call.
    
    * platform/ScrollbarClient.cpp:
    (WebCore::ScrollbarClient::scroll):
    (WebCore::ScrollbarClient::scrollToOffsetWithoutAnimation):
    (WebCore::ScrollbarClient::scrollToXOffsetWithoutAnimation):
    (WebCore::ScrollbarClient::scrollToYOffsetWithoutAnimation):
    (WebCore::ScrollbarClient::setScrollOffsetFromAnimation):
    * platform/ScrollbarClient.h:
    (WebCore::ScrollbarClient::horizontalScrollbar):
    (WebCore::ScrollbarClient::verticalScrollbar):
    Make the increasingly misnamed ScrollbarClient responsible for
    scrolling.
    
    * platform/efl/ScrollbarEfl.cpp:
    (scrollbarEflEdjeMessage):
    * platform/gtk/MainFrameScrollbarGtk.cpp:
    (MainFrameScrollbarGtk::gtkValueChanged):
    * platform/qt/ScrollbarQt.cpp:
    (WebCore::Scrollbar::contextMenu):
    Update to move scrolling through the client.
    
    * platform/win/PopupMenuWin.cpp:
    (WebCore::PopupMenuWin::scrollToRevealSelection):
    (WebCore::PopupMenuWin::scrollPosition):
    (WebCore::PopupMenuWin::setScrollOffset):
    (WebCore::PopupMenuWin::scrollTo):
    (WebCore::PopupMenuWin::wndProc):
    * platform/win/PopupMenuWin.h:
    (WebCore::PopupMenuWin::verticalScrollbar):
    * rendering/RenderLayer.cpp:
    (WebCore::RenderLayer::scrollToOffset):
    (WebCore::RenderLayer::scrollTo):
    (WebCore::RenderLayer::setScrollOffset):
    (WebCore::RenderLayer::scrollPosition):
    (WebCore::RenderLayer::updateScrollInfoAfterLayout):
    (WebCore::RenderLayer::scroll):
    * rendering/RenderLayer.h:
    * rendering/RenderListBox.cpp:
    (WebCore::RenderListBox::scrollToRevealElementAtListIndex):
    (WebCore::RenderListBox::scroll):
    (WebCore::RenderListBox::logicalScroll):
    (WebCore::RenderListBox::scrollPosition):
    (WebCore::RenderListBox::setScrollOffset):
    (WebCore::RenderListBox::scrollTo):
    (WebCore::RenderListBox::setScrollTop):
    * rendering/RenderListBox.h:
    (WebCore::RenderListBox::verticalScrollbar):
    Update to scroll via the ScrollbarClient rather than the Scrollbar.
    
    * rendering/RenderMarquee.cpp:
    (WebCore::RenderMarquee::start):
    Simplify initial paint to just do an immediate scroll to the position.
    
    Source/WebKit/chromium:
    
    * src/WebScrollbarImpl.cpp:
    (WebKit::WebScrollbarImpl::WebScrollbarImpl):
    (WebKit::WebScrollbarImpl::value):
    (WebKit::WebScrollbarImpl::setValue):
    (WebKit::WebScrollbarImpl::scroll):
    (WebKit::WebScrollbarImpl::onMouseDown):
    (WebKit::WebScrollbarImpl::onMouseMove):
    (WebKit::WebScrollbarImpl::onMouseWheel):
    (WebKit::WebScrollbarImpl::onKeyDown):
    (WebKit::WebScrollbarImpl::scrollPosition):
    (WebKit::WebScrollbarImpl::setScrollOffset):
    * src/WebScrollbarImpl.h:
    
    Source/WebKit/qt:
    
    * Api/qwebframe.cpp:
    (QWebFrame::setScrollBarValue):
    
    Source/WebKit/win:
    
    * WebScrollBar.cpp:
    (WebScrollBar::WebScrollBar):
    (WebScrollBar::setValue):
    (WebScrollBar::value):
    (WebScrollBar::scroll):
    (WebScrollBar::scrollPosition):
    (WebScrollBar::setScrollOffset):
    * WebScrollBar.h:
    
    Source/WebKit2:
    
    * UIProcess/win/WebPopupMenuProxyWin.cpp:
    (WebKit::WebPopupMenuProxyWin::scrollPosition):
    (WebKit::WebPopupMenuProxyWin::setScrollOffset):
    (WebKit::WebPopupMenuProxyWin::scrollTo):
    (WebKit::WebPopupMenuProxyWin::onMouseWheel):
    (WebKit::WebPopupMenuProxyWin::scrollToRevealSelection):
    * UIProcess/win/WebPopupMenuProxyWin.h:
    (WebKit::WebPopupMenuProxyWin::verticalScrollbar):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76291 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 2a78d31..a8d9203 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,132 @@
+2011-01-20  Sam Weinig  <sam at webkit.org>
+
+        Reviewed by Dave Hyatt.
+
+        Cleanup Scrollbar/ScrollbarClient relationship
+        https://bugs.webkit.org/show_bug.cgi?id=52779
+
+        Pipe all scrolling through the ScrollbarClient/ScrollAnimator
+        rather than through the Scrollbar. The Scrollbar now is just
+        a "view" on the scroll position of the scrollable area it is
+        attached to.
+
+        There are now two ways to scroll a scrollable area:
+        - ScrollbarClient::scroll()
+        - ScrollbarClient::scrollToOffsetWithoutAnimation()
+
+        Both of these go through the ScrollAnimator (updating its state
+        or starting an animation). The ScrollAnimator, in turn, now calls
+        ScrollbarClient::setScrollOffsetFromAnimation, which tells the
+        Scrollbars to pull a new offset (via Scrollbar::offsetDidChange)
+        and tells the class that derives from ScrollbarClient to scroll
+        its contents (via ScrollbarClient::setScrollOffset).
+
+        * WebCore.xcodeproj/project.pbxproj:
+        Move Scrollbar.cpp to the right place.
+
+        * accessibility/AccessibilityScrollbar.cpp:
+        (WebCore::AccessibilityScrollbar::setValue):
+        Initiate the scroll through the scrollbar client, rather than the
+        scrollbar itself.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::scrollTo):
+        * page/FrameView.h:
+        Condense the two valueChanged overrides to a single override of the
+        scrollTo function.
+
+        * platform/ScrollAnimator.cpp:
+        (WebCore::ScrollAnimator::scroll):
+        (WebCore::ScrollAnimator::scrollToOffsetWithoutAnimation):
+        (WebCore::ScrollAnimator::currentPosition):
+        (WebCore::ScrollAnimator::notityPositionChanged):
+        * platform/ScrollAnimator.h:
+        * platform/ScrollAnimatorWin.cpp:
+        (WebCore::ScrollAnimatorWin::scrollToOffsetWithoutAnimation):
+        (WebCore::ScrollAnimatorWin::animateScroll):
+        * platform/ScrollAnimatorWin.h:
+        * platform/mac/ScrollAnimatorMac.h:
+        * platform/mac/ScrollAnimatorMac.mm:
+        (WebCore::ScrollAnimatorMac::scrollToOffsetWithoutAnimation):
+        (WebCore::ScrollAnimatorMac::immediateScrollToPoint):
+        Change setScrollPositionAndStopAnimation to scrollToOffsetWithoutAnimation
+        and bottleneck all client notification of changed position through a new
+        notityPositionChanged() function.
+
+        * platform/ScrollView.cpp:
+        (WebCore::ScrollView::setScrollOffset):
+        (WebCore::ScrollView::scrollTo):
+        (WebCore::ScrollView::scrollPosition):
+        (WebCore::ScrollView::scroll):
+        (WebCore::ScrollView::updateScrollbars):
+        (WebCore::ScrollView::wheelEvent):
+        * platform/ScrollView.h:
+        (WebCore::ScrollView::horizontalScrollbar):
+        (WebCore::ScrollView::verticalScrollbar):
+        Update to scroll via the ScrollbarClient rather than the Scrollbar.
+
+        * platform/Scrollbar.cpp:
+        (WebCore::Scrollbar::offsetDidChange):
+        (WebCore::Scrollbar::autoscrollPressedPart):
+        (WebCore::Scrollbar::moveThumb):
+        (WebCore::Scrollbar::mouseMoved):
+        * platform/Scrollbar.h:
+        (WebCore::Scrollbar::setPressedPos):
+        Change the scrollbar to only updates its offset in response to
+        an offsetDidChange call.
+
+        * platform/ScrollbarClient.cpp:
+        (WebCore::ScrollbarClient::scroll):
+        (WebCore::ScrollbarClient::scrollToOffsetWithoutAnimation):
+        (WebCore::ScrollbarClient::scrollToXOffsetWithoutAnimation):
+        (WebCore::ScrollbarClient::scrollToYOffsetWithoutAnimation):
+        (WebCore::ScrollbarClient::setScrollOffsetFromAnimation):
+        * platform/ScrollbarClient.h:
+        (WebCore::ScrollbarClient::horizontalScrollbar):
+        (WebCore::ScrollbarClient::verticalScrollbar):
+        Make the increasingly misnamed ScrollbarClient responsible for
+        scrolling.
+
+        * platform/efl/ScrollbarEfl.cpp:
+        (scrollbarEflEdjeMessage):
+        * platform/gtk/MainFrameScrollbarGtk.cpp:
+        (MainFrameScrollbarGtk::gtkValueChanged):
+        * platform/qt/ScrollbarQt.cpp:
+        (WebCore::Scrollbar::contextMenu):
+        Update to move scrolling through the client.
+
+        * platform/win/PopupMenuWin.cpp:
+        (WebCore::PopupMenuWin::scrollToRevealSelection):
+        (WebCore::PopupMenuWin::scrollPosition):
+        (WebCore::PopupMenuWin::setScrollOffset):
+        (WebCore::PopupMenuWin::scrollTo):
+        (WebCore::PopupMenuWin::wndProc):
+        * platform/win/PopupMenuWin.h:
+        (WebCore::PopupMenuWin::verticalScrollbar):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::scrollToOffset):
+        (WebCore::RenderLayer::scrollTo):
+        (WebCore::RenderLayer::setScrollOffset):
+        (WebCore::RenderLayer::scrollPosition):
+        (WebCore::RenderLayer::updateScrollInfoAfterLayout):
+        (WebCore::RenderLayer::scroll):
+        * rendering/RenderLayer.h:
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::scrollToRevealElementAtListIndex):
+        (WebCore::RenderListBox::scroll):
+        (WebCore::RenderListBox::logicalScroll):
+        (WebCore::RenderListBox::scrollPosition):
+        (WebCore::RenderListBox::setScrollOffset):
+        (WebCore::RenderListBox::scrollTo):
+        (WebCore::RenderListBox::setScrollTop):
+        * rendering/RenderListBox.h:
+        (WebCore::RenderListBox::verticalScrollbar):
+        Update to scroll via the ScrollbarClient rather than the Scrollbar.
+
+        * rendering/RenderMarquee.cpp:
+        (WebCore::RenderMarquee::start):
+        Simplify initial paint to just do an immediate scroll to the position.
+
 2011-01-20  Patrick Gansterer  <paroga at webkit.org>
 
         Unreviewed WinCE build fix for r76170.
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index d81d712..91e1188 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -11415,7 +11415,7 @@
 		BCA8CA5D11E4E6D100812FB7 /* BackForwardListImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackForwardListImpl.cpp; sourceTree = "<group>"; };
 		BCA8CA5E11E4E6D100812FB7 /* BackForwardListImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackForwardListImpl.h; sourceTree = "<group>"; };
 		BCA979161215D055005C485C /* ImageBufferData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferData.h; sourceTree = "<group>"; };
-		BCAA90C20A7EBA60008B1229 /* Scrollbar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Scrollbar.cpp; path = platform/Scrollbar.cpp; sourceTree = SOURCE_ROOT; };
+		BCAA90C20A7EBA60008B1229 /* Scrollbar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Scrollbar.cpp; sourceTree = "<group>"; };
 		BCACF3BA1072921A00C0C8A3 /* UserContentURLPattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserContentURLPattern.cpp; sourceTree = "<group>"; };
 		BCACF3BB1072921A00C0C8A3 /* UserContentURLPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserContentURLPattern.h; sourceTree = "<group>"; };
 		BCAE1FA512939DB7004CB026 /* ScrollAnimatorMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimatorMac.h; sourceTree = "<group>"; };
@@ -13890,7 +13890,6 @@
 				1CE24F960D7CAF0E007E04C2 /* SchedulePairMac.mm */,
 				BCAE1FA512939DB7004CB026 /* ScrollAnimatorMac.h */,
 				BC51156D12B1749C00C96754 /* ScrollAnimatorMac.mm */,
-				BCAA90C20A7EBA60008B1229 /* Scrollbar.cpp */,
 				BC8B853C0E7C7F1100AB6984 /* ScrollbarThemeMac.h */,
 				BCEF869E0E844E9D00A85CD5 /* ScrollbarThemeMac.mm */,
 				9353676A09AED88B00D35CD6 /* ScrollViewMac.mm */,
@@ -18278,6 +18277,7 @@
 				5162C7F311F77EFB00612EFE /* SchemeRegistry.h */,
 				CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */,
 				CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */,
+				BCAA90C20A7EBA60008B1229 /* Scrollbar.cpp */,
 				BC7B2AF80450824100A8000F /* Scrollbar.h */,
 				BC9BC64B0E7C4889008B9849 /* ScrollbarClient.cpp */,
 				BC9BC64C0E7C4889008B9849 /* ScrollbarClient.h */,
diff --git a/Source/WebCore/accessibility/AccessibilityScrollbar.cpp b/Source/WebCore/accessibility/AccessibilityScrollbar.cpp
index 865797a..b261a46 100644
--- a/Source/WebCore/accessibility/AccessibilityScrollbar.cpp
+++ b/Source/WebCore/accessibility/AccessibilityScrollbar.cpp
@@ -97,9 +97,11 @@ void AccessibilityScrollbar::setValue(float value)
     if (!m_scrollbar)
         return;
     
+    if (!m_scrollbar->client())
+        return;
+
     float newValue = value * m_scrollbar->maximum();
-    
-    m_scrollbar->setValue(newValue, Scrollbar::NotFromScrollAnimator);    
+    m_scrollbar->client()->scrollToOffsetWithoutAnimation(m_scrollbar->orientation(), newValue);
 }
     
 } // namespace WebCore
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
index 7132cb5..6cea443 100644
--- a/Source/WebCore/page/FrameView.cpp
+++ b/Source/WebCore/page/FrameView.cpp
@@ -1956,23 +1956,15 @@ bool FrameView::isActive() const
     return page && page->focusController()->isActive();
 }
 
-void FrameView::valueChanged(Scrollbar* bar)
+void FrameView::scrollTo(const IntSize& newOffset)
 {
-    // Figure out if we really moved.
     IntSize offset = scrollOffset();
-    ScrollView::valueChanged(bar);
+    ScrollView::scrollTo(newOffset);
     if (offset != scrollOffset())
         scrollPositionChanged();
     frame()->loader()->client()->didChangeScrollOffset();
 }
 
-void FrameView::valueChanged(const IntSize& scrollDelta)
-{
-    ScrollView::valueChanged(scrollDelta);
-    frame()->eventHandler()->sendScrollEvent();
-    frame()->loader()->client()->didChangeScrollOffset();
-}
-
 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
 {
     // Add in our offset within the FrameView.
diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h
index efe9769..174619d 100644
--- a/Source/WebCore/page/FrameView.h
+++ b/Source/WebCore/page/FrameView.h
@@ -295,12 +295,12 @@ private:
     virtual IntPoint convertFromContainingView(const IntPoint&) const;
 
     // ScrollBarClient interface
-    virtual void valueChanged(Scrollbar*);
-    virtual void valueChanged(const IntSize&);
     virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
     virtual bool isActive() const;
     virtual void getTickmarks(Vector<IntRect>&) const;
 
+    virtual void scrollTo(const IntSize&);
+
     void deferredRepaintTimerFired(Timer<FrameView>*);
     void doDeferredRepaints();
     void updateDeferredRepaintDelay();
diff --git a/Source/WebCore/platform/ScrollAnimator.cpp b/Source/WebCore/platform/ScrollAnimator.cpp
index 583e833..5873e88 100644
--- a/Source/WebCore/platform/ScrollAnimator.cpp
+++ b/Source/WebCore/platform/ScrollAnimator.cpp
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "ScrollAnimator.h"
 
+#include "FloatPoint.h"
 #include "ScrollbarClient.h"
 #include <algorithm>
 
@@ -61,16 +62,27 @@ bool ScrollAnimator::scroll(ScrollbarOrientation orientation, ScrollGranularity,
     if (*currentPos == newPos)
         return false;
     *currentPos = newPos;
-    m_client->setScrollOffsetFromAnimation(IntPoint(m_currentPosX, m_currentPosY));
+
+    notityPositionChanged();
+
     return true;
 }
 
-void ScrollAnimator::setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos)
+void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
+{
+    m_currentPosX = offset.x();
+    m_currentPosY = offset.y();
+    notityPositionChanged();
+}
+
+FloatPoint ScrollAnimator::currentPosition() const
 {
-    if (orientation == HorizontalScrollbar)
-        m_currentPosX = pos;
-    else
-        m_currentPosY = pos;
+    return FloatPoint(m_currentPosX, m_currentPosY);
+}
+
+void ScrollAnimator::notityPositionChanged()
+{
+    m_client->setScrollOffsetFromAnimation(IntPoint(m_currentPosX, m_currentPosY));
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/platform/ScrollAnimator.h b/Source/WebCore/platform/ScrollAnimator.h
index e674339..553ceee 100644
--- a/Source/WebCore/platform/ScrollAnimator.h
+++ b/Source/WebCore/platform/ScrollAnimator.h
@@ -35,6 +35,7 @@
 
 namespace WebCore {
 
+class FloatPoint;
 class ScrollbarClient;
 
 class ScrollAnimator {
@@ -50,16 +51,18 @@ public:
     // The base class implementation always scrolls immediately, never animates.
     virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier);
 
-    // Stops any animation in the given direction and updates the ScrollAnimator
-    // with the current scroll position.  This does not cause a callback to the
-    // ScrollbarClient.
-    virtual void setScrollPositionAndStopAnimation(ScrollbarOrientation, float);
+    virtual void scrollToOffsetWithoutAnimation(const FloatPoint&);
+
+    FloatPoint currentPosition() const;
 
 protected:
+    void notityPositionChanged();
+
     ScrollbarClient* m_client;
     float m_currentPosX; // We avoid using a FloatPoint in order to reduce
     float m_currentPosY; // subclass code complexity.
 };
 
 } // namespace WebCore
-#endif
+
+#endif // ScrollAnimator_h
diff --git a/Source/WebCore/platform/ScrollAnimatorWin.cpp b/Source/WebCore/platform/ScrollAnimatorWin.cpp
index 025aa71..cdbfb94 100644
--- a/Source/WebCore/platform/ScrollAnimatorWin.cpp
+++ b/Source/WebCore/platform/ScrollAnimatorWin.cpp
@@ -34,6 +34,7 @@
 
 #include "ScrollAnimatorWin.h"
 
+#include "FloatPoint.h"
 #include "ScrollbarClient.h"
 #include "ScrollbarTheme.h"
 #include <algorithm>
@@ -177,17 +178,24 @@ bool ScrollAnimatorWin::scroll(ScrollbarOrientation orientation, ScrollGranulari
     return true;
 }
 
-void ScrollAnimatorWin::setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos)
+void ScrollAnimatorWin::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
 {
-    PerAxisData* data = (orientation == HorizontalScrollbar) ? &m_horizontalData : &m_verticalData;
-    stopAnimationTimerIfNeeded(data);
-    *data->m_currentPos = pos;
-    data->m_desiredPos = pos;
-    data->m_currentVelocity = 0;
-    data->m_desiredVelocity = 0;
+    stopAnimationTimerIfNeeded(&m_horizontalData);
+    stopAnimationTimerIfNeeded(&m_verticalData);
+
+    *m_horizontalData.m_currentPos = offset.x();
+    m_horizontalData.m_desiredPos = offset.x();
+    m_horizontalData.m_currentVelocity = 0;
+    m_horizontalData.m_desiredVelocity = 0;
+
+    *m_verticalData.m_currentPos = offset.y();
+    m_verticalData.m_desiredPos = offset.y();
+    m_verticalData.m_currentVelocity = 0;
+    m_verticalData.m_desiredVelocity = 0;
+
+    notityPositionChanged();
 }
 
-// static
 double ScrollAnimatorWin::accelerationTime()
 {
     // We elect to use ScrollbarTheme::nativeTheme()->autoscrollTimerDelay() as
@@ -293,7 +301,8 @@ void ScrollAnimatorWin::animateScroll(PerAxisData* data)
         data->m_animationTimer.startOneShot(animationTimerDelay);
         data->m_lastAnimationTime = WTF::currentTime();
     }
-    m_client->setScrollOffsetFromAnimation(IntPoint(*m_horizontalData.m_currentPos, *m_verticalData.m_currentPos));
+
+    notityPositionChanged();
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/platform/ScrollAnimatorWin.h b/Source/WebCore/platform/ScrollAnimatorWin.h
index 7043634..ef421f3 100644
--- a/Source/WebCore/platform/ScrollAnimatorWin.h
+++ b/Source/WebCore/platform/ScrollAnimatorWin.h
@@ -44,7 +44,7 @@ public:
     virtual ~ScrollAnimatorWin();
 
     virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier);
-    virtual void setScrollPositionAndStopAnimation(ScrollbarOrientation, float);
+    virtual void scrollToOffsetWithoutAnimation(const FloatPoint&);
 
 private:
     struct PerAxisData {
@@ -69,8 +69,8 @@ private:
     PerAxisData m_verticalData;
 };
 
-}
+} // namespace WebCore
 
 #endif // ENABLE(SMOOTH_SCROLLING)
 
-#endif
+#endif // ScrollAnimatorWin_h
diff --git a/Source/WebCore/platform/ScrollView.cpp b/Source/WebCore/platform/ScrollView.cpp
index dad73bf..5a68a9d 100644
--- a/Source/WebCore/platform/ScrollView.cpp
+++ b/Source/WebCore/platform/ScrollView.cpp
@@ -320,25 +320,20 @@ int ScrollView::scrollSize(ScrollbarOrientation orientation) const
     return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
 }
 
-void ScrollView::setScrollOffsetFromAnimation(const IntPoint& offset)
+void ScrollView::setScrollOffset(const IntPoint& offset)
 {
-    if (m_horizontalScrollbar)
-        m_horizontalScrollbar->setValue(offset.x(), Scrollbar::FromScrollAnimator);
-    if (m_verticalScrollbar)
-        m_verticalScrollbar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
-}
+    int horizontalOffset = std::max(std::min(offset.x(), contentsWidth() - visibleWidth()), 0);
+    int verticalOffset = std::max(std::min(offset.y(), contentsHeight() - visibleHeight()), 0);
 
-void ScrollView::valueChanged(Scrollbar* scrollbar)
-{
-    // Figure out if we really moved.
     IntSize newOffset = m_scrollOffset;
-    if (scrollbar) {
-        if (scrollbar->orientation() == HorizontalScrollbar)
-            newOffset.setWidth(scrollbar->value() - m_scrollOrigin.x());
-        else if (scrollbar->orientation() == VerticalScrollbar)
-            newOffset.setHeight(scrollbar->value() - m_scrollOrigin.y());
-    }
+    newOffset.setWidth(horizontalOffset - m_scrollOrigin.x());
+    newOffset.setHeight(verticalOffset - m_scrollOrigin.y());
+
+    scrollTo(newOffset);
+}
 
+void ScrollView::scrollTo(const IntSize& newOffset)
+{
     IntSize scrollDelta = newOffset - m_scrollOffset;
     if (scrollDelta == IntSize())
         return;
@@ -351,13 +346,13 @@ void ScrollView::valueChanged(Scrollbar* scrollbar)
     scrollContents(scrollDelta);
 }
 
-void ScrollView::valueChanged(const IntSize& scrollDelta)
+int ScrollView::scrollPosition(Scrollbar* scrollbar) const
 {
-    if (scrollbarsSuppressed())
-        return;
-
-    repaintFixedElementsAfterScrolling();
-    scrollContents(scrollDelta);
+    if (scrollbar->orientation() == HorizontalScrollbar)
+        return scrollPosition().x();
+    if (scrollbar->orientation() == VerticalScrollbar)
+        return scrollPosition().y();
+    return 0;
 }
 
 void ScrollView::setScrollPosition(const IntPoint& scrollPoint)
@@ -391,15 +386,8 @@ bool ScrollView::scroll(ScrollDirection direction, ScrollGranularity granularity
 {
     if (platformWidget())
         return platformScroll(direction, granularity);
-    
-    if (direction == ScrollUp || direction == ScrollDown) {
-        if (m_verticalScrollbar)
-            return m_verticalScrollbar->scroll(direction, granularity);
-    } else {
-        if (m_horizontalScrollbar)
-            return m_horizontalScrollbar->scroll(direction, granularity);
-    }
-    return false;
+
+    return ScrollbarClient::scroll(direction, granularity);
 }
 
 bool ScrollView::logicalScroll(ScrollLogicalDirection direction, ScrollGranularity granularity)
@@ -530,7 +518,6 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
             m_horizontalScrollbar->setSuppressInvalidation(true);
         m_horizontalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
         m_horizontalScrollbar->setProportion(clientWidth, contentsWidth());
-        m_horizontalScrollbar->setValue(scroll.width() + m_scrollOrigin.x(), Scrollbar::NotFromScrollAnimator);
         if (m_scrollbarsSuppressed)
             m_horizontalScrollbar->setSuppressInvalidation(false); 
     } 
@@ -552,7 +539,6 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
             m_verticalScrollbar->setSuppressInvalidation(true);
         m_verticalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
         m_verticalScrollbar->setProportion(clientHeight, contentsHeight());
-        m_verticalScrollbar->setValue(scroll.height() + m_scrollOrigin.y(), Scrollbar::NotFromScrollAnimator);
         if (m_scrollbarsSuppressed)
             m_verticalScrollbar->setSuppressInvalidation(false);
     }
@@ -562,15 +548,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
         updateScrollCorner();
     }
 
-    // See if our offset has changed in a situation where we might not have scrollbars.
-    // This can happen when editing a body with overflow:hidden and scrolling to reveal selection.
-    // It can also happen when maximizing a window that has scrollbars (but the new maximized result
-    // does not).
-    IntSize scrollDelta = scroll - m_scrollOffset;
-    if (scrollDelta != IntSize()) {
-       m_scrollOffset = scroll;
-       valueChanged(scrollDelta);
-    }
+    ScrollbarClient::scrollToOffsetWithoutAnimation(FloatPoint(scroll.width(), scroll.height()));
 
     m_inUpdateScrollbars = false;
 }
@@ -757,6 +735,7 @@ void ScrollView::wheelEvent(PlatformWheelEvent& e)
     // scroll any further.
     float deltaX = m_horizontalScrollbar ? e.deltaX() : 0;
     float deltaY = m_verticalScrollbar ? e.deltaY() : 0;
+    
     IntSize maxForwardScrollDelta = maximumScrollPosition() - scrollPosition();
     IntSize maxBackwardScrollDelta = scrollPosition() - minimumScrollPosition();
     if ((deltaX < 0 && maxForwardScrollDelta.width() > 0)
@@ -773,9 +752,9 @@ void ScrollView::wheelEvent(PlatformWheelEvent& e)
         }
 
         if (deltaY)
-            m_verticalScrollbar->scroll(ScrollUp, ScrollByPixel, deltaY);
+            ScrollbarClient::scroll(ScrollUp, ScrollByPixel, deltaY);
         if (deltaX)
-            m_horizontalScrollbar->scroll(ScrollLeft, ScrollByPixel, deltaX);
+            ScrollbarClient::scroll(ScrollLeft, ScrollByPixel, deltaX);
     }
 }
 
diff --git a/Source/WebCore/platform/ScrollView.h b/Source/WebCore/platform/ScrollView.h
index 2477f49..00e8bf8 100644
--- a/Source/WebCore/platform/ScrollView.h
+++ b/Source/WebCore/platform/ScrollView.h
@@ -60,10 +60,12 @@ public:
 
     // ScrollbarClient functions.  FrameView overrides the others.
     virtual int scrollSize(ScrollbarOrientation orientation) const;
-    virtual void setScrollOffsetFromAnimation(const IntPoint&);
-    virtual void valueChanged(Scrollbar*);
-    virtual void valueChanged(const IntSize&);
+    virtual int scrollPosition(Scrollbar*) const;
+    virtual void setScrollOffset(const IntPoint&);
     
+    // NOTE: This should only be called by the overriden setScrollOffset from ScrollbarClient.
+    virtual void scrollTo(const IntSize& newOffset);
+
     // The window thats hosts the ScrollView. The ScrollView will communicate scrolls and repaints to the
     // host window in the window's coordinate space.
     virtual HostWindow* hostWindow() const = 0;
@@ -78,8 +80,8 @@ public:
     
     // If the scroll view does not use a native widget, then it will have cross-platform Scrollbars. These functions
     // can be used to obtain those scrollbars.
-    Scrollbar* horizontalScrollbar() const { return m_horizontalScrollbar.get(); }
-    Scrollbar* verticalScrollbar() const { return m_verticalScrollbar.get(); }
+    virtual Scrollbar* horizontalScrollbar() const { return m_horizontalScrollbar.get(); }
+    virtual Scrollbar* verticalScrollbar() const { return m_verticalScrollbar.get(); }
     bool isScrollViewScrollbar(const Widget* child) const { return horizontalScrollbar() == child || verticalScrollbar() == child; }
 
     // Functions for setting and retrieving the scrolling mode in each axis (horizontal/vertical). The mode has values of
diff --git a/Source/WebCore/platform/Scrollbar.cpp b/Source/WebCore/platform/Scrollbar.cpp
index 7fd2651..377186d 100644
--- a/Source/WebCore/platform/Scrollbar.cpp
+++ b/Source/WebCore/platform/Scrollbar.cpp
@@ -104,13 +104,19 @@ Scrollbar::~Scrollbar()
     m_theme->unregisterScrollbar(this);
 }
 
-bool Scrollbar::setValue(int v, ScrollSource source)
+void Scrollbar::offsetDidChange()
 {
-    v = max(min(v, m_totalSize - m_visibleSize), 0);
-    if (value() == v)
-        return false; // Our value stayed the same.
-    setCurrentPos(v, source);
-    return true;
+    ASSERT(m_client);
+
+    float position = static_cast<float>(m_client->scrollPosition(this));
+    if (position == m_currentPos)
+        return;
+
+    int oldThumbPosition = theme()->thumbPosition(this);
+    m_currentPos = position;
+    updateThumbPosition();
+    if (m_pressedPart == ThumbPart)
+        setPressedPos(m_pressedPos + theme()->thumbPosition(this) - oldThumbPosition);    
 }
 
 void Scrollbar::setProportion(int visibleSize, int totalSize)
@@ -131,31 +137,6 @@ void Scrollbar::setSteps(int lineStep, int pageStep, int pixelsPerStep)
     m_pixelStep = 1.0f / pixelsPerStep;
 }
 
-bool Scrollbar::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
-{
-#if HAVE(ACCESSIBILITY)
-    if (AXObjectCache::accessibilityEnabled() && axObjectCache())
-        axObjectCache()->postNotification(axObjectCache()->getOrCreate(this), 0, AXObjectCache::AXValueChanged, true);
-#endif
-
-    // Ignore perpendicular scrolls.
-    if ((m_orientation == HorizontalScrollbar) ? (direction == ScrollUp || direction == ScrollDown) : (direction == ScrollLeft || direction == ScrollRight))
-        return false;
-    float step = 0;
-    switch (granularity) {
-    case ScrollByLine:     step = m_lineStep;  break;
-    case ScrollByPage:     step = m_pageStep;  break;
-    case ScrollByDocument: step = m_totalSize; break;
-    case ScrollByPixel:    step = m_pixelStep; break;
-    }
-    if (direction == ScrollUp || direction == ScrollLeft)
-        multiplier = -multiplier;
-    if (client())
-        return client()->scroll(m_orientation, granularity, step, multiplier);
-
-    return setCurrentPos(max(min(m_currentPos + (step * multiplier), static_cast<float>(m_totalSize - m_visibleSize)), 0.0f), NotFromScrollAnimator);
-}
-
 void Scrollbar::updateThumb()
 {
 #ifdef THUMB_POSITION_AFFECTS_BUTTONS
@@ -215,7 +196,7 @@ void Scrollbar::autoscrollPressedPart(double delay)
     }
 
     // Handle the arrows and track.
-    if (scroll(pressedPartScrollDirection(), pressedPartScrollGranularity()))
+    if (client()->scroll(pressedPartScrollDirection(), pressedPartScrollGranularity()))
         startTimerIfNeeded(delay);
 }
 
@@ -284,28 +265,11 @@ void Scrollbar::moveThumb(int pos)
         delta = min(maxPos - thumbPos, delta);
     else if (delta < 0)
         delta = max(-thumbPos, delta);
-    if (delta)
-        setCurrentPos(static_cast<float>(thumbPos + delta) * maximum() / (trackLen - thumbLen), NotFromScrollAnimator);
-}
-
-bool Scrollbar::setCurrentPos(float pos, ScrollSource source)
-{
-    if ((source != FromScrollAnimator) && client())
-        client()->setScrollPositionAndStopAnimation(m_orientation, pos);
-
-    if (pos == m_currentPos)
-        return false;
-
-    int oldValue = value();
-    int oldThumbPos = theme()->thumbPosition(this);
-    m_currentPos = pos;
-    updateThumbPosition();
-    if (m_pressedPart == ThumbPart)
-        setPressedPos(m_pressedPos + theme()->thumbPosition(this) - oldThumbPos);
-
-    if (value() != oldValue && client())
-        client()->valueChanged(this);
-    return true;
+    
+    if (delta) {
+        float newPosition = static_cast<float>(thumbPos + delta) * maximum() / (trackLen - thumbLen);
+        client()->scrollToOffsetWithoutAnimation(m_orientation, newPosition);
+    }
 }
 
 void Scrollbar::setHoveredPart(ScrollbarPart part)
@@ -337,7 +301,7 @@ bool Scrollbar::mouseMoved(const PlatformMouseEvent& evt)
 {
     if (m_pressedPart == ThumbPart) {
         if (theme()->shouldSnapBackToDragOrigin(this, evt))
-            setCurrentPos(m_dragOrigin, NotFromScrollAnimator);
+            client()->scrollToOffsetWithoutAnimation(m_orientation, m_dragOrigin);
         else {
             moveThumb(m_orientation == HorizontalScrollbar ? 
                       convertFromContainingWindow(evt.pos()).x() :
@@ -521,4 +485,4 @@ IntPoint Scrollbar::convertFromContainingView(const IntPoint& parentPoint) const
     return Widget::convertFromContainingView(parentPoint);
 }
 
-}
+} // namespace WebCore
diff --git a/Source/WebCore/platform/Scrollbar.h b/Source/WebCore/platform/Scrollbar.h
index 69e94a1..869aef2 100644
--- a/Source/WebCore/platform/Scrollbar.h
+++ b/Source/WebCore/platform/Scrollbar.h
@@ -52,6 +52,9 @@ public:
     // Must be implemented by platforms that can't simply use the Scrollbar base class.  Right now the only platform that is not using the base class is GTK.
     static PassRefPtr<Scrollbar> createNativeScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize size);
 
+    // Called by the ScrollbarClient when the scroll offset changes.
+    void offsetDidChange();
+
     static int pixelsPerLineStep() { return 40; }
     static float minFractionToStepWhenPaging() { return 0.875f; }
     static int maxOverlapBetweenPages();
@@ -61,7 +64,7 @@ public:
 
     virtual bool isCustomScrollbar() const { return false; }
     ScrollbarOrientation orientation() const { return m_orientation; }
-    
+
     int value() const { return lroundf(m_currentPos); }
     float currentPos() const { return m_currentPos; }
     int pressedPos() const { return m_pressedPos; }
@@ -73,18 +76,15 @@ public:
     int lineStep() const { return m_lineStep; }
     int pageStep() const { return m_pageStep; }
     float pixelStep() const { return m_pixelStep; }
-    
+
     ScrollbarPart pressedPart() const { return m_pressedPart; }
     ScrollbarPart hoveredPart() const { return m_hoveredPart; }
     virtual void setHoveredPart(ScrollbarPart);
     virtual void setPressedPart(ScrollbarPart);
 
     void setSteps(int lineStep, int pageStep, int pixelsPerStep = 1);
-    bool setValue(int, ScrollSource source);
     void setProportion(int visibleSize, int totalSize);
     void setPressedPos(int p) { m_pressedPos = p; }
-
-    bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1);
     
     virtual void paint(GraphicsContext*, const IntRect& damageRect);
 
@@ -172,10 +172,8 @@ protected:
 private:
     virtual bool isScrollbar() const { return true; }
     virtual AXObjectCache* axObjectCache() const;
-
-    bool setCurrentPos(float pos, ScrollSource source);
 };
 
-}
+} // namespace WebCore
 
-#endif
+#endif // Scrollbar_h
diff --git a/Source/WebCore/platform/ScrollbarClient.cpp b/Source/WebCore/platform/ScrollbarClient.cpp
index 2f81a93..d8529b4 100644
--- a/Source/WebCore/platform/ScrollbarClient.cpp
+++ b/Source/WebCore/platform/ScrollbarClient.cpp
@@ -31,6 +31,8 @@
 #include "config.h"
 #include "ScrollbarClient.h"
 
+#include "FloatPoint.h"
+#include "PlatformWheelEvent.h"
 #include "ScrollAnimator.h"
 
 namespace WebCore {
@@ -44,14 +46,76 @@ ScrollbarClient::~ScrollbarClient()
 {
 }
 
-bool ScrollbarClient::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier)
+bool ScrollbarClient::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
 {
+    ScrollbarOrientation orientation;
+    Scrollbar* scrollbar;
+    if (direction == ScrollUp || direction == ScrollDown) {
+        orientation = VerticalScrollbar;
+        scrollbar = verticalScrollbar();
+    } else {
+        orientation = HorizontalScrollbar;
+        scrollbar = horizontalScrollbar();
+    }
+
+    if (!scrollbar)
+        return false;
+
+    float step = 0;
+    switch (granularity) {
+    case ScrollByLine:
+        step = scrollbar->lineStep();
+        break;
+    case ScrollByPage:
+        step = scrollbar->pageStep();
+        break;
+    case ScrollByDocument:
+        step = scrollbar->totalSize();
+        break;
+    case ScrollByPixel:
+        step = scrollbar->pixelStep();
+        break;
+    }
+
+    if (direction == ScrollUp || direction == ScrollLeft)
+        multiplier = -multiplier;
+
     return m_scrollAnimator->scroll(orientation, granularity, step, multiplier);
 }
 
-void ScrollbarClient::setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos)
+void ScrollbarClient::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
 {
-    m_scrollAnimator->setScrollPositionAndStopAnimation(orientation, pos);
+    m_scrollAnimator->scrollToOffsetWithoutAnimation(offset);
+}
+
+void ScrollbarClient::scrollToOffsetWithoutAnimation(ScrollbarOrientation orientation, float offset)
+{
+    if (orientation == HorizontalScrollbar)
+        scrollToXOffsetWithoutAnimation(offset);
+    else
+        scrollToYOffsetWithoutAnimation(offset);
+}
+
+void ScrollbarClient::scrollToXOffsetWithoutAnimation(float x)
+{
+    scrollToOffsetWithoutAnimation(FloatPoint(x, m_scrollAnimator->currentPosition().y()));
+}
+
+void ScrollbarClient::scrollToYOffsetWithoutAnimation(float y)
+{
+    scrollToOffsetWithoutAnimation(FloatPoint(m_scrollAnimator->currentPosition().x(), y));
+}
+
+void ScrollbarClient::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+    // Tell the derived class to scroll its contents.
+    setScrollOffset(offset);
+
+    // Tell the scrollbars to update their thumb postions.
+    if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar())
+        horizontalScrollbar->offsetDidChange();
+    if (Scrollbar* verticalScrollbar = this->verticalScrollbar())
+        verticalScrollbar->offsetDidChange();
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/platform/ScrollbarClient.h b/Source/WebCore/platform/ScrollbarClient.h
index ab3b10e..4abd51e 100644
--- a/Source/WebCore/platform/ScrollbarClient.h
+++ b/Source/WebCore/platform/ScrollbarClient.h
@@ -26,13 +26,14 @@
 #ifndef ScrollbarClient_h
 #define ScrollbarClient_h
 
-#include "IntPoint.h"
 #include "IntRect.h"
 #include "Scrollbar.h"
 #include <wtf/Vector.h>
 
 namespace WebCore {
 
+class FloatPoint;
+class PlatformWheelEvent;
 class ScrollAnimator;
 
 class ScrollbarClient {
@@ -40,18 +41,24 @@ public:
     ScrollbarClient();
     virtual ~ScrollbarClient();
 
-    bool scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier);
-    void setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos);
+    bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1);
+    void scrollToOffsetWithoutAnimation(const FloatPoint&);
+    void scrollToOffsetWithoutAnimation(ScrollbarOrientation, float offset);
+    void scrollToXOffsetWithoutAnimation(float x);
+    void scrollToYOffsetWithoutAnimation(float x);
 
-    virtual int scrollSize(ScrollbarOrientation orientation) const = 0;
-    virtual void setScrollOffsetFromAnimation(const IntPoint&) = 0;
-    virtual void valueChanged(Scrollbar*) = 0;
+    virtual int scrollSize(ScrollbarOrientation) const = 0;
+    virtual int scrollPosition(Scrollbar*) const = 0;
     virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0;
     virtual bool isActive() const = 0;
     virtual bool scrollbarCornerPresent() const = 0;
-
     virtual void getTickmarks(Vector<IntRect>&) const { }
 
+    // This function should be overriden by subclasses to perform the actual
+    // scroll of the content.
+    virtual void setScrollOffset(const IntPoint&) = 0;
+
+
     // Convert points and rects between the scrollbar and its containing view.
     // The client needs to implement these in order to be aware of layout effects
     // like CSS transforms.
@@ -72,9 +79,17 @@ public:
         return scrollbar->Widget::convertFromContainingView(parentPoint);
     }
 
+    virtual Scrollbar* horizontalScrollbar() const { return 0; }
+    virtual Scrollbar* verticalScrollbar() const { return 0; }
+
 private:
+    // NOTE: Only called from the ScrollAnimator.
+    friend class ScrollAnimator;
+    void setScrollOffsetFromAnimation(const IntPoint&);
+
     OwnPtr<ScrollAnimator> m_scrollAnimator;
 };
 
-}
-#endif
+} // namespace WebCore
+
+#endif // ScrollbarClient_h
diff --git a/Source/WebCore/platform/efl/ScrollbarEfl.cpp b/Source/WebCore/platform/efl/ScrollbarEfl.cpp
index 282ca7c..a7a063d 100644
--- a/Source/WebCore/platform/efl/ScrollbarEfl.cpp
+++ b/Source/WebCore/platform/efl/ScrollbarEfl.cpp
@@ -84,7 +84,7 @@ static void scrollbarEflEdjeMessage(void* data, Evas_Object* o, Edje_Message_Typ
 
     m = static_cast<Edje_Message_Float*>(msg);
     v = m->val * (that->totalSize() - that->visibleSize());
-    that->setValue(v, Scrollbar::NotFromScrollAnimator);
+    that->client()->scrollToOffsetWithoutAnimation(that->orientation(), v);
 }
 
 void ScrollbarEfl::setParent(ScrollView* view)
diff --git a/Source/WebCore/platform/gtk/MainFrameScrollbarGtk.cpp b/Source/WebCore/platform/gtk/MainFrameScrollbarGtk.cpp
index c2e24e0..9eef3dc 100644
--- a/Source/WebCore/platform/gtk/MainFrameScrollbarGtk.cpp
+++ b/Source/WebCore/platform/gtk/MainFrameScrollbarGtk.cpp
@@ -25,6 +25,7 @@
 #include "GraphicsContext.h"
 #include "GtkVersioning.h"
 #include "IntRect.h"
+#include "ScrollbarClient.h"
 #include <gtk/gtk.h>
 
 using namespace WebCore;
@@ -108,7 +109,7 @@ void MainFrameScrollbarGtk::updateThumbProportion()
 
 void MainFrameScrollbarGtk::gtkValueChanged(GtkAdjustment*, MainFrameScrollbarGtk* that)
 {
-    that->setValue(static_cast<int>(gtk_adjustment_get_value(that->m_adjustment.get())), NotFromScrollAnimator);
+    that->client()->scrollToOffsetWithoutAnimation(that->orientation(), static_cast<int>(gtk_adjustment_get_value(that->m_adjustment.get())));
 }
 
 void MainFrameScrollbarGtk::paint(GraphicsContext* context, const IntRect& rect)
diff --git a/Source/WebCore/platform/mac/ScrollAnimatorMac.h b/Source/WebCore/platform/mac/ScrollAnimatorMac.h
index 234e43c..401833c 100644
--- a/Source/WebCore/platform/mac/ScrollAnimatorMac.h
+++ b/Source/WebCore/platform/mac/ScrollAnimatorMac.h
@@ -28,7 +28,6 @@
 
 #if ENABLE(SMOOTH_SCROLLING)
 
-#include "FloatPoint.h"
 #include "ScrollAnimator.h"
 #include <wtf/RetainPtr.h>
 
@@ -46,10 +45,9 @@ public:
     virtual ~ScrollAnimatorMac();
 
     virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier);
-    virtual void setScrollPositionAndStopAnimation(ScrollbarOrientation, float position);
+    virtual void scrollToOffsetWithoutAnimation(const FloatPoint&);
 
     // Called by the ScrollAnimationHelperDelegate.
-    FloatPoint currentPosition() const;
     void immediateScrollToPoint(const FloatPoint& newPosition);
 
 private:
diff --git a/Source/WebCore/platform/mac/ScrollAnimatorMac.mm b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
index ca71bd3..fcca519 100644
--- a/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
+++ b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
@@ -27,6 +27,7 @@
 
 #if ENABLE(SMOOTH_SCROLLING)
 
+#include "FloatPoint.h"
 #include "ScrollAnimatorMac.h"
 #include "ScrollbarClient.h"
 
@@ -161,23 +162,17 @@ bool ScrollAnimatorMac::scroll(ScrollbarOrientation orientation, ScrollGranulari
     return true;
 }
 
-void ScrollAnimatorMac::setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos)
+void ScrollAnimatorMac::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
 {
     [m_scrollAnimationHelper.get() _stopRun];
-    ScrollAnimator::setScrollPositionAndStopAnimation(orientation, pos);
-}
-
-FloatPoint ScrollAnimatorMac::currentPosition() const
-{
-    return FloatPoint(m_currentPosX, m_currentPosY);
+    ScrollAnimator::scrollToOffsetWithoutAnimation(offset);
 }
 
 void ScrollAnimatorMac::immediateScrollToPoint(const FloatPoint& newPosition)
 {
     m_currentPosX = newPosition.x();
     m_currentPosY = newPosition.y();
-
-    m_client->setScrollOffsetFromAnimation(IntPoint(m_currentPosX, m_currentPosY));
+    notityPositionChanged();
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/platform/qt/ScrollbarQt.cpp b/Source/WebCore/platform/qt/ScrollbarQt.cpp
index a517064..d32e693 100644
--- a/Source/WebCore/platform/qt/ScrollbarQt.cpp
+++ b/Source/WebCore/platform/qt/ScrollbarQt.cpp
@@ -34,6 +34,7 @@
 #include "GraphicsContext.h"
 #include "IntRect.h"
 #include "PlatformMouseEvent.h"
+#include "ScrollbarClient.h"
 #include "ScrollbarTheme.h"
 
 #include <QApplication>
@@ -76,17 +77,17 @@ bool Scrollbar::contextMenu(const PlatformMouseEvent& event)
         const QPoint pos = convertFromContainingWindow(event.pos());
         moveThumb(horizontal ? pos.x() : pos.y());
     } else if (actionSelected == actScrollTop)
-        scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByDocument);
+        client()->scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByDocument);
     else if (actionSelected == actScrollBottom)
-        scroll(horizontal ? ScrollRight : ScrollDown, ScrollByDocument);
+        client()->scroll(horizontal ? ScrollRight : ScrollDown, ScrollByDocument);
     else if (actionSelected == actPageUp)
-        scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByPage);
+        client()->scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByPage);
     else if (actionSelected == actPageDown)
-        scroll(horizontal ? ScrollRight : ScrollDown, ScrollByPage);
+        client()->scroll(horizontal ? ScrollRight : ScrollDown, ScrollByPage);
     else if (actionSelected == actScrollUp)
-        scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByLine);
+        client()->scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByLine);
     else if (actionSelected == actScrollDown)
-        scroll(horizontal ? ScrollRight : ScrollDown, ScrollByLine);
+        client()->scroll(horizontal ? ScrollRight : ScrollDown, ScrollByLine);
 #endif // QT_NO_CONTEXTMENU
     return true;
 }
diff --git a/Source/WebCore/platform/win/PopupMenuWin.cpp b/Source/WebCore/platform/win/PopupMenuWin.cpp
index 88c9a4f..fe903cd 100644
--- a/Source/WebCore/platform/win/PopupMenuWin.cpp
+++ b/Source/WebCore/platform/win/PopupMenuWin.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
  * Copyright (C) 2007-2009 Torch Mobile Inc.
  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
  *
@@ -532,12 +532,12 @@ bool PopupMenuWin::scrollToRevealSelection()
     int index = focusedIndex();
 
     if (index < m_scrollOffset) {
-        m_scrollbar->setValue(index, Scrollbar::NotFromScrollAnimator);
+        ScrollbarClient::scrollToYOffsetWithoutAnimation(index);
         return true;
     }
 
     if (index >= m_scrollOffset + visibleItems()) {
-        m_scrollbar->setValue(index - visibleItems() + 1, Scrollbar::NotFromScrollAnimator);
+        ScrollbarClient::scrollToYOffsetWithoutAnimation(index - visibleItems() + 1);
         return true;
     }
 
@@ -670,21 +670,23 @@ int PopupMenuWin::scrollSize(ScrollbarOrientation orientation) const
     return ((orientation == VerticalScrollbar) && m_scrollbar) ? (m_scrollbar->totalSize() - m_scrollbar->visibleSize()) : 0;
 }
 
-void PopupMenuWin::setScrollOffsetFromAnimation(const IntPoint& offset)
+int PopupMenuWin::scrollPosition(Scrollbar*) const
 {
-    if (m_scrollbar)
-        m_scrollbar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+    return m_scrollOffset;
+}
+
+void PopupMenuWin::setScrollOffset(const IntPoint& offset)
+{
+    scrollTo(offset.y());
 }
 
-void PopupMenuWin::valueChanged(Scrollbar* scrollBar)
+void PopupMenuWin::scrollTo(int offset)
 {
     ASSERT(m_scrollbar);
 
     if (!m_popup)
         return;
 
-    int offset = scrollBar->value();
-
     if (m_scrollOffset == offset)
         return;
 
@@ -991,7 +993,8 @@ LRESULT PopupMenuWin::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
                 else
                     --i;
             }
-            scrollbar()->scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i));
+
+            ScrollbarClient::scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i));
             break;
         }
 
diff --git a/Source/WebCore/platform/win/PopupMenuWin.h b/Source/WebCore/platform/win/PopupMenuWin.h
index bfec7aa..de7a93d 100644
--- a/Source/WebCore/platform/win/PopupMenuWin.h
+++ b/Source/WebCore/platform/win/PopupMenuWin.h
@@ -78,7 +78,6 @@ private:
     void setWasClicked(bool b = true) { m_wasClicked = b; }
     bool wasClicked() const { return m_wasClicked; }
 
-    void setScrollOffset(int offset) { m_scrollOffset = offset; }
     int scrollOffset() const { return m_scrollOffset; }
 
     bool scrollToRevealSelection();
@@ -92,11 +91,15 @@ private:
 
     // ScrollBarClient
     virtual int scrollSize(ScrollbarOrientation orientation) const;
-    virtual void setScrollOffsetFromAnimation(const IntPoint&);
-    virtual void valueChanged(Scrollbar*);
+    virtual int scrollPosition(Scrollbar*) const;
+    virtual void setScrollOffset(const IntPoint&);
     virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
     virtual bool isActive() const { return true; }
     virtual bool scrollbarCornerPresent() const { return false; }
+    virtual Scrollbar* verticalScrollbar() const { return m_scrollbar.get(); }
+
+    // NOTE: This should only be called by the overriden setScrollOffset from ScrollbarClient.
+    void scrollTo(int offset);
 
     void calculatePositionAndSize(const IntRect&, FrameView*);
     void invalidateItem(int index);
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index 32b4f5b..900054e 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -1306,23 +1306,36 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
     }
 }
 
-void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repaint)
+void RenderLayer::scrollToOffset(int x, int y)
+{
+    ScrollbarClient::scrollToOffsetWithoutAnimation(IntPoint(x, y));
+}
+
+void RenderLayer::scrollTo(int x, int y)
 {
     RenderBox* box = renderBox();
     if (!box)
         return;
 
     if (box->style()->overflowX() != OMARQUEE) {
-        if (x < 0) x = 0;
-        if (y < 0) y = 0;
+        if (x < 0)
+            x = 0;
+        if (y < 0)
+            y = 0;
     
         // Call the scrollWidth/Height functions so that the dimensions will be computed if they need
         // to be (for overflow:hidden blocks).
         int maxX = scrollWidth() - box->clientWidth();
+        if (maxX < 0)
+            maxX = 0;
         int maxY = scrollHeight() - box->clientHeight();
-        
-        if (x > maxX) x = maxX;
-        if (y > maxY) y = maxY;
+        if (maxY < 0)
+            maxY = 0;
+
+        if (x > maxX)
+            x = maxX;
+        if (y > maxY)
+            y = maxY;
     }
     
     // FIXME: Eventually, we will want to perform a blit.  For now never
@@ -1386,16 +1399,9 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
     }
 
     // Just schedule a full repaint of our object.
-    if (view && repaint)
+    if (view)
         renderer()->repaintUsingContainer(repaintContainer, rectForRepaint);
 
-    if (updateScrollbars) {
-        if (m_hBar)
-            m_hBar->setValue(scrollXOffset(), Scrollbar::NotFromScrollAnimator);
-        if (m_vBar)
-            m_vBar->setValue(m_scrollY, Scrollbar::NotFromScrollAnimator);
-    }
-
     // Schedule the scroll DOM event.
     renderer()->node()->document()->eventQueue()->enqueueScrollEvent(renderer()->node(), EventQueue::ScrollEventElementTarget);
 }
@@ -1649,36 +1655,18 @@ int RenderLayer::scrollSize(ScrollbarOrientation orientation) const
     return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
 }
 
-void RenderLayer::setScrollOffsetFromAnimation(const IntPoint& offset)
+void RenderLayer::setScrollOffset(const IntPoint& offset)
 {
-    if (m_hBar)
-        m_hBar->setValue(offset.x(), Scrollbar::FromScrollAnimator);
-    if (m_vBar)
-        m_vBar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+    scrollTo(offset.x(), offset.y());
 }
 
-void RenderLayer::valueChanged(Scrollbar*)
+int RenderLayer::scrollPosition(Scrollbar* scrollbar) const
 {
-    // Update scroll position from scrollbars.
-
-    bool needUpdate = false;
-    int newX = scrollXOffset();
-    int newY = m_scrollY;
-    
-    if (m_hBar) {
-        newX = m_hBar->value();
-        if (newX != scrollXOffset())
-           needUpdate = true;
-    }
-
-    if (m_vBar) {
-        newY = m_vBar->value();
-        if (newY != m_scrollY)
-           needUpdate = true;
-    }
-
-    if (needUpdate)
-        scrollToOffset(newX, newY, false);
+    if (scrollbar->orientation() == HorizontalScrollbar)
+        return scrollXOffset();
+    if (scrollbar->orientation() == VerticalScrollbar)
+        return m_scrollY;
+    return 0;
 }
 
 bool RenderLayer::isActive() const
@@ -1687,7 +1675,6 @@ bool RenderLayer::isActive() const
     return page && page->focusController()->isActive();
 }
 
-
 static IntRect cornerRect(const RenderLayer* layer, const IntRect& bounds)
 {
     int horizontalThickness;
@@ -2031,8 +2018,7 @@ void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOve
     }
 }
 
-void
-RenderLayer::updateScrollInfoAfterLayout()
+void RenderLayer::updateScrollInfoAfterLayout()
 {
     RenderBox* box = renderBox();
     if (!box)
@@ -2124,28 +2110,16 @@ RenderLayer::updateScrollInfoAfterLayout()
         int pageStep = max(max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
         m_hBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
         m_hBar->setProportion(clientWidth, m_scrollWidth);
-        // Explicitly set the horizontal scroll value.  This ensures that when a
-        // right-to-left scrollable area's width (or content width) changes, the
-        // top right corner of the content doesn't shift with respect to the top
-        // right corner of the area. Conceptually, right-to-left areas have
-        // their origin at the top-right, but RenderLayer is top-left oriented,
-        // so this is needed to keep everything working.
-        m_hBar->setValue(scrollXOffset(), Scrollbar::NotFromScrollAnimator);
     }
     if (m_vBar) {
         int clientHeight = box->clientHeight();
         int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
         m_vBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
         m_vBar->setProportion(clientHeight, m_scrollHeight);
-        // Explicitly set the vertical scroll value.  This ensures that when a
-        // right-to-left vertical writing-mode scrollable area's height (or content height) changes, the
-        // bottom right corner of the content doesn't shift with respect to the bottom
-        // right corner of the area. Conceptually, right-to-left vertical writing-mode areas have
-        // their origin at the bottom-right, but RenderLayer is top-left oriented,
-        // so this is needed to keep everything working.
-        m_vBar->setValue(scrollYOffset(), Scrollbar::NotFromScrollAnimator);
     }
  
+    scrollToOffset(scrollXOffset(), scrollYOffset());
+ 
     if (renderer()->node() && renderer()->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
         updateOverflowStatus(horizontalOverflow, verticalOverflow);
 }
@@ -2300,15 +2274,7 @@ bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const IntPoint&
 
 bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
 {
-    bool didHorizontalScroll = false;
-    bool didVerticalScroll = false;
-
-    if (m_hBar)
-        didHorizontalScroll = m_hBar->scroll(direction, granularity, multiplier);
-    if (m_vBar)
-        didVerticalScroll = m_vBar->scroll(direction, granularity, multiplier);
-
-    return (didHorizontalScroll || didVerticalScroll);
+    return ScrollbarClient::scroll(direction, granularity, multiplier);
 }
 
 void RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintBehavior paintBehavior, RenderObject *paintingRoot)
diff --git a/Source/WebCore/rendering/RenderLayer.h b/Source/WebCore/rendering/RenderLayer.h
index 1b60594..cca3a7e 100644
--- a/Source/WebCore/rendering/RenderLayer.h
+++ b/Source/WebCore/rendering/RenderLayer.h
@@ -239,7 +239,7 @@ public:
     int scrollXOffset() const { return m_scrollX + m_scrollOrigin.x(); }
     int scrollYOffset() const { return m_scrollY + m_scrollOrigin.y(); }
 
-    void scrollToOffset(int x, int y, bool updateScrollbars = true, bool repaint = true);
+    void scrollToOffset(int x, int y);
     void scrollToXOffset(int x) { scrollToOffset(x, m_scrollY + m_scrollOrigin.y()); }
     void scrollToYOffset(int y) { scrollToOffset(m_scrollX + m_scrollOrigin.x(), y); }
     void scrollRectToVisible(const IntRect&, bool scrollToAnchor = false, const ScrollAlignment& alignX = ScrollAlignment::alignCenterIfNeeded, const ScrollAlignment& alignY = ScrollAlignment::alignCenterIfNeeded);
@@ -515,8 +515,8 @@ private:
 
     // ScrollBarClient interface
     virtual int scrollSize(ScrollbarOrientation orientation) const;
-    virtual void setScrollOffsetFromAnimation(const IntPoint&);
-    virtual void valueChanged(Scrollbar*);
+    virtual void setScrollOffset(const IntPoint&);
+    virtual int scrollPosition(Scrollbar*) const;
     virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
     virtual bool isActive() const;
     virtual bool scrollbarCornerPresent() const;
@@ -524,7 +524,10 @@ private:
     virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar*, const IntRect&) const;
     virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar*, const IntPoint&) const;
     virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar*, const IntPoint&) const;
-    
+
+    // NOTE: This should only be called by the overriden setScrollOffset from ScrollbarClient.
+    void scrollTo(int x, int y);
+
     IntSize scrollbarOffset(const Scrollbar*) const;
     
     void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow);
diff --git a/Source/WebCore/rendering/RenderListBox.cpp b/Source/WebCore/rendering/RenderListBox.cpp
index 6c2f13e..3df1486 100644
--- a/Source/WebCore/rendering/RenderListBox.cpp
+++ b/Source/WebCore/rendering/RenderListBox.cpp
@@ -495,9 +495,7 @@ bool RenderListBox::scrollToRevealElementAtListIndex(int index)
     else
         newOffset = index - numVisibleItems() + 1;
 
-    m_indexOffset = newOffset;
-    if (m_vBar)
-        m_vBar->setValue(m_indexOffset, Scrollbar::NotFromScrollAnimator);
+    ScrollbarClient::scrollToYOffsetWithoutAnimation(newOffset);
 
     return true;
 }
@@ -509,12 +507,12 @@ bool RenderListBox::listIndexIsVisible(int index)
 
 bool RenderListBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier, Node**)
 {
-    return m_vBar && m_vBar->scroll(direction, granularity, multiplier);
+    return ScrollbarClient::scroll(direction, granularity, multiplier);
 }
 
 bool RenderListBox::logicalScroll(ScrollLogicalDirection direction, ScrollGranularity granularity, float multiplier, Node**)
 {
-    return m_vBar && m_vBar->scroll(logicalToPhysical(direction, style()->isHorizontalWritingMode(), style()->isFlippedBlocksWritingMode()), granularity, multiplier);
+    return ScrollbarClient::scroll(logicalToPhysical(direction, style()->isHorizontalWritingMode(), style()->isFlippedBlocksWritingMode()), granularity, multiplier);
 }
 
 void RenderListBox::valueChanged(unsigned listIndex)
@@ -530,20 +528,24 @@ int RenderListBox::scrollSize(ScrollbarOrientation orientation) const
     return ((orientation == VerticalScrollbar) && m_vBar) ? (m_vBar->totalSize() - m_vBar->visibleSize()) : 0;
 }
 
-void RenderListBox::setScrollOffsetFromAnimation(const IntPoint& offset)
+int RenderListBox::scrollPosition(Scrollbar*) const
 {
-    if (m_vBar)
-        m_vBar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+    return m_indexOffset;
 }
 
-void RenderListBox::valueChanged(Scrollbar*)
+void RenderListBox::setScrollOffset(const IntPoint& offset)
 {
-    int newOffset = m_vBar->value();
-    if (newOffset != m_indexOffset) {
-        m_indexOffset = newOffset;
-        repaint();
-        node()->document()->eventQueue()->enqueueScrollEvent(node(), EventQueue::ScrollEventElementTarget);
-    }
+    scrollTo(offset.y());
+}
+
+void RenderListBox::scrollTo(int newOffset)
+{
+    if (newOffset == m_indexOffset)
+        return;
+
+    m_indexOffset = newOffset;
+    repaint();
+    node()->document()->eventQueue()->enqueueScrollEvent(node(), EventQueue::ScrollEventElementTarget);
 }
 
 int RenderListBox::itemHeight() const
@@ -589,9 +591,8 @@ void RenderListBox::setScrollTop(int newTop)
     int index = newTop / itemHeight();
     if (index < 0 || index >= numItems() || index == m_indexOffset)
         return;
-    m_indexOffset = index;
-    if (m_vBar)
-        m_vBar->setValue(index, Scrollbar::NotFromScrollAnimator);
+    
+    ScrollbarClient::scrollToYOffsetWithoutAnimation(index);
 }
 
 bool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
diff --git a/Source/WebCore/rendering/RenderListBox.h b/Source/WebCore/rendering/RenderListBox.h
index 243fcbe..f768247 100644
--- a/Source/WebCore/rendering/RenderListBox.h
+++ b/Source/WebCore/rendering/RenderListBox.h
@@ -96,8 +96,8 @@ private:
 
     // ScrollbarClient interface.
     virtual int scrollSize(ScrollbarOrientation orientation) const;
-    virtual void setScrollOffsetFromAnimation(const IntPoint&);
-    virtual void valueChanged(Scrollbar*);
+    virtual int scrollPosition(Scrollbar*) const;
+    virtual void setScrollOffset(const IntPoint&);
     virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
     virtual bool isActive() const;
     virtual bool scrollbarCornerPresent() const { return false; } // We don't support resize on list boxes yet.  If we did this would have to change.
@@ -105,6 +105,10 @@ private:
     virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar*, const IntRect&) const;
     virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar*, const IntPoint&) const;
     virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar*, const IntPoint&) const;
+    virtual Scrollbar* verticalScrollbar() const { return m_vBar.get(); }
+
+    // NOTE: This should only be called by the overriden setScrollOffset from ScrollbarClient.
+    void scrollTo(int newOffset);
 
     void setHasVerticalScrollbar(bool hasScrollbar);
     PassRefPtr<Scrollbar> createScrollbar();
diff --git a/Source/WebCore/rendering/RenderMarquee.cpp b/Source/WebCore/rendering/RenderMarquee.cpp
index 1c08831..9b58118 100644
--- a/Source/WebCore/rendering/RenderMarquee.cpp
+++ b/Source/WebCore/rendering/RenderMarquee.cpp
@@ -171,9 +171,9 @@ void RenderMarquee::start()
 
     if (!m_suspended && !m_stopped) {
         if (isHorizontal())
-            m_layer->scrollToOffset(m_start, 0, false, false);
+            m_layer->scrollToOffset(m_start, 0);
         else
-            m_layer->scrollToOffset(0, m_start, false, false);
+            m_layer->scrollToOffset(0, m_start);
     }
     else {
         m_suspended = false;
diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog
index 83c14bd..8b92aa3 100644
--- a/Source/WebKit/chromium/ChangeLog
+++ b/Source/WebKit/chromium/ChangeLog
@@ -1,3 +1,23 @@
+2011-01-20  Sam Weinig  <sam at webkit.org>
+
+        Reviewed by Dave Hyatt.
+
+        Cleanup Scrollbar/ScrollbarClient relationship
+        https://bugs.webkit.org/show_bug.cgi?id=52779
+
+        * src/WebScrollbarImpl.cpp:
+        (WebKit::WebScrollbarImpl::WebScrollbarImpl):
+        (WebKit::WebScrollbarImpl::value):
+        (WebKit::WebScrollbarImpl::setValue):
+        (WebKit::WebScrollbarImpl::scroll):
+        (WebKit::WebScrollbarImpl::onMouseDown):
+        (WebKit::WebScrollbarImpl::onMouseMove):
+        (WebKit::WebScrollbarImpl::onMouseWheel):
+        (WebKit::WebScrollbarImpl::onKeyDown):
+        (WebKit::WebScrollbarImpl::scrollPosition):
+        (WebKit::WebScrollbarImpl::setScrollOffset):
+        * src/WebScrollbarImpl.h:
+
 2011-01-20  James Robinson  <jamesr at chromium.org>
 
         Reviewed by Darin Fisher.
diff --git a/Source/WebKit/chromium/src/WebScrollbarImpl.cpp b/Source/WebKit/chromium/src/WebScrollbarImpl.cpp
index 8b9e287..527634a 100644
--- a/Source/WebKit/chromium/src/WebScrollbarImpl.cpp
+++ b/Source/WebKit/chromium/src/WebScrollbarImpl.cpp
@@ -62,6 +62,7 @@ int WebScrollbar::defaultThickness()
 
 WebScrollbarImpl::WebScrollbarImpl(WebScrollbarClient* client, Orientation orientation)
     : m_client(client)
+    , m_scrollOffset(0)
 {
     m_scrollbar = Scrollbar::createNativeScrollbar(
         static_cast<ScrollbarClient*>(this),
@@ -89,12 +90,12 @@ void WebScrollbarImpl::setLocation(const WebRect& rect)
 
 int WebScrollbarImpl::value() const
 {
-    return m_scrollbar->value();
+    return m_scrollOffset;
 }
 
 void WebScrollbarImpl::setValue(int position)
 {
-    m_scrollbar->setValue(position, Scrollbar::NotFromScrollAnimator);
+    WebCore::ScrollbarClient::scrollToOffsetWithoutAnimation(m_scrollbar->orientation(), position);
 }
 
 void WebScrollbarImpl::setDocumentSize(int size)
@@ -112,7 +113,8 @@ void WebScrollbarImpl::scroll(ScrollDirection direction, ScrollGranularity granu
         dir = horizontal ? ScrollRight : ScrollDown;
     else
         dir = horizontal ? ScrollLeft : ScrollUp;
-    m_scrollbar->scroll(dir, static_cast<WebCore::ScrollGranularity>(granularity), multiplier);
+
+    WebCore::ScrollbarClient::scroll(dir, static_cast<WebCore::ScrollGranularity>(granularity), multiplier);
 }
 
 void WebScrollbarImpl::paint(WebCanvas* canvas, const WebRect& rect)
@@ -167,11 +169,11 @@ bool WebScrollbarImpl::onMouseDown(const WebInputEvent& event)
     if (!m_scrollbar->frameRect().contains(mousedown.x, mousedown.y))
         return false;
 
-            mousedown.x -= m_scrollbar->x();
-            mousedown.y -= m_scrollbar->y();
-            m_scrollbar->mouseDown(PlatformMouseEventBuilder(m_scrollbar.get(), mousedown));
-            return true;
-        }
+    mousedown.x -= m_scrollbar->x();
+    mousedown.y -= m_scrollbar->y();
+    m_scrollbar->mouseDown(PlatformMouseEventBuilder(m_scrollbar.get(), mousedown));
+    return true;
+}
 
 bool WebScrollbarImpl::onMouseUp(const WebInputEvent& event)
 {
@@ -183,16 +185,16 @@ bool WebScrollbarImpl::onMouseUp(const WebInputEvent& event)
 
 bool WebScrollbarImpl::onMouseMove(const WebInputEvent& event)
 {
-        WebMouseEvent mousemove = *static_cast<const WebMouseEvent*>(&event);
-        if (m_scrollbar->frameRect().contains(mousemove.x, mousemove.y)
-            || m_scrollbar->pressedPart() != NoPart) {
-            mousemove.x -= m_scrollbar->x();
-            mousemove.y -= m_scrollbar->y();
-            return m_scrollbar->mouseMoved(PlatformMouseEventBuilder(m_scrollbar.get(), mousemove));
-        }
+    WebMouseEvent mousemove = *static_cast<const WebMouseEvent*>(&event);
+    if (m_scrollbar->frameRect().contains(mousemove.x, mousemove.y)
+        || m_scrollbar->pressedPart() != NoPart) {
+        mousemove.x -= m_scrollbar->x();
+        mousemove.y -= m_scrollbar->y();
+        return m_scrollbar->mouseMoved(PlatformMouseEventBuilder(m_scrollbar.get(), mousemove));
+    }
 
-        if (m_scrollbar->hoveredPart() != NoPart)
-            m_scrollbar->mouseExited();
+    if (m_scrollbar->hoveredPart() != NoPart)
+        m_scrollbar->mouseExited();
     return false;
 }
 
@@ -206,59 +208,59 @@ bool WebScrollbarImpl::onMouseLeave(const WebInputEvent& event)
 
 bool WebScrollbarImpl::onMouseWheel(const WebInputEvent& event)
 {
-        // Same logic as in Scrollview.cpp.  If we can move at all, we'll accept the event.
-        WebMouseWheelEvent mousewheel = *static_cast<const WebMouseWheelEvent*>(&event);
-        int maxScrollDelta = m_scrollbar->maximum() - m_scrollbar->value();
-        float delta = m_scrollbar->orientation() == HorizontalScrollbar ? mousewheel.deltaX : mousewheel.deltaY;
-        if ((delta < 0 && maxScrollDelta > 0) || (delta > 0 && m_scrollbar->value() > 0)) {
-            if (mousewheel.scrollByPage) {
-                ASSERT(m_scrollbar->orientation() == VerticalScrollbar);
-                bool negative = delta < 0;
-                delta = max(max(static_cast<float>(m_scrollbar->visibleSize()) * Scrollbar::minFractionToStepWhenPaging(), static_cast<float>(m_scrollbar->visibleSize() - Scrollbar::maxOverlapBetweenPages())), 1.0f);
-                if (negative)
-                    delta *= -1;
-            }
-            m_scrollbar->scroll((m_scrollbar->orientation() == HorizontalScrollbar) ? WebCore::ScrollLeft : WebCore::ScrollUp, WebCore::ScrollByPixel, delta);
-            return true;
+    // Same logic as in Scrollview.cpp.  If we can move at all, we'll accept the event.
+    WebMouseWheelEvent mousewheel = *static_cast<const WebMouseWheelEvent*>(&event);
+    int maxScrollDelta = m_scrollbar->maximum() - m_scrollbar->value();
+    float delta = m_scrollbar->orientation() == HorizontalScrollbar ? mousewheel.deltaX : mousewheel.deltaY;
+    if ((delta < 0 && maxScrollDelta > 0) || (delta > 0 && m_scrollbar->value() > 0)) {
+        if (mousewheel.scrollByPage) {
+            ASSERT(m_scrollbar->orientation() == VerticalScrollbar);
+            bool negative = delta < 0;
+            delta = max(max(static_cast<float>(m_scrollbar->visibleSize()) * Scrollbar::minFractionToStepWhenPaging(), static_cast<float>(m_scrollbar->visibleSize() - Scrollbar::maxOverlapBetweenPages())), 1.0f);
+            if (negative)
+                delta *= -1;
         }
+        WebCore::ScrollbarClient::scroll((m_scrollbar->orientation() == HorizontalScrollbar) ? WebCore::ScrollLeft : WebCore::ScrollUp, WebCore::ScrollByPixel, delta);
+        return true;
+    }
 
     return false;
     }
 
 bool WebScrollbarImpl::onKeyDown(const WebInputEvent& event)
 {
-        WebKeyboardEvent keyboard = *static_cast<const WebKeyboardEvent*>(&event);
-        int keyCode;
-        // We have to duplicate this logic from WebViewImpl because there it uses
-        // Char and RawKeyDown events, which don't exist at this point.
-        if (keyboard.windowsKeyCode == VKEY_SPACE)
-            keyCode = ((keyboard.modifiers & WebInputEvent::ShiftKey) ? VKEY_PRIOR : VKEY_NEXT);
-        else {
-            if (keyboard.modifiers == WebInputEvent::ControlKey) {
-                // Match FF behavior in the sense that Ctrl+home/end are the only Ctrl
-                // key combinations which affect scrolling. Safari is buggy in the
-                // sense that it scrolls the page for all Ctrl+scrolling key
-                // combinations. For e.g. Ctrl+pgup/pgdn/up/down, etc.
-                switch (keyboard.windowsKeyCode) {
-                case VKEY_HOME:
-                case VKEY_END:
-                    break;
-                default:
-                    return false;
-                }
+    WebKeyboardEvent keyboard = *static_cast<const WebKeyboardEvent*>(&event);
+    int keyCode;
+    // We have to duplicate this logic from WebViewImpl because there it uses
+    // Char and RawKeyDown events, which don't exist at this point.
+    if (keyboard.windowsKeyCode == VKEY_SPACE)
+        keyCode = ((keyboard.modifiers & WebInputEvent::ShiftKey) ? VKEY_PRIOR : VKEY_NEXT);
+    else {
+        if (keyboard.modifiers == WebInputEvent::ControlKey) {
+            // Match FF behavior in the sense that Ctrl+home/end are the only Ctrl
+            // key combinations which affect scrolling. Safari is buggy in the
+            // sense that it scrolls the page for all Ctrl+scrolling key
+            // combinations. For e.g. Ctrl+pgup/pgdn/up/down, etc.
+            switch (keyboard.windowsKeyCode) {
+            case VKEY_HOME:
+            case VKEY_END:
+                break;
+            default:
+                return false;
             }
+        }
 
-            if (keyboard.isSystemKey || (keyboard.modifiers & WebInputEvent::ShiftKey))
-                return false;
+        if (keyboard.isSystemKey || (keyboard.modifiers & WebInputEvent::ShiftKey))
+            return false;
 
-            keyCode = keyboard.windowsKeyCode;
-        }
-        WebCore::ScrollDirection scrollDirection;
-        WebCore::ScrollGranularity scrollGranularity;
-        if (WebViewImpl::mapKeyCodeForScroll(keyCode, &scrollDirection, &scrollGranularity)) {
-            // Will return false if scroll direction wasn't compatible with this scrollbar.
-            return m_scrollbar->scroll(scrollDirection, scrollGranularity);
-        }
+        keyCode = keyboard.windowsKeyCode;
+    }
+    WebCore::ScrollDirection scrollDirection;
+    WebCore::ScrollGranularity scrollGranularity;
+    if (WebViewImpl::mapKeyCodeForScroll(keyCode, &scrollDirection, &scrollGranularity)) {
+        // Will return false if scroll direction wasn't compatible with this scrollbar.
+        return WebCore::ScrollbarClient::scroll(scrollDirection, scrollGranularity);
+    }
     return false;
 }
 
@@ -267,13 +269,18 @@ int WebScrollbarImpl::scrollSize(WebCore::ScrollbarOrientation orientation) cons
     return (orientation == m_scrollbar->orientation()) ? (m_scrollbar->totalSize() - m_scrollbar->visibleSize()) : 0;
 }
 
-void WebScrollbarImpl::setScrollOffsetFromAnimation(const WebCore::IntPoint& offset)
+int WebScrollbarImpl::scrollPosition(WebCore::Scrollbar*) const
 {
-    m_scrollbar->setValue((m_scrollbar->orientation() == HorizontalScrollbar) ? offset.x() : offset.y(), Scrollbar::FromScrollAnimator);
+    return m_scrollOffset;
 }
 
-void WebScrollbarImpl::valueChanged(WebCore::Scrollbar*)
+void WebScrollbarImpl::setScrollOffset(const WebCore::IntPoint& offset)
 {
+    if (m_scrollbar->orientation() == HorizontalScrollbar)
+        m_scrollOffset = offset.x();
+    else
+        m_scrollOffset = offset.y();
+
     m_client->valueChanged(this);
 }
 
diff --git a/Source/WebKit/chromium/src/WebScrollbarImpl.h b/Source/WebKit/chromium/src/WebScrollbarImpl.h
index 5512867..71b6dca 100644
--- a/Source/WebKit/chromium/src/WebScrollbarImpl.h
+++ b/Source/WebKit/chromium/src/WebScrollbarImpl.h
@@ -58,9 +58,9 @@ public:
     virtual bool handleInputEvent(const WebInputEvent&);
 
     // WebCore::ScrollbarClient methods
-    virtual int scrollSize(WebCore::ScrollbarOrientation orientation) const;
-    virtual void setScrollOffsetFromAnimation(const WebCore::IntPoint&);
-    virtual void valueChanged(WebCore::Scrollbar*);
+    virtual int scrollSize(WebCore::ScrollbarOrientation) const;
+    virtual int scrollPosition(WebCore::Scrollbar*) const;
+    virtual void setScrollOffset(const WebCore::IntPoint&);
     virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&);
     virtual bool isActive() const;
     virtual bool scrollbarCornerPresent() const;
@@ -76,6 +76,7 @@ private:
 
     WebScrollbarClient* m_client;
 
+    int m_scrollOffset;
     RefPtr<WebCore::Scrollbar> m_scrollbar;
 };
 
diff --git a/Source/WebKit/qt/Api/qwebframe.cpp b/Source/WebKit/qt/Api/qwebframe.cpp
index 9c89a4c..6305b86 100644
--- a/Source/WebKit/qt/Api/qwebframe.cpp
+++ b/Source/WebKit/qt/Api/qwebframe.cpp
@@ -1071,7 +1071,7 @@ void QWebFrame::setScrollBarValue(Qt::Orientation orientation, int value)
             value = 0;
         else if (value > scrollBarMaximum(orientation))
             value = scrollBarMaximum(orientation);
-        sb->setValue(value, Scrollbar::NotFromScrollAnimator);
+        ScrollbarClient::scrollToOffsetWithoutAnimation(orientation == Qt::Horizontal ? HorizontalScrollbar : VerticalScrollbar, position);
     }
 }
 
diff --git a/Source/WebKit/qt/ChangeLog b/Source/WebKit/qt/ChangeLog
index ffd1ae6..5bb8400 100644
--- a/Source/WebKit/qt/ChangeLog
+++ b/Source/WebKit/qt/ChangeLog
@@ -1,3 +1,13 @@
+2011-01-20  Sam Weinig  <sam at webkit.org>
+
+        Reviewed by Dave Hyatt.
+
+        Cleanup Scrollbar/ScrollbarClient relationship
+        https://bugs.webkit.org/show_bug.cgi?id=52779
+
+        * Api/qwebframe.cpp:
+        (QWebFrame::setScrollBarValue):
+
 2011-01-19  Simon Fraser  <simon.fraser at apple.com>
 
         Reviewed by Sam Weinig.
diff --git a/Source/WebKit/win/ChangeLog b/Source/WebKit/win/ChangeLog
index 8f32e77..a5182fa 100644
--- a/Source/WebKit/win/ChangeLog
+++ b/Source/WebKit/win/ChangeLog
@@ -1,3 +1,19 @@
+2011-01-20  Sam Weinig  <sam at webkit.org>
+
+        Reviewed by Dave Hyatt.
+
+        Cleanup Scrollbar/ScrollbarClient relationship
+        https://bugs.webkit.org/show_bug.cgi?id=52779
+
+        * WebScrollBar.cpp:
+        (WebScrollBar::WebScrollBar):
+        (WebScrollBar::setValue):
+        (WebScrollBar::value):
+        (WebScrollBar::scroll):
+        (WebScrollBar::scrollPosition):
+        (WebScrollBar::setScrollOffset):
+        * WebScrollBar.h:
+
 2011-01-19  Adam Roben  <aroben at apple.com>
 
         Update for WKCACFLayerRenderer changes
diff --git a/Source/WebKit/win/WebScrollBar.cpp b/Source/WebKit/win/WebScrollBar.cpp
index 8613c1c..1f8cb84 100644
--- a/Source/WebKit/win/WebScrollBar.cpp
+++ b/Source/WebKit/win/WebScrollBar.cpp
@@ -42,6 +42,7 @@ using namespace WebCore;
 WebScrollBar::WebScrollBar()
     : m_refCount(0)
     , m_containingWindow(0)
+    , m_currentPosition(0)
 {
     gClassCount++;
     gClassNameCount.add("WebScrollBar");
@@ -143,7 +144,7 @@ HRESULT STDMETHODCALLTYPE WebScrollBar::setRect(
 HRESULT STDMETHODCALLTYPE WebScrollBar::setValue( 
     /* [in] */ int value)
 {
-    m_scrollBar->setValue(value, Scrollbar::NotFromScrollAnimator);
+    m_currentPosition = value;
     return S_OK;
 }
 
@@ -152,7 +153,7 @@ HRESULT STDMETHODCALLTYPE WebScrollBar::value(
 {
     if (!value)
         return E_POINTER;
-    *value = m_scrollBar->value();
+    *value = m_currentPosition;
     return S_OK;
 }
 
@@ -247,7 +248,7 @@ HRESULT STDMETHODCALLTYPE WebScrollBar::scroll(
 {
     ScrollDirection webCoreScrollDirection = (ScrollDirection) direction;
     ScrollGranularity webCoreGranularity = (ScrollGranularity) granularity;
-    m_scrollBar->scroll(webCoreScrollDirection, webCoreGranularity, multiplier);
+    ScrollbarClient::scroll(webCoreScrollDirection, webCoreGranularity, multiplier);
     return S_OK;
 }
 
@@ -257,17 +258,14 @@ int WebScrollBar::scrollSize(ScrollbarOrientation orientation) const
     return (orientation == m_scrollBar->orientation()) ? (m_scrollBar->totalSize() - m_scrollBar->visibleSize()) : 0; 
 }
 
-void WebScrollBar::setScrollOffsetFromAnimation(const IntPoint& offset)
+int WebScrollBar::scrollPosition(Scrollbar*) const
 {
-    m_scrollBar->setValue((m_scrollBar->orientation() == HorizontalScrollbar) ? offset.x() : offset.y(), Scrollbar::FromScrollAnimator);
+    return m_currentPosition;
 }
 
-void WebScrollBar::valueChanged(Scrollbar* scrollBar)
+void WebScrollBar::setScrollOffset(const IntPoint& offset)
 {
-    if (m_scrollBar != scrollBar) {
-        ASSERT(false);  // shouldn't happen
-        return;
-    }
+    m_currentPosition = (m_scrollBar->orientation() == HorizontalScrollbar) ? offset.x() : offset.y();
     m_delegate->valueChanged(this);
 }
 
diff --git a/Source/WebKit/win/WebScrollBar.h b/Source/WebKit/win/WebScrollBar.h
index 90f2491..d7d923b 100644
--- a/Source/WebKit/win/WebScrollBar.h
+++ b/Source/WebKit/win/WebScrollBar.h
@@ -117,8 +117,8 @@ public:
 protected:
     // ScrollbarClient
     virtual int scrollSize(ScrollbarOrientation orientation) const;
-    virtual void setScrollOffsetFromAnimation(const IntPoint&);
-    virtual void valueChanged(Scrollbar*);
+    virtual int scrollPosition(Scrollbar*) const;
+    virtual void setScrollOffset(const IntPoint&);
     virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
 
     // FIXME: We should provide a way to set this value.
@@ -128,6 +128,7 @@ protected:
 
     ULONG m_refCount;
     HWND m_containingWindow;
+    int m_currentPosition;
     RefPtr<WebCore::Scrollbar> m_scrollBar;
     COMPtr<IWebScrollBarDelegatePrivate> m_delegate;
 };
diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog
index e9c3ffb..5339117 100644
--- a/Source/WebKit2/ChangeLog
+++ b/Source/WebKit2/ChangeLog
@@ -1,3 +1,19 @@
+2011-01-20  Sam Weinig  <sam at webkit.org>
+
+        Reviewed by Dave Hyatt.
+
+        Cleanup Scrollbar/ScrollbarClient relationship
+        https://bugs.webkit.org/show_bug.cgi?id=52779
+
+        * UIProcess/win/WebPopupMenuProxyWin.cpp:
+        (WebKit::WebPopupMenuProxyWin::scrollPosition):
+        (WebKit::WebPopupMenuProxyWin::setScrollOffset):
+        (WebKit::WebPopupMenuProxyWin::scrollTo):
+        (WebKit::WebPopupMenuProxyWin::onMouseWheel):
+        (WebKit::WebPopupMenuProxyWin::scrollToRevealSelection):
+        * UIProcess/win/WebPopupMenuProxyWin.h:
+        (WebKit::WebPopupMenuProxyWin::verticalScrollbar):
+
 2011-01-20  Anders Carlsson  <andersca at apple.com>
 
         Reviewed by Adam Roben.
diff --git a/Source/WebKit2/UIProcess/win/WebPopupMenuProxyWin.cpp b/Source/WebKit2/UIProcess/win/WebPopupMenuProxyWin.cpp
index 64b9fb5..ae97ab8 100644
--- a/Source/WebKit2/UIProcess/win/WebPopupMenuProxyWin.cpp
+++ b/Source/WebKit2/UIProcess/win/WebPopupMenuProxyWin.cpp
@@ -439,21 +439,23 @@ int WebPopupMenuProxyWin::scrollSize(ScrollbarOrientation orientation) const
     return ((orientation == VerticalScrollbar) && m_scrollbar) ? (m_scrollbar->totalSize() - m_scrollbar->visibleSize()) : 0;
 }
 
-void WebPopupMenuProxyWin::setScrollOffsetFromAnimation(const IntPoint& offset)
+int WebPopupMenuProxyWin::scrollPosition(Scrollbar*) const
 {
-    if (m_scrollbar)
-        m_scrollbar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+    return m_scrollOffset;
+}
+
+void WebPopupMenuProxyWin::setScrollOffset(const IntPoint& offset)
+{
+    scrollTo(offset.y());
 }
 
-void WebPopupMenuProxyWin::valueChanged(Scrollbar* scrollBar)
+void WebPopupMenuProxyWin::scrollTo(int offset)
 {
     ASSERT(m_scrollbar);
 
     if (!m_popup)
         return;
 
-    int offset = scrollBar->value();
-
     if (m_scrollOffset == offset)
         return;
 
@@ -720,7 +722,8 @@ LRESULT WebPopupMenuProxyWin::onMouseWheel(HWND hWnd, UINT message, WPARAM wPara
         else
             --i;
     }
-    scrollbar()->scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i));
+
+    ScrollbarClient::scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i));
     return 0;
 }
 
@@ -922,12 +925,12 @@ bool WebPopupMenuProxyWin::scrollToRevealSelection()
     int index = focusedIndex();
 
     if (index < m_scrollOffset) {
-        m_scrollbar->setValue(index, Scrollbar::NotFromScrollAnimator);
+        ScrollbarClient::scrollToYOffsetWithoutAnimation(index);
         return true;
     }
 
     if (index >= m_scrollOffset + visibleItems()) {
-        m_scrollbar->setValue(index - visibleItems() + 1, Scrollbar::NotFromScrollAnimator);
+        ScrollbarClient::scrollToYOffsetWithoutAnimation(index - visibleItems() + 1);
         return true;
     }
 
diff --git a/Source/WebKit2/UIProcess/win/WebPopupMenuProxyWin.h b/Source/WebKit2/UIProcess/win/WebPopupMenuProxyWin.h
index 7a53c2c..0ed69e2 100644
--- a/Source/WebKit2/UIProcess/win/WebPopupMenuProxyWin.h
+++ b/Source/WebKit2/UIProcess/win/WebPopupMenuProxyWin.h
@@ -60,11 +60,15 @@ private:
 
     // ScrollBarClient
     virtual int scrollSize(WebCore::ScrollbarOrientation orientation) const;
-    virtual void setScrollOffsetFromAnimation(const WebCore::IntPoint&);
-    virtual void valueChanged(WebCore::Scrollbar*);
+    virtual int scrollPosition(WebCore::Scrollbar*) const;
+    virtual void setScrollOffset(const WebCore::IntPoint&);
     virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&);
     virtual bool isActive() const { return true; }
     virtual bool scrollbarCornerPresent() const { return false; }
+    virtual WebCore::Scrollbar* verticalScrollbar() const { return m_scrollbar.get(); }
+
+    // NOTE: This should only be called by the overriden setScrollOffset from ScrollbarClient.
+    void scrollTo(int offset);
 
     static bool registerWindowClass();
     static LRESULT CALLBACK WebPopupMenuProxyWndProc(HWND, UINT, WPARAM, LPARAM);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list