Changeset 173894 in webkit


Ignore:
Timestamp:
Sep 23, 2014 3:16:25 PM (10 years ago)
Author:
Brent Fulgham
Message:

Implement snapping behavior for Mac overflow scrolling
https://bugs.webkit.org/show_bug.cgi?id=135774

Patch by Wenson Hsieh <Wenson Hsieh> on 2014-09-22
Reviewed by Beth Dakin.

Hooks into AxisScrollSnapAnimator to implement overflow scroll snapping on Mac.

We need to find a way to test this!

  • dom/Element.cpp:

(WebCore::Element::dispatchWheelEvent):

  • page/EventHandler.cpp:

(WebCore::handleWheelEventInAppropriateEnclosingBoxForSingleAxis):

  • platform/ScrollAnimator.cpp:

(WebCore::ScrollAnimator::handleWheelEvent):
(WebCore::ScrollAnimator::updateScrollAnimatorsAndTimers):
(WebCore::ScrollAnimator::scrollOffsetInAxis):
(WebCore::ScrollAnimator::immediateScrollInAxis):
(WebCore::ScrollAnimator::startScrollSnapTimer):
(WebCore::ScrollAnimator::stopScrollSnapTimer):
(WebCore::ScrollAnimator::horizontalScrollSnapTimerFired):
(WebCore::ScrollAnimator::verticalScrollSnapTimerFired):

  • platform/ScrollAnimator.h:
  • platform/mac/AxisScrollSnapAnimator.h:
  • platform/mac/AxisScrollSnapAnimator.mm:

