Changeset 287733 in webkit


Ignore:
Timestamp:
Jan 6, 2022, 4:36:26 PM (4 years ago)
Author:
Russell Epstein
Message:

Cherry-pick r287641. rdar://problem/86338105

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.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@287641 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Location:
branches/safari-612.4.9.1-branch/Source
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-612.4.9.1-branch/Source/WTF/ChangeLog

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

    r286236 r287733  
    11551155#define HAVE_PUACTIVITYPROGRESSCONTROLLER 1
    11561156#endif
     1157
     1158#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 120200
     1159#define HAVE_PLATFORM_SCROLL_MOMENTUM_INTERRUPTION_REASON 1
     1160#endif
  • branches/safari-612.4.9.1-branch/Source/WebCore/PAL/pal/spi/mac/IOKitSPIMac.h

    r286683 r287733  
    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
  • branches/safari-612.4.9.1-branch/Source/WebKit/ChangeLog

    r287635 r287733  
     12022-01-06  Russell Epstein  <repstein@apple.com>
     2
     3        Cherry-pick r287641. rdar://problem/86338105
     4
     5    Momentum Event Dispatcher: Momentum tails may get truncated if the duration runs longer than the system's
     6    https://bugs.webkit.org/show_bug.cgi?id=234535
     7    <rdar://problem/86338105>
     8   
     9    Reviewed by Simon Fraser.
     10   
     11    Source/WebKit:
     12   
     13    Currently, synthetic momentum dispatch is strictly tied to the duration
     14    of the real platform momentum phase, which has two unfortunate implications:
     15   
     16    - if our phase runs shorter than the platform phase, we'll keep dispatching
     17      zero-delta events until the platform momentum ends
     18   
     19    - more importantly, if our phase runs longer, it will be abruptly terminated
     20      when the platform momentum ends
     21   
     22    In practice, our synthetic phase is very close in duration to the system one,
     23    so the impact is minimal. But, to be safe, disentagle the two durations,
     24    using a new bit from the platform to determine if the system momentum phase
     25    was interrupted by the user (e.g. by tapping the trackpad) or naturally,
     26    and ignoring the ended event in the natural case, allowing synthetic
     27    events to continue being dispatched.
     28   
     29    * Shared/WebWheelEvent.cpp:
     30    (WebKit::WebWheelEvent::WebWheelEvent):
     31    (WebKit::WebWheelEvent::encode const):
     32    (WebKit::WebWheelEvent::decode):
     33    * Shared/WebWheelEvent.h:
     34    (WebKit::WebWheelEvent::momentumEndType const):
     35    * Shared/WebWheelEventCoalescer.cpp:
     36    (WebKit::WebWheelEventCoalescer::coalesce):
     37    Plumb momentumEndType along on WebWheelEvent. Platforms that don't
     38    provide information about the interruption reason will always say Unknown.
     39   
     40    * Shared/mac/WebEventFactory.mm:
     41    (WebKit::WebEventFactory::createWebWheelEvent):
     42    Only bother looking up the CGEvent/IOHIDEvent once, and extract all
     43    relevant details in one go.
     44   
     45    * WebProcess/WebPage/MomentumEventDispatcher.cpp:
     46    (WebKit::MomentumEventDispatcher::handleWheelEvent):
     47    Don't interrupt the synthetic momentum phase if the momentum-ended event
     48    comes from the natural end of the deceleration instead of an interruption
     49    (or an unknown reason).
     50   
     51    Keep track of whether we're in the middle of a platform momentum phase
     52    that we chose (at momentum-begin time) to override. When deciding
     53    whether to eat an incoming event, take *both* this new bit and whether
     54    we are currently in the middle of a synthetic phase into account. It
     55    is important to continue eating incoming events in the case where
     56    the synthetic phase ended early (so `active` became false) but the
     57    platform phase continues.
     58   
     59    (WebKit::MomentumEventDispatcher::dispatchSyntheticMomentumEvent):
     60    (WebKit::MomentumEventDispatcher::didEndMomentumPhase):
     61    Adjust some logging wording to be more precise.
     62   
     63    (WebKit::MomentumEventDispatcher::setScrollingAccelerationCurve):
     64    Make this log public so that the curve value is visible in logs.
     65   
     66    (WebKit::MomentumEventDispatcher::consumeDeltaForCurrentTime):
     67    Make consumeDeltaForCurrentTime inform the client via an optional when
     68    we are at the end of the delta table.
     69   
     70    (WebKit::MomentumEventDispatcher::displayWasRefreshed):
     71    Stop the synthetic momentum phase as soon as we run out of deltas.
     72   
     73    (WebKit::MomentumEventDispatcher::computeNextDelta):
     74    * WebProcess/WebPage/MomentumEventDispatcher.h:
     75   
     76    Source/WTF:
     77   
     78    * wtf/PlatformHave.h:
     79    Add a HAVE for kIOHIDEventScrollMomentumInterrupted.
     80   
     81   
     82    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@287641 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     83
     84    2022-01-05  Tim Horton  <timothy_horton@apple.com>
     85
     86            Momentum Event Dispatcher: Momentum tails may get truncated if the duration runs longer than the system's
     87            https://bugs.webkit.org/show_bug.cgi?id=234535
     88            <rdar://problem/86338105>
     89
     90            Reviewed by Simon Fraser.
     91
     92            Currently, synthetic momentum dispatch is strictly tied to the duration
     93            of the real platform momentum phase, which has two unfortunate implications:
     94
     95            - if our phase runs shorter than the platform phase, we'll keep dispatching
     96              zero-delta events until the platform momentum ends
     97
     98            - more importantly, if our phase runs longer, it will be abruptly terminated
     99              when the platform momentum ends
     100
     101            In practice, our synthetic phase is very close in duration to the system one,
     102            so the impact is minimal. But, to be safe, disentagle the two durations,
     103            using a new bit from the platform to determine if the system momentum phase
     104            was interrupted by the user (e.g. by tapping the trackpad) or naturally,
     105            and ignoring the ended event in the natural case, allowing synthetic
     106            events to continue being dispatched.
     107
     108            * Shared/WebWheelEvent.cpp:
     109            (WebKit::WebWheelEvent::WebWheelEvent):
     110            (WebKit::WebWheelEvent::encode const):
     111            (WebKit::WebWheelEvent::decode):
     112            * Shared/WebWheelEvent.h:
     113            (WebKit::WebWheelEvent::momentumEndType const):
     114            * Shared/WebWheelEventCoalescer.cpp:
     115            (WebKit::WebWheelEventCoalescer::coalesce):
     116            Plumb momentumEndType along on WebWheelEvent. Platforms that don't
     117            provide information about the interruption reason will always say Unknown.
     118
     119            * Shared/mac/WebEventFactory.mm:
     120            (WebKit::WebEventFactory::createWebWheelEvent):
     121            Only bother looking up the CGEvent/IOHIDEvent once, and extract all
     122            relevant details in one go.
     123
     124            * WebProcess/WebPage/MomentumEventDispatcher.cpp:
     125            (WebKit::MomentumEventDispatcher::handleWheelEvent):
     126            Don't interrupt the synthetic momentum phase if the momentum-ended event
     127            comes from the natural end of the deceleration instead of an interruption
     128            (or an unknown reason).
     129
     130            Keep track of whether we're in the middle of a platform momentum phase
     131            that we chose (at momentum-begin time) to override. When deciding
     132            whether to eat an incoming event, take *both* this new bit and whether
     133            we are currently in the middle of a synthetic phase into account. It
     134            is important to continue eating incoming events in the case where
     135            the synthetic phase ended early (so `active` became false) but the
     136            platform phase continues.
     137
     138            (WebKit::MomentumEventDispatcher::dispatchSyntheticMomentumEvent):
     139            (WebKit::MomentumEventDispatcher::didEndMomentumPhase):
     140            Adjust some logging wording to be more precise.
     141
     142            (WebKit::MomentumEventDispatcher::setScrollingAccelerationCurve):
     143            Make this log public so that the curve value is visible in logs.
     144
     145            (WebKit::MomentumEventDispatcher::consumeDeltaForCurrentTime):
     146            Make consumeDeltaForCurrentTime inform the client via an optional when
     147            we are at the end of the delta table.
     148
     149            (WebKit::MomentumEventDispatcher::displayWasRefreshed):
     150            Stop the synthetic momentum phase as soon as we run out of deltas.
     151
     152            (WebKit::MomentumEventDispatcher::computeNextDelta):
     153            * WebProcess/WebPage/MomentumEventDispatcher.h:
     154
    11552022-01-05  Russell Epstein  <repstein@apple.com>
    2156
  • branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEvent.cpp

    r286679 r287733  
    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))
  • branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEvent.h

    r286679 r287733  
    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
  • branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEventCoalescer.cpp

    r286679 r287733  
    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());
  • branches/safari-612.4.9.1-branch/Source/WebKit/Shared/mac/WebEventFactory.mm

    r287635 r287733  
    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
  • branches/safari-612.4.9.1-branch/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp

    r287031 r287733  
    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
  • branches/safari-612.4.9.1-branch/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h

    r287634 r287733  
    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.