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

Changeset 287641 in webkit


Ignore:
Timestamp:
Jan 5, 2022, 11:29:43 AM (5 years ago)
Author:
timothy_horton@apple.com
Message:

Momentum Event Dispatcher: Momentum tails may get truncated if the duration runs longer than the system's
​https://bugs.webkit.org/show_bug.cgi?id=234535
<rdar://problem/86338105>

Reviewed by Simon Fraser.

Source/WebKit:

Currently, synthetic momentum dispatch is strictly tied to the duration
of the real platform momentum phase, which has two unfortunate implications:

  • if our phase runs shorter than the platform phase, we'll keep dispatching zero-delta events until the platform momentum ends
  • more importantly, if our phase runs longer, it will be abruptly terminated when the platform momentum ends

In practice, our synthetic phase is very close in duration to the system one,
so the impact is minimal. But, to be safe, disentagle the two durations,
using a new bit from the platform to determine if the system momentum phase
was interrupted by the user (e.g. by tapping the trackpad) or naturally,
and ignoring the ended event in the natural case, allowing synthetic
events to continue being dispatched.

  • Shared/WebWheelEvent.cpp:

(WebKit::WebWheelEvent::WebWheelEvent):
(WebKit::WebWheelEvent::encode const):
(WebKit::WebWheelEvent::decode):

  • Shared/WebWheelEvent.h:

(WebKit::WebWheelEvent::momentumEndType const):

  • Shared/WebWheelEventCoalescer.cpp:

(WebKit::WebWheelEventCoalescer::coalesce):
Plumb momentumEndType along on WebWheelEvent. Platforms that don't
provide information about the interruption reason will always say Unknown.

  • Shared/mac/WebEventFactory.mm:

(WebKit::WebEventFactory::createWebWheelEvent):
Only bother looking up the CGEvent/IOHIDEvent once, and extract all
relevant details in one go.

  • WebProcess/WebPage/MomentumEventDispatcher.cpp:

(WebKit::MomentumEventDispatcher::handleWheelEvent):
Don't interrupt the synthetic momentum phase if the momentum-ended event
comes from the natural end of the deceleration instead of an interruption
(or an unknown reason).

Keep track of whether we're in the middle of a platform momentum phase
that we chose (at momentum-begin time) to override. When deciding
whether to eat an incoming event, take *both* this new bit and whether
we are currently in the middle of a synthetic phase into account. It
is important to continue eating incoming events in the case where
the synthetic phase ended early (so active became false) but the
platform phase continues.

(WebKit::MomentumEventDispatcher::dispatchSyntheticMomentumEvent):
(WebKit::MomentumEventDispatcher::didEndMomentumPhase):
Adjust some logging wording to be more precise.

(WebKit::MomentumEventDispatcher::setScrollingAccelerationCurve):
Make this log public so that the curve value is visible in logs.

(WebKit::MomentumEventDispatcher::consumeDeltaForCurrentTime):
Make consumeDeltaForCurrentTime inform the client via an optional when
we are at the end of the delta table.

(WebKit::MomentumEventDispatcher::displayWasRefreshed):
Stop the synthetic momentum phase as soon as we run out of deltas.

(WebKit::MomentumEventDispatcher::computeNextDelta):

  • WebProcess/WebPage/MomentumEventDispatcher.h:

Source/WTF:

  • wtf/PlatformHave.h:

Add a HAVE for kIOHIDEventScrollMomentumInterrupted.

Location:
trunk/Source
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r287510 r287641  
     12022-01-05  Tim Horton  <timothy_horton@apple.com>
     2
     3        Momentum Event Dispatcher: Momentum tails may get truncated if the duration runs longer than the system's
     4        https://bugs.webkit.org/show_bug.cgi?id=234535
     5        <rdar://problem/86338105>
     6
     7        Reviewed by Simon Fraser.
     8
     9        * wtf/PlatformHave.h:
     10        Add a HAVE for kIOHIDEventScrollMomentumInterrupted.
     11
    1122021-12-31  Yusuke Suzuki  <ysuzuki@apple.com>
    213
  • trunk/Source/WTF/wtf/PlatformHave.h

    r287481 r287641  
    11411141#define HAVE_CFAUTORELEASE 1
    11421142#endif
     1143
     1144#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 120200
     1145#define HAVE_PLATFORM_SCROLL_MOMENTUM_INTERRUPTION_REASON 1
     1146#endif
  • trunk/Source/WebCore/PAL/pal/spi/mac/IOKitSPIMac.h

    r286346 r287641  
    8282    kIOHIDEventTypeNavigationSwipe = 16,
    8383    kIOHIDEventTypeForce = 32,
    84 
    8584};
    8685typedef uint32_t IOHIDEventType;
    … …  
    8887typedef uint32_t IOHIDEventField;
    8988typedef uint64_t IOHIDEventSenderID;
     89
     90
     91enum {
     92    kIOHIDEventScrollMomentumInterrupted = (1 << 4),
     93};
     94typedef uint8_t IOHIDEventScrollMomentumBits;
    9095
    9196#ifdef __LP64__
    … …  
    104109IOHIDFloat IOHIDEventGetFloatValue(IOHIDEventRef, IOHIDEventField);
    105110IOHIDEventSenderID IOHIDEventGetSenderID(IOHIDEventRef);
     111IOHIDEventScrollMomentumBits IOHIDEventGetScrollMomentum(IOHIDEventRef);
    106112
    107113WTF_EXTERN_C_END
  • trunk/Source/WebKit/ChangeLog

    r287616 r287641  
     12022-01-05  Tim Horton  <timothy_horton@apple.com>
     2
     3        Momentum Event Dispatcher: Momentum tails may get truncated if the duration runs longer than the system's
     4        https://bugs.webkit.org/show_bug.cgi?id=234535
     5        <rdar://problem/86338105>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Currently, synthetic momentum dispatch is strictly tied to the duration
     10        of the real platform momentum phase, which has two unfortunate implications:
     11
     12        - if our phase runs shorter than the platform phase, we'll keep dispatching
     13          zero-delta events until the platform momentum ends
     14
     15        - more importantly, if our phase runs longer, it will be abruptly terminated
     16          when the platform momentum ends
     17
     18        In practice, our synthetic phase is very close in duration to the system one,
     19        so the impact is minimal. But, to be safe, disentagle the two durations,
     20        using a new bit from the platform to determine if the system momentum phase
     21        was interrupted by the user (e.g. by tapping the trackpad) or naturally,
     22        and ignoring the ended event in the natural case, allowing synthetic
     23        events to continue being dispatched.
     24
     25        * Shared/WebWheelEvent.cpp:
     26        (WebKit::WebWheelEvent::WebWheelEvent):
     27        (WebKit::WebWheelEvent::encode const):
     28        (WebKit::WebWheelEvent::decode):
     29        * Shared/WebWheelEvent.h:
     30        (WebKit::WebWheelEvent::momentumEndType const):
     31        * Shared/WebWheelEventCoalescer.cpp:
     32        (WebKit::WebWheelEventCoalescer::coalesce):
     33        Plumb momentumEndType along on WebWheelEvent. Platforms that don't
     34        provide information about the interruption reason will always say Unknown.
     35
     36        * Shared/mac/WebEventFactory.mm:
     37        (WebKit::WebEventFactory::createWebWheelEvent):
     38        Only bother looking up the CGEvent/IOHIDEvent once, and extract all
     39        relevant details in one go.
     40
     41        * WebProcess/WebPage/MomentumEventDispatcher.cpp:
     42        (WebKit::MomentumEventDispatcher::handleWheelEvent):
     43        Don't interrupt the synthetic momentum phase if the momentum-ended event
     44        comes from the natural end of the deceleration instead of an interruption
     45        (or an unknown reason).
     46
     47        Keep track of whether we're in the middle of a platform momentum phase
     48        that we chose (at momentum-begin time) to override. When deciding
     49        whether to eat an incoming event, take *both* this new bit and whether
     50        we are currently in the middle of a synthetic phase into account. It
     51        is important to continue eating incoming events in the case where
     52        the synthetic phase ended early (so `active` became false) but the
     53        platform phase continues.
     54
     55        (WebKit::MomentumEventDispatcher::dispatchSyntheticMomentumEvent):
     56        (WebKit::MomentumEventDispatcher::didEndMomentumPhase):
     57        Adjust some logging wording to be more precise.
     58
     59        (WebKit::MomentumEventDispatcher::setScrollingAccelerationCurve):
     60        Make this log public so that the curve value is visible in logs.
     61
     62        (WebKit::MomentumEventDispatcher::consumeDeltaForCurrentTime):
     63        Make consumeDeltaForCurrentTime inform the client via an optional when
     64        we are at the end of the delta table.
     65
     66        (WebKit::MomentumEventDispatcher::displayWasRefreshed):
     67        Stop the synthetic momentum phase as soon as we run out of deltas.
     68
     69        (WebKit::MomentumEventDispatcher::computeNextDelta):
     70        * WebProcess/WebPage/MomentumEventDispatcher.h:
     71
    1722022-01-05  Per Arne Vollan  <pvollan@apple.com>
    273
  • trunk/Source/WebKit/Shared/WebWheelEvent.cpp

    r286270 r287641  
    4545
    4646#if PLATFORM(COCOA)
    47 WebWheelEvent::WebWheelEvent(Type type, const IntPoint& position, const IntPoint& globalPosition, const FloatSize& delta, const FloatSize& wheelTicks, Granularity granularity, bool directionInvertedFromDevice, Phase phase, Phase momentumPhase, bool hasPreciseScrollingDeltas, uint32_t scrollCount, const WebCore::FloatSize& unacceleratedScrollingDelta, OptionSet<Modifier> modifiers, WallTime timestamp, WallTime ioHIDEventTimestamp, std::optional<WebCore::FloatSize> rawPlatformDelta)
     47WebWheelEvent::WebWheelEvent(Type type, const IntPoint& position, const IntPoint& globalPosition, const FloatSize& delta, const FloatSize& wheelTicks, Granularity granularity, bool directionInvertedFromDevice, Phase phase, Phase momentumPhase, bool hasPreciseScrollingDeltas, uint32_t scrollCount, const WebCore::FloatSize& unacceleratedScrollingDelta, OptionSet<Modifier> modifiers, WallTime timestamp, WallTime ioHIDEventTimestamp, std::optional<WebCore::FloatSize> rawPlatformDelta, MomentumEndType momentumEndType)
    4848    : WebEvent(type, modifiers, timestamp)
    4949    , m_position(position)
    … …  
    5454    , m_phase(phase)
    5555    , m_momentumPhase(momentumPhase)
     56    , m_momentumEndType(momentumEndType)
    5657    , m_directionInvertedFromDevice(directionInvertedFromDevice)
    5758    , m_hasPreciseScrollingDeltas(hasPreciseScrollingDeltas)
    … …  
    8889    encoder << m_wheelTicks;
    8990    encoder << m_granularity;
     91    encoder << m_momentumEndType;
    9092    encoder << m_directionInvertedFromDevice;
    9193#if PLATFORM(COCOA) || PLATFORM(GTK) || USE(LIBWPE)
    … …  
    115117        return false;
    116118    if (!decoder.decode(t.m_granularity))
     119        return false;
     120    if (!decoder.decode(t.m_momentumEndType))
    117121        return false;
    118122    if (!decoder.decode(t.m_directionInvertedFromDevice))
  • trunk/Source/WebKit/Shared/WebWheelEvent.h

    r286270 r287641  
    3030#include <WebCore/FloatSize.h>
    3131#include <WebCore/IntPoint.h>
     32#include <wtf/EnumTraits.h>
    3233
    3334namespace WebKit {
    … …  
    5051    };
    5152
     53    enum class MomentumEndType : uint8_t {
     54        Unknown,
     55        Interrupted,
     56        Natural,
     57    };
     58
    5259    WebWheelEvent() = default;
    5360
    5461    WebWheelEvent(Type, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, const WebCore::FloatSize& delta, const WebCore::FloatSize& wheelTicks, Granularity, OptionSet<Modifier>, WallTime timestamp);
    5562#if PLATFORM(COCOA)
    56     WebWheelEvent(Type, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, const WebCore::FloatSize& delta, const WebCore::FloatSize& wheelTicks, Granularity, bool directionInvertedFromDevice, Phase, Phase momentumPhase, bool hasPreciseScrollingDeltas, uint32_t scrollCount, const WebCore::FloatSize& unacceleratedScrollingDelta, OptionSet<Modifier>, WallTime timestamp, WallTime ioHIDEventTimestamp, std::optional<WebCore::FloatSize> rawPlatformDelta);
     63    WebWheelEvent(Type, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, const WebCore::FloatSize& delta, const WebCore::FloatSize& wheelTicks, Granularity, bool directionInvertedFromDevice, Phase, Phase momentumPhase, bool hasPreciseScrollingDeltas, uint32_t scrollCount, const WebCore::FloatSize& unacceleratedScrollingDelta, OptionSet<Modifier>, WallTime timestamp, WallTime ioHIDEventTimestamp, std::optional<WebCore::FloatSize> rawPlatformDelta, MomentumEndType);
    5764#elif PLATFORM(GTK) || USE(LIBWPE)
    5865    WebWheelEvent(Type, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, const WebCore::FloatSize& delta, const WebCore::FloatSize& wheelTicks, Phase, Phase momentumPhase, Granularity, bool hasPreciseScrollingDeltas, OptionSet<Modifier>, WallTime timestamp);
    … …  
    6774    Phase phase() const { return static_cast<Phase>(m_phase); }
    6875    Phase momentumPhase() const { return static_cast<Phase>(m_momentumPhase); }
     76    MomentumEndType momentumEndType() const { return m_momentumEndType; }
    6977#if PLATFORM(COCOA) || PLATFORM(GTK) || USE(LIBWPE)
    7078    bool hasPreciseScrollingDeltas() const { return m_hasPreciseScrollingDeltas; }
    … …  
    9199    uint32_t m_momentumPhase { Phase::PhaseNone };
    92100
     101    MomentumEndType m_momentumEndType { MomentumEndType::Unknown };
    93102    bool m_directionInvertedFromDevice { false };
    94103#if PLATFORM(COCOA) || PLATFORM(GTK) || USE(LIBWPE)
    … …  
    104113
    105114} // namespace WebKit
     115
     116namespace WTF {
     117
     118template<> struct EnumTraits<WebKit::WebWheelEvent::MomentumEndType> {
     119    using values = EnumValues<
     120    WebKit::WebWheelEvent::MomentumEndType,
     121    WebKit::WebWheelEvent::MomentumEndType::Unknown,
     122    WebKit::WebWheelEvent::MomentumEndType::Interrupted,
     123    WebKit::WebWheelEvent::MomentumEndType::Natural
     124    >;
     125};
     126
     127} // namespace WTF
  • trunk/Source/WebKit/Shared/WebWheelEventCoalescer.cpp

    r287431 r287641  
    8282        mergedRawPlatformScrollingDelta = a.rawPlatformDelta().value() + b.rawPlatformDelta().value();
    8383
    84     return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.directionInvertedFromDevice(), b.phase(), b.momentumPhase(), b.hasPreciseScrollingDeltas(), b.scrollCount(), mergedUnacceleratedScrollingDelta, b.modifiers(), b.timestamp(), b.ioHIDEventTimestamp(), mergedRawPlatformScrollingDelta);
     84    return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.directionInvertedFromDevice(), b.phase(), b.momentumPhase(), b.hasPreciseScrollingDeltas(), b.scrollCount(), mergedUnacceleratedScrollingDelta, b.modifiers(), b.timestamp(), b.ioHIDEventTimestamp(), mergedRawPlatformScrollingDelta, b.momentumEndType());
    8585#elif PLATFORM(GTK) || USE(LIBWPE)
    8686    return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.phase(), b.momentumPhase(), b.granularity(), b.hasPreciseScrollingDeltas(), b.modifiers(), b.timestamp());
  • trunk/Source/WebKit/Shared/mac/WebEventFactory.mm

    r287593 r287641  
    411411    auto modifiers = modifiersForEvent(event);
    412412    auto timestamp = WebCore::eventTimeStampSince1970(event.timestamp);
    413 
    414     auto ioHIDEventTimestamp = [&]() {
     413   
     414    auto ioHIDEventWallTime = timestamp;
     415    std::optional<WebCore::FloatSize> rawPlatformDelta;
     416    auto momentumEndType = WebWheelEvent::MomentumEndType::Unknown;
     417   
     418    ([&] {
    415419        auto cgEvent = event.CGEvent;
    416420        if (!cgEvent)
    417             return event.timestamp;
     421            return;
    418422
    419423        auto ioHIDEvent = adoptCF(CGEventCopyIOHIDEvent(cgEvent));
    420424        if (!ioHIDEvent)
    421             return event.timestamp;
     425            return;
    422426
    423427        auto ioHIDEventTimestamp = IOHIDEventGetTimeStamp(ioHIDEvent.get()); // IOEventRef timestamp is mach_absolute_time units.
    424         return MonotonicTime::fromMachAbsoluteTime(ioHIDEventTimestamp).secondsSinceEpoch().seconds();
    425     }();
    426 
    427     auto rawPlatformDelta = [&]() -> std::optional<WebCore::FloatSize> {
    428         auto cgEvent = event.CGEvent;
    429         if (!cgEvent)
    430             return std::nullopt;
    431 
    432         auto ioHIDEvent = adoptCF(CGEventCopyIOHIDEvent(cgEvent));
    433         if (!ioHIDEvent)
    434             return std::nullopt;
     428        auto monotonicIOHIDEventTimestamp = MonotonicTime::fromMachAbsoluteTime(ioHIDEventTimestamp).secondsSinceEpoch().seconds();
     429        ioHIDEventWallTime = WebCore::eventTimeStampSince1970(monotonicIOHIDEventTimestamp);
    435430       
    436         return { WebCore::FloatSize(-IOHIDEventGetFloatValue(ioHIDEvent.get(), kIOHIDEventFieldScrollX), -IOHIDEventGetFloatValue(ioHIDEvent.get(), kIOHIDEventFieldScrollY)) };
    437     }();
    438 
    439     auto ioHIDEventWallTime = WebCore::eventTimeStampSince1970(ioHIDEventTimestamp);
     431        rawPlatformDelta = { WebCore::FloatSize(-IOHIDEventGetFloatValue(ioHIDEvent.get(), kIOHIDEventFieldScrollX), -IOHIDEventGetFloatValue(ioHIDEvent.get(), kIOHIDEventFieldScrollY)) };
     432
     433#if HAVE(PLATFORM_SCROLL_MOMENTUM_INTERRUPTION_REASON)
     434        bool momentumWasInterrupted = IOHIDEventGetScrollMomentum(ioHIDEvent.get()) & kIOHIDEventScrollMomentumInterrupted;
     435        momentumEndType = momentumWasInterrupted ? WebWheelEvent::MomentumEndType::Interrupted : WebWheelEvent::MomentumEndType::Natural;
     436#endif
     437    })();
    440438
    441439    if (phase == WebWheelEvent::PhaseCancelled) {
    … …  
    450448    return WebWheelEvent(WebEvent::Wheel, WebCore::IntPoint(position), WebCore::IntPoint(globalPosition), WebCore::FloatSize(deltaX, deltaY), WebCore::FloatSize(wheelTicksX, wheelTicksY),
    451449        granularity, directionInvertedFromDevice, phase, momentumPhase, hasPreciseScrollingDeltas,
    452         scrollCount, unacceleratedScrollingDelta, modifiers, timestamp, ioHIDEventWallTime, rawPlatformDelta);
     450        scrollCount, unacceleratedScrollingDelta, modifiers, timestamp, ioHIDEventWallTime, rawPlatformDelta, momentumEndType);
    453451}
    454452
  • trunk/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp

    r286999 r287641  
    8888        bool eventShouldInterruptGesture = !isMomentumEvent || event.momentumPhase() != WebWheelEvent::PhaseChanged;
    8989
    90         if (pageIdentifierChanged || eventShouldInterruptGesture)
     90        if (event.momentumPhase() == WebWheelEvent::PhaseEnded) {
     91#if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
     92            RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher saw momentum ended phase, interrupted=%d", static_cast<int>(event.momentumEndType()));
     93#endif
     94
     95            // Ignore momentumPhase == PhaseEnded if it was due to the natural
     96            // end of the animation (as opposed to interruption by placing fingers
     97            // on the trackpad), so that our momentum is not cut short if the
     98            // deceleration runs longer than the system curve.
     99            if (event.momentumEndType() == WebWheelEvent::MomentumEndType::Natural)
     100                eventShouldInterruptGesture = false;
     101        }
     102
     103        if (pageIdentifierChanged || eventShouldInterruptGesture) {
     104            RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher interrupting synthetic momentum phase");
    91105            didEndMomentumPhase();
     106        }
    92107    }
    93108
    … …  
    101116    }
    102117
    103     if (eventShouldStartSyntheticMomentumPhase(pageIdentifier, event))
     118    if (eventShouldStartSyntheticMomentumPhase(pageIdentifier, event)) {
    104119        didStartMomentumPhase(pageIdentifier, event);
    105 
    106     bool isMomentumEventDuringSyntheticGesture = isMomentumEvent && m_currentGesture.active;
    107 
    108 #if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
    109     if (isMomentumEventDuringSyntheticGesture)
     120        m_isInOverriddenPlatformMomentumGesture = true;
     121    }
     122
     123    // Consume any incoming momentum events while we're generating a synthetic
     124    // momentum gesture *or* a platform momentum phase that was overridden
     125    // is still running after we finished the synthetic gesture.
     126    bool shouldIgnoreIncomingPlatformEvent = isMomentumEvent && (m_isInOverriddenPlatformMomentumGesture || m_currentGesture.active);
     127
     128    if (event.momentumPhase() == WebWheelEvent::PhaseEnded)
     129        m_isInOverriddenPlatformMomentumGesture = false;
     130
     131#if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
     132    if (shouldIgnoreIncomingPlatformEvent)
    110133        m_currentGesture.accumulatedEventOffset += event.delta();
    111134
    112135    auto combinedPhase = (event.phase() << 8) | (event.momentumPhase());
    113136    m_currentLogState.totalEventOffset += event.delta().height();
    114     if (!isMomentumEventDuringSyntheticGesture) {
     137    if (!shouldIgnoreIncomingPlatformEvent) {
    115138        // Log events that we don't block to the generated offsets log as well,
    116139        // even though we didn't technically generate them, just passed them through.
    … …  
    122145#endif
    123146
    124     // Consume any normal momentum events while we're inside a synthetic momentum gesture.
    125     return isMomentumEventDuringSyntheticGesture;
     147    return shouldIgnoreIncomingPlatformEvent;
    126148}
    127149
    … …  
    171193        time,
    172194        time,
    173         { });
     195        { },
     196        WebWheelEvent::MomentumEndType::Unknown);
    174197    m_dispatcher.internalWheelEvent(m_currentGesture.pageIdentifier, syntheticEvent, m_lastRubberBandableEdges, EventDispatcher::WheelEventOrigin::MomentumEventDispatcher);
    175198
    … …  
    224247
    225248#if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
    226     RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher saw momentum end phase with total offset %.1f %.1f, duration %f (event offset would have been %.1f %.1f) (tail index %d of %zu)", m_currentGesture.currentOffset.width(), m_currentGesture.currentOffset.height(), (MonotonicTime::now() - m_currentGesture.startTime).seconds(), m_currentGesture.accumulatedEventOffset.width(), m_currentGesture.accumulatedEventOffset.height(), m_currentGesture.currentTailDeltaIndex, m_currentGesture.tailDeltaTable.size());
     249    RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher ending synthetic momentum phase with total offset %.1f %.1f, duration %f (event offset would have been %.1f %.1f) (tail index %d of %zu)", m_currentGesture.currentOffset.width(), m_currentGesture.currentOffset.height(), (MonotonicTime::now() - m_currentGesture.startTime).seconds(), m_currentGesture.accumulatedEventOffset.width(), m_currentGesture.accumulatedEventOffset.height(), m_currentGesture.currentTailDeltaIndex, m_currentGesture.tailDeltaTable.size());
    227250    m_dispatcher.queue().dispatchAfter(1_s, [this] {
    228251        flushLog();
    … …  
    243266    WTF::TextStream stream(WTF::TextStream::LineMode::SingleLine);
    244267    stream << curve;
    245     RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher set curve %s", stream.release().utf8().data());
     268    RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher set curve %{public}s", stream.release().utf8().data());
    246269#endif
    247270}
    … …  
    300323}
    301324
    302 WebCore::FloatSize MomentumEventDispatcher::consumeDeltaForCurrentTime()
     325std::optional<WebCore::FloatSize> MomentumEventDispatcher::consumeDeltaForCurrentTime()
    303326{
    304327    WebCore::FloatSize delta;
    … …  
    312335            delta = -m_currentGesture.tailDeltaTable[m_currentGesture.currentTailDeltaIndex++];
    313336        else
    314             delta = { };
     337            return std::nullopt;
    315338    }
    316339
    … …  
    332355        return;
    333356
    334     dispatchSyntheticMomentumEvent(WebWheelEvent::PhaseChanged, consumeDeltaForCurrentTime());
     357    auto delta = consumeDeltaForCurrentTime();
     358    if (!delta) {
     359#if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
     360        RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher completed synthetic momentum phase");
     361#endif
     362        didEndMomentumPhase();
     363        return;
     364    }
     365
     366    dispatchSyntheticMomentumEvent(WebWheelEvent::PhaseChanged, *delta);
    335367}
    336368
  • trunk/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h

    r287578 r287641  
    8787
    8888    // Once consumed, this delta *must* be dispatched in an event.
    89     WebCore::FloatSize consumeDeltaForCurrentTime();
     89    std::optional<WebCore::FloatSize> consumeDeltaForCurrentTime();
    9090
    9191    WebCore::FloatSize offsetAtTime(Seconds);
    … …  
    126126    std::optional<WebWheelEvent> m_lastIncomingEvent;
    127127    WebCore::RectEdges<bool> m_lastRubberBandableEdges;
     128    bool m_isInOverriddenPlatformMomentumGesture { false };
    128129
    129130    struct {
Note: See TracChangeset for help on using the changeset viewer.