(WebCore::AxisScrollSnapAnimator::AxisScrollSnapAnimator):
(WebCore::AxisScrollSnapAnimator::beginScrollSnapAnimation):
(WebCore::AxisScrollSnapAnimator::endScrollSnapAnimation):
(WebCore::AxisScrollSnapAnimator::initializeGlideParameters):

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::updateScrollInfoAfterLayout):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r173893 r173894  
     12014-09-22  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Implement snapping behavior for Mac overflow scrolling
     4        https://bugs.webkit.org/show_bug.cgi?id=135774
     5
     6        Reviewed by Beth Dakin.
     7
     8        Hooks into AxisScrollSnapAnimator to implement overflow scroll snapping on Mac.
     9
     10        We need to find a way to test this!
     11
     12        * dom/Element.cpp:
     13        (WebCore::Element::dispatchWheelEvent):
     14        * page/EventHandler.cpp:
     15        (WebCore::handleWheelEventInAppropriateEnclosingBoxForSingleAxis):
     16        * platform/ScrollAnimator.cpp:
     17        (WebCore::ScrollAnimator::handleWheelEvent):
     18        (WebCore::ScrollAnimator::updateScrollAnimatorsAndTimers):
     19        (WebCore::ScrollAnimator::scrollOffsetInAxis):
     20        (WebCore::ScrollAnimator::immediateScrollInAxis):
     21        (WebCore::ScrollAnimator::startScrollSnapTimer):
     22        (WebCore::ScrollAnimator::stopScrollSnapTimer):
     23        (WebCore::ScrollAnimator::horizontalScrollSnapTimerFired):
     24        (WebCore::ScrollAnimator::verticalScrollSnapTimerFired):
     25        * platform/ScrollAnimator.h:
     26        * platform/mac/AxisScrollSnapAnimator.h:
     27        * platform/mac/AxisScrollSnapAnimator.mm:
     28        (WebCore::AxisScrollSnapAnimator::AxisScrollSnapAnimator):
     29        (WebCore::AxisScrollSnapAnimator::beginScrollSnapAnimation):
     30        (WebCore::AxisScrollSnapAnimator::endScrollSnapAnimation):
     31        (WebCore::AxisScrollSnapAnimator::initializeGlideParameters):
     32        * rendering/RenderLayer.cpp:
     33        (WebCore::RenderLayer::updateScrollInfoAfterLayout):
     34
    1352014-09-23  Chris Dumez  <cdumez@apple.com>
    236
  • trunk/Source/WebCore/platform/ScrollAnimator.cpp

    r172182 r173894  
    8383bool ScrollAnimator::handleWheelEvent(const PlatformWheelEvent& e)
    8484{
     85#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
     86    if (m_verticalScrollSnapAnimator) {
     87        m_verticalScrollSnapAnimator->handleWheelEvent(e);
     88        if (m_verticalScrollSnapAnimator->shouldOverrideWheelEvent(e))
     89            return false;
     90    }
     91    if (m_horizontalScrollSnapAnimator) {
     92        m_horizontalScrollSnapAnimator->handleWheelEvent(e);
     93        if (m_horizontalScrollSnapAnimator->shouldOverrideWheelEvent(e))
     94            return false;
     95    }
     96#endif
    8597#if PLATFORM(COCOA)
    8698    // Events in the PlatformWheelEventPhaseMayBegin phase have no deltas, and therefore never passes through the scroll handling logic below.
     
    159171}
    160172
     173#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
     174void ScrollAnimator::updateScrollAnimatorsAndTimers()
     175{
     176    // FIXME: Currently, scroll snap animators are recreated even though the snap offsets alone can be updated.
     177    if (m_scrollableArea->horizontalSnapOffsets()) {
     178        m_horizontalScrollSnapAnimator = std::make_unique<AxisScrollSnapAnimator>(this, m_scrollableArea->horizontalSnapOffsets(), ScrollEventAxis::Horizontal);
     179        m_horizontalScrollSnapTimer = std::make_unique<Timer<ScrollAnimator>>(this, &ScrollAnimator::horizontalScrollSnapTimerFired);
     180    } else if (m_horizontalScrollSnapAnimator) {
     181        m_horizontalScrollSnapAnimator = nullptr;
     182        m_horizontalScrollSnapTimer = nullptr;
     183    }
     184    if (m_scrollableArea->verticalSnapOffsets()) {
     185        m_verticalScrollSnapAnimator = std::make_unique<AxisScrollSnapAnimator>(this, m_scrollableArea->verticalSnapOffsets(), ScrollEventAxis::Vertical);
     186        m_verticalScrollSnapTimer = std::make_unique<Timer<ScrollAnimator>>(this, &ScrollAnimator::verticalScrollSnapTimerFired);
     187    } else if (m_verticalScrollSnapAnimator) {
     188        m_verticalScrollSnapAnimator = nullptr;
     189        m_verticalScrollSnapTimer = nullptr;
     190    }
     191}
     192
     193LayoutUnit ScrollAnimator::scrollOffsetInAxis(ScrollEventAxis axis)
     194{
     195    FloatPoint currentPosition = this->currentPosition();
     196    return axis == ScrollEventAxis::Horizontal ? currentPosition.x() : currentPosition.y();
     197}
     198
     199void ScrollAnimator::immediateScrollInAxis(ScrollEventAxis axis, float delta)
     200{
     201    FloatPoint currentPosition = this->currentPosition();
     202    if (axis == ScrollEventAxis::Horizontal)
     203        scrollToOffsetWithoutAnimation(FloatPoint(currentPosition.x() + delta, currentPosition.y()));
     204    else
     205        scrollToOffsetWithoutAnimation(FloatPoint(currentPosition.x(), currentPosition.y() + delta));
     206}
     207
     208void ScrollAnimator::startScrollSnapTimer(ScrollEventAxis axis)
     209{
     210    Timer<ScrollAnimator>* scrollSnapTimer = axis == ScrollEventAxis::Horizontal ? m_horizontalScrollSnapTimer.get() : m_verticalScrollSnapTimer.get();
     211    if (!scrollSnapTimer->isActive())
     212        scrollSnapTimer->startRepeating(1.0 / 60.0);
     213}
     214
     215void ScrollAnimator::stopScrollSnapTimer(ScrollEventAxis axis)
     216{
     217    Timer<ScrollAnimator>* scrollSnapTimer = axis == ScrollEventAxis::Horizontal ? m_horizontalScrollSnapTimer.get() : m_verticalScrollSnapTimer.get();
     218    if (scrollSnapTimer->isActive())
     219        scrollSnapTimer->stop();
     220}
     221
     222void ScrollAnimator::horizontalScrollSnapTimerFired(Timer<ScrollAnimator>&)
     223{
     224    m_horizontalScrollSnapAnimator->scrollSnapAnimationUpdate();
     225}
     226
     227void ScrollAnimator::verticalScrollSnapTimerFired(Timer<ScrollAnimator>&)
     228{
     229    m_verticalScrollSnapAnimator->scrollSnapAnimationUpdate();
     230}
     231#endif
     232
    161233} // namespace WebCore
  • trunk/Source/WebCore/platform/ScrollAnimator.h

    r163657 r173894  
    3838#include <wtf/Forward.h>
    3939
     40#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
     41#include "AxisScrollSnapAnimator.h"
     42#include "Timer.h"
     43#endif
     44
    4045namespace WebCore {
    4146
     
    4550class Scrollbar;
    4651
     52#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
     53class ScrollAnimator : public AxisScrollSnapAnimatorClient {
     54#else
    4755class ScrollAnimator {
     56#endif
    4857    WTF_MAKE_FAST_ALLOCATED;
    4958public:
     
    107116    virtual bool isRubberBandInProgress() const { return false; }
    108117
     118#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
     119    void updateScrollAnimatorsAndTimers();
     120    virtual LayoutUnit scrollOffsetInAxis(ScrollEventAxis) override;
     121    virtual void immediateScrollInAxis(ScrollEventAxis, float delta) override;
     122    virtual void startScrollSnapTimer(ScrollEventAxis) override;
     123    virtual void stopScrollSnapTimer(ScrollEventAxis) override;
     124#endif
     125
    109126protected:
    110127    explicit ScrollAnimator(ScrollableArea*);
     
    112129    virtual void notifyPositionChanged(const FloatSize& delta);
    113130
     131#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
     132    // Trivial wrappers around the actual update loop in AxisScrollSnapAnimator, since WebCore Timer requires a Timer argument.
     133    void horizontalScrollSnapTimerFired(Timer<ScrollAnimator>&);
     134    void verticalScrollSnapTimerFired(Timer<ScrollAnimator>&);
     135#endif
     136
    114137    ScrollableArea* m_scrollableArea;
    115138    float m_currentPosX; // We avoid using a FloatPoint in order to reduce
    116139    float m_currentPosY; // subclass code complexity.
     140#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
     141    std::unique_ptr<AxisScrollSnapAnimator> m_horizontalScrollSnapAnimator;
     142    std::unique_ptr<Timer<ScrollAnimator>> m_horizontalScrollSnapTimer;
     143    // FIXME: Find a way to consolidate both timers into one variable.
     144    std::unique_ptr<AxisScrollSnapAnimator> m_verticalScrollSnapAnimator;
     145    std::unique_ptr<Timer<ScrollAnimator>> m_verticalScrollSnapTimer;
     146#endif
    117147};
    118148
  • trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.h

    r172659 r173894  
    6060    virtual LayoutUnit scrollOffsetInAxis(ScrollEventAxis) = 0;
    6161    virtual void immediateScrollInAxis(ScrollEventAxis, float velocity) = 0;
    62     virtual void startScrollSnapTimer() = 0;
    63     virtual void stopScrollSnapTimer() = 0;
     62    virtual void startScrollSnapTimer(ScrollEventAxis) = 0;
     63    virtual void stopScrollSnapTimer(ScrollEventAxis) = 0;
    6464};
    6565
    6666class AxisScrollSnapAnimator {
    6767public:
    68     AxisScrollSnapAnimator(AxisScrollSnapAnimatorClient*, Vector<LayoutUnit>* snapOffsets, ScrollEventAxis);
     68    AxisScrollSnapAnimator(AxisScrollSnapAnimatorClient*, const Vector<LayoutUnit>* snapOffsets, ScrollEventAxis);
    6969    void handleWheelEvent(const PlatformWheelEvent&);
    7070    bool shouldOverrideWheelEvent(const PlatformWheelEvent&) const;
     
    8686
    8787    AxisScrollSnapAnimatorClient* m_client;
    88     Vector<LayoutUnit>* m_snapOffsets;
     88    const Vector<LayoutUnit>* m_snapOffsets;
    8989    ScrollEventAxis m_axis;
    9090    // Used to track both snapping and gliding behaviors.
  • trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.mm

    r172659 r173894  
    8383}
    8484
    85 AxisScrollSnapAnimator::AxisScrollSnapAnimator(AxisScrollSnapAnimatorClient* client, Vector<LayoutUnit>* snapOffsets, ScrollEventAxis axis)
     85AxisScrollSnapAnimator::AxisScrollSnapAnimator(AxisScrollSnapAnimatorClient* client, const Vector<LayoutUnit>* snapOffsets, ScrollEventAxis axis)
    8686    : m_client(client)
    8787    , m_snapOffsets(snapOffsets)
     
    185185        clearInitialWheelDeltaWindow();
    186186    }
    187     m_client->startScrollSnapTimer();
     187    m_client->startScrollSnapTimer(m_axis);
    188188}
    189189
     
    195195
    196196    m_currentState = newState;
    197     m_client->stopScrollSnapTimer();
     197    m_client->stopScrollSnapTimer(m_axis);
    198198}
    199199
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r173865 r173894  
    33833383    // https://bugs.webkit.org/show_bug.cgi?id=135964
    33843384    updateSnapOffsets();
     3385#if PLATFORM(MAC)
     3386    if (existingScrollAnimator())
     3387        scrollAnimator()->updateScrollAnimatorsAndTimers();
     3388#endif
    33853389#endif
    33863390}
Note: See TracChangeset for help on using the changeset viewer.