⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 285953 in webkit


Ignore:
Timestamp:
Nov 17, 2021, 2:21:59 PM (5 years ago)
Author:
timothy_horton@apple.com
Message:

Momentum animator sometimes starts the animation at a very high velocity
https://bugs.webkit.org/show_bug.cgi?id=233245
<rdar://problem/85307115>

Reviewed by Simon Fraser.

Source/WebCore:

  • page/WheelEventDeltaFilter.cpp:

(WebCore::WheelEventDeltaFilter::eventCopyWithVelocity const):

  • page/WheelEventDeltaFilter.h:
  • platform/PlatformWheelEvent.h:

(WebCore::PlatformWheelEvent::copyWithVelocity const):
Make it possible to ask the delta filter to only add velocity data without filtering deltas.
We should later make ScrollingEffectsController talk directly to the
WheelEventDeltaFilter to get the velocity, but that requires a great
deal of scrolling thread plumbing.

  • page/mac/WheelEventDeltaFilterMac.h:
  • page/mac/WheelEventDeltaFilterMac.mm:

(WebCore::WheelEventDeltaFilterMac::updateFromEvent):
Factor updateCurrentVelocityFromEvent out.
Update the current velocity for momentum begin phase events as well.

(WebCore::WheelEventDeltaFilterMac::updateCurrentVelocityFromEvent):

  • platform/ScrollingEffectsController.h:
  • platform/mac/ScrollingEffectsController.mm:

(WebCore::ScrollingEffectsController::handleWheelEvent):
Start the momentum animation with the velocity provided by the momentum
begin phase, instead of a potentially incorrect delta from an earlier change phase.

Source/WebKit:

  • WebProcess/WebPage/EventDispatcher.cpp:

(WebKit::EventDispatcher::wheelEvent):
Ensure that wheel events always have velocities attached, even for
events that don't go through the delta filter.

Location:
trunk/Source
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r285949 r285953  
     12021-11-17  Tim Horton  <timothy_horton@apple.com>
     2
     3        Momentum animator sometimes starts the animation at a very high velocity
     4        https://bugs.webkit.org/show_bug.cgi?id=233245
     5        <rdar://problem/85307115>
     6
     7        Reviewed by Simon Fraser.
     8
     9        * page/WheelEventDeltaFilter.cpp:
     10        (WebCore::WheelEventDeltaFilter::eventCopyWithVelocity const):
     11        * page/WheelEventDeltaFilter.h:
     12        * platform/PlatformWheelEvent.h:
     13        (WebCore::PlatformWheelEvent::copyWithVelocity const):
     14        Make it possible to ask the delta filter to only add velocity data without filtering deltas.
     15        We should later make ScrollingEffectsController talk directly to the
     16        WheelEventDeltaFilter to get the velocity, but that requires a great
     17        deal of scrolling thread plumbing.
     18
     19        * page/mac/WheelEventDeltaFilterMac.h:
     20        * page/mac/WheelEventDeltaFilterMac.mm:
     21        (WebCore::WheelEventDeltaFilterMac::updateFromEvent):
     22        Factor updateCurrentVelocityFromEvent out.
     23        Update the current velocity for momentum begin phase events as well.
     24
     25        (WebCore::WheelEventDeltaFilterMac::updateCurrentVelocityFromEvent):
     26
     27        * platform/ScrollingEffectsController.h:
     28        * platform/mac/ScrollingEffectsController.mm:
     29        (WebCore::ScrollingEffectsController::handleWheelEvent):
     30        Start the momentum animation with the velocity provided by the momentum
     31        begin phase, instead of a potentially incorrect delta from an earlier change phase.
     32
    1332021-11-17  Wenson Hsieh  <wenson_hsieh@apple.com>
    234
  • trunk/Source/WebCore/page/WheelEventDeltaFilter.cpp

    r285787 r285953  
    6363}
    6464
     65bool WheelEventDeltaFilter::shouldIncludeVelocityForEvent(const PlatformWheelEvent& event)
     66{
     67#if ENABLE(KINETIC_SCROLLING)
     68    // Include velocity on momentum-began phases so that the momentum animator can use it.
     69    if (event.momentumPhase() == PlatformWheelEventPhase::Began)
     70        return true;
     71#endif
     72    return shouldApplyFilteringForEvent(event);
     73}
     74
    6575PlatformWheelEvent WheelEventDeltaFilter::eventCopyWithFilteredDeltas(const PlatformWheelEvent& event) const
    6676{
    6777    return event.copyWithDeltaAndVelocity(m_currentFilteredDelta, m_currentFilteredVelocity);
     78}
     79
     80PlatformWheelEvent WheelEventDeltaFilter::eventCopyWithVelocity(const PlatformWheelEvent& event) const
     81{
     82    return event.copyWithVelocity(m_currentFilteredVelocity);
    6883}
    6984
  • trunk/Source/WebCore/page/WheelEventDeltaFilter.h

    r285787 r285953  
    4444
    4545    WEBCORE_EXPORT PlatformWheelEvent eventCopyWithFilteredDeltas(const PlatformWheelEvent&) const;
     46    WEBCORE_EXPORT PlatformWheelEvent eventCopyWithVelocity(const PlatformWheelEvent&) const;
    4647
    4748    WEBCORE_EXPORT FloatSize filteredVelocity() const;
     
    4950
    5051    WEBCORE_EXPORT static bool shouldApplyFilteringForEvent(const PlatformWheelEvent&);
     52    WEBCORE_EXPORT static bool shouldIncludeVelocityForEvent(const PlatformWheelEvent&);
    5153
    5254protected:
  • trunk/Source/WebCore/page/mac/WheelEventDeltaFilterMac.h

    r285883 r285953  
    4646    void reset();
    4747
     48    void updateCurrentVelocityFromEvent(const PlatformWheelEvent&);
     49
    4850    RetainPtr<_NSScrollingPredominantAxisFilter> m_predominantAxisFilter;
    4951    WallTime m_initialWallTime;
  • trunk/Source/WebCore/page/mac/WheelEventDeltaFilterMac.mm

    r285883 r285953  
    4646{
    4747    if (event.momentumPhase() != PlatformWheelEventPhase::None) {
     48        if (event.momentumPhase() == PlatformWheelEventPhase::Began)
     49            updateCurrentVelocityFromEvent(event);
    4850        m_lastIOHIDEventTimestamp = event.ioHIDEventTimestamp();
    4951        return;
    5052    }
    51 
    52     // The absolute value of timestamp doesn't matter; the filter looks at deltas from the previous event.
    53     auto timestamp = event.timestamp() - m_initialWallTime;
    5453
    5554    switch (event.phase()) {
     
    6059    case PlatformWheelEventPhase::Began:
    6160        reset();
    62         FALLTHROUGH;
    63     case PlatformWheelEventPhase::Changed: {
    64         NSPoint filteredDeltaResult;
    65         NSPoint filteredVelocityResult;
     61        updateCurrentVelocityFromEvent(event);
     62        break;
    6663
    67         [m_predominantAxisFilter filterInputDelta:toFloatPoint(event.delta()) timestamp:timestamp.seconds() outputDelta:&filteredDeltaResult velocity:&filteredVelocityResult];
    68         auto axisFilteredVelocity = toFloatSize(filteredVelocityResult);
    69         m_currentFilteredDelta = toFloatSize(filteredDeltaResult);
     64    case PlatformWheelEventPhase::Changed:
     65        updateCurrentVelocityFromEvent(event);
     66        break;
    7067
    71         // Use a 1ms minimum to avoid divide by zero. The usual cadence of these events matches screen refresh rate.
    72         auto deltaFromLastEvent = std::max(event.ioHIDEventTimestamp() - m_lastIOHIDEventTimestamp, 1_ms);
    73         m_currentFilteredVelocity = event.delta() / deltaFromLastEvent.seconds();
    74 
    75         // Apply the axis-locking that m_predominantAxisFilter does.
    76         if (!axisFilteredVelocity.width())
    77             m_currentFilteredVelocity.setWidth(0);
    78         if (!axisFilteredVelocity.height())
    79             m_currentFilteredVelocity.setHeight(0);
    80 
    81         LOG(ScrollAnimations, "WheelEventDeltaFilterMac::updateFromEvent: _NSScrollingPredominantAxisFilter velocity %.2f, %2f, IOHIDEvent velocity %.2f,%.2f",
    82             axisFilteredVelocity.width(), axisFilteredVelocity.height(), m_currentFilteredVelocity.width(), m_currentFilteredVelocity.height());
    83         break;
    84     }
    8568    case PlatformWheelEventPhase::MayBegin:
    8669    case PlatformWheelEventPhase::Cancelled:
     
    9174
    9275    m_lastIOHIDEventTimestamp = event.ioHIDEventTimestamp();
     76}
     77
     78void WheelEventDeltaFilterMac::updateCurrentVelocityFromEvent(const PlatformWheelEvent& event)
     79{
     80    // The absolute value of timestamp doesn't matter; the filter looks at deltas from the previous event.
     81    auto timestamp = event.timestamp() - m_initialWallTime;
     82
     83    NSPoint filteredDeltaResult;
     84    NSPoint filteredVelocityResult;
     85
     86    [m_predominantAxisFilter filterInputDelta:toFloatPoint(event.delta()) timestamp:timestamp.seconds() outputDelta:&filteredDeltaResult velocity:&filteredVelocityResult];
     87    auto axisFilteredVelocity = toFloatSize(filteredVelocityResult);
     88    m_currentFilteredDelta = toFloatSize(filteredDeltaResult);
     89
     90    // Use a 1ms minimum to avoid divide by zero. The usual cadence of these events matches screen refresh rate.
     91    auto deltaFromLastEvent = std::max(event.ioHIDEventTimestamp() - m_lastIOHIDEventTimestamp, 1_ms);
     92    m_currentFilteredVelocity = event.delta() / deltaFromLastEvent.seconds();
     93
     94    // Apply the axis-locking that m_predominantAxisFilter does.
     95    if (!axisFilteredVelocity.width())
     96        m_currentFilteredVelocity.setWidth(0);
     97    if (!axisFilteredVelocity.height())
     98        m_currentFilteredVelocity.setHeight(0);
     99
     100    LOG(ScrollAnimations, "WheelEventDeltaFilterMac::updateFromEvent: _NSScrollingPredominantAxisFilter velocity %.2f, %2f, IOHIDEvent velocity %.2f,%.2f",
     101        axisFilteredVelocity.width(), axisFilteredVelocity.height(), m_currentFilteredVelocity.width(), m_currentFilteredVelocity.height());
    93102}
    94103
  • trunk/Source/WebCore/platform/PlatformWheelEvent.h

    r285790 r285953  
    130130    }
    131131
     132    PlatformWheelEvent copyWithVelocity(FloatSize velocity) const
     133    {
     134        PlatformWheelEvent copy = *this;
     135        copy.m_scrollingVelocity = velocity;
     136        return copy;
     137    }
     138
    132139    const IntPoint& position() const { return m_position; } // PlatformWindow coordinates.
    133140    const IntPoint& globalPosition() const { return m_globalPosition; } // Screen coordinates.
  • trunk/Source/WebCore/platform/ScrollingEffectsController.h

    r285917 r285953  
    261261    FloatSize m_momentumVelocity;
    262262
    263     FloatSize m_scrollingVelocityForMomentumAnimation; // Do we need both this, m_scrollingVelocityForScrollSnap and m_momentumVelocity?
    264263    FloatSize m_scrollingVelocityForScrollSnap;
    265264#if !LOG_DISABLED
  • trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm

    r285917 r285953  
    130130bool ScrollingEffectsController::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
    131131{
    132     if (WheelEventDeltaFilter::shouldApplyFilteringForEvent(wheelEvent))
    133         m_scrollingVelocityForMomentumAnimation = -wheelEvent.scrollingVelocity(); // Note that event delta is reversed from scroll direction.
    134 
    135132    if (processWheelEventForScrollSnap(wheelEvent))
    136133        return true;
     
    229226        m_momentumScrollInProgress = true;
    230227        if (momentumScrollingAnimatorEnabled()) {
    231             startMomentumScrollWithInitialVelocity(m_client.scrollOffset(), m_scrollingVelocityForMomentumAnimation, -wheelEvent.delta(), [](const FloatPoint& targetOffset) { return targetOffset; });
     228            startMomentumScrollWithInitialVelocity(m_client.scrollOffset(), -wheelEvent.scrollingVelocity(), -wheelEvent.delta(), [](const FloatPoint& targetOffset) { return targetOffset; });
    232229#if !LOG_DISABLED
    233230            m_eventDrivenScrollOffset = m_client.scrollOffset();
  • trunk/Source/WebKit/ChangeLog

    r285949 r285953  
     12021-11-17  Tim Horton  <timothy_horton@apple.com>
     2
     3        Momentum animator sometimes starts the animation at a very high velocity
     4        https://bugs.webkit.org/show_bug.cgi?id=233245
     5        <rdar://problem/85307115>
     6
     7        Reviewed by Simon Fraser.
     8
     9        * WebProcess/WebPage/EventDispatcher.cpp:
     10        (WebKit::EventDispatcher::wheelEvent):
     11        Ensure that wheel events always have velocities attached, even for
     12        events that don't go through the delta filter.
     13
    1142021-11-17  Wenson Hsieh  <wenson_hsieh@apple.com>
    215
  • trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp

    r285375 r285953  
    107107        if (WheelEventDeltaFilter::shouldApplyFilteringForEvent(platformWheelEvent))
    108108            platformWheelEvent = m_recentWheelEventDeltaFilter->eventCopyWithFilteredDeltas(platformWheelEvent);
     109        else if (WheelEventDeltaFilter::shouldIncludeVelocityForEvent(platformWheelEvent))
     110            platformWheelEvent = m_recentWheelEventDeltaFilter->eventCopyWithVelocity(platformWheelEvent);
    109111#endif
    110112
Note: See TracChangeset for help on using the changeset viewer.