Title: [287733] branches/safari-612.4.9.1-branch/Source
Revision
287733
Author
[email protected]
Date
2022-01-06 16:36:26 -0800 (Thu, 06 Jan 2022)

Log 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

Modified Paths

Diff

Modified: branches/safari-612.4.9.1-branch/Source/WTF/ChangeLog (287732 => 287733)


--- branches/safari-612.4.9.1-branch/Source/WTF/ChangeLog	2022-01-07 00:34:21 UTC (rev 287732)
+++ branches/safari-612.4.9.1-branch/Source/WTF/ChangeLog	2022-01-07 00:36:26 UTC (rev 287733)
@@ -1,3 +1,97 @@
+2022-01-06  Russell Epstein  <[email protected]>
+
+        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
+
+    2022-01-05  Tim Horton  <[email protected]>
+
+            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.
+
+            * wtf/PlatformHave.h:
+            Add a HAVE for kIOHIDEventScrollMomentumInterrupted.
+
 2021-12-13  Alan Coon  <[email protected]>
 
         Cherry-pick r286858. rdar://problem/86423741

Modified: branches/safari-612.4.9.1-branch/Source/WTF/wtf/PlatformHave.h (287732 => 287733)


--- branches/safari-612.4.9.1-branch/Source/WTF/wtf/PlatformHave.h	2022-01-07 00:34:21 UTC (rev 287732)
+++ branches/safari-612.4.9.1-branch/Source/WTF/wtf/PlatformHave.h	2022-01-07 00:36:26 UTC (rev 287733)
@@ -1154,3 +1154,7 @@
 #if PLATFORM(IOS)
 #define HAVE_PUACTIVITYPROGRESSCONTROLLER 1
 #endif
+
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 120200
+#define HAVE_PLATFORM_SCROLL_MOMENTUM_INTERRUPTION_REASON 1
+#endif

Modified: branches/safari-612.4.9.1-branch/Source/WebCore/PAL/pal/spi/mac/IOKitSPIMac.h (287732 => 287733)


--- branches/safari-612.4.9.1-branch/Source/WebCore/PAL/pal/spi/mac/IOKitSPIMac.h	2022-01-07 00:34:21 UTC (rev 287732)
+++ branches/safari-612.4.9.1-branch/Source/WebCore/PAL/pal/spi/mac/IOKitSPIMac.h	2022-01-07 00:36:26 UTC (rev 287733)
@@ -81,7 +81,6 @@
     kIOHIDEventTypeDigitizer = 11,
     kIOHIDEventTypeNavigationSwipe = 16,
     kIOHIDEventTypeForce = 32,
-
 };
 typedef uint32_t IOHIDEventType;
 
@@ -88,6 +87,12 @@
 typedef uint32_t IOHIDEventField;
 typedef uint64_t IOHIDEventSenderID;
 
+
+enum {
+    kIOHIDEventScrollMomentumInterrupted = (1 << 4),
+};
+typedef uint8_t IOHIDEventScrollMomentumBits;
+
 #ifdef __LP64__
 typedef double IOHIDFloat;
 #else
@@ -103,6 +108,7 @@
 uint64_t IOHIDEventGetTimeStamp(IOHIDEventRef);
 IOHIDFloat IOHIDEventGetFloatValue(IOHIDEventRef, IOHIDEventField);
 IOHIDEventSenderID IOHIDEventGetSenderID(IOHIDEventRef);
+IOHIDEventScrollMomentumBits IOHIDEventGetScrollMomentum(IOHIDEventRef);
 
 WTF_EXTERN_C_END
 

Modified: branches/safari-612.4.9.1-branch/Source/WebKit/ChangeLog (287732 => 287733)


--- branches/safari-612.4.9.1-branch/Source/WebKit/ChangeLog	2022-01-07 00:34:21 UTC (rev 287732)
+++ branches/safari-612.4.9.1-branch/Source/WebKit/ChangeLog	2022-01-07 00:36:26 UTC (rev 287733)
@@ -1,3 +1,157 @@
+2022-01-06  Russell Epstein  <[email protected]>
+
+        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
+
+    2022-01-05  Tim Horton  <[email protected]>
+
+            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.
+
+            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:
+
 2022-01-05  Russell Epstein  <[email protected]>
 
         Cherry-pick r287593. rdar://problem/86910670

Modified: branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEvent.cpp (287732 => 287733)


--- branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEvent.cpp	2022-01-07 00:34:21 UTC (rev 287732)
+++ branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEvent.cpp	2022-01-07 00:36:26 UTC (rev 287733)
@@ -44,7 +44,7 @@
 }
 
 #if PLATFORM(COCOA)
-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)
+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, MomentumEndType momentumEndType)
     : WebEvent(type, modifiers, timestamp)
     , m_position(position)
     , m_globalPosition(globalPosition)
@@ -53,6 +53,7 @@
     , m_granularity(granularity)
     , m_phase(phase)
     , m_momentumPhase(momentumPhase)
+    , m_momentumEndType(momentumEndType)
     , m_directionInvertedFromDevice(directionInvertedFromDevice)
     , m_hasPreciseScrollingDeltas(hasPreciseScrollingDeltas)
     , m_ioHIDEventTimestamp(ioHIDEventTimestamp)
@@ -87,6 +88,7 @@
     encoder << m_delta;
     encoder << m_wheelTicks;
     encoder << m_granularity;
+    encoder << m_momentumEndType;
     encoder << m_directionInvertedFromDevice;
 #if PLATFORM(COCOA) || PLATFORM(GTK) || USE(LIBWPE)
     encoder << m_phase;
@@ -115,6 +117,8 @@
         return false;
     if (!decoder.decode(t.m_granularity))
         return false;
+    if (!decoder.decode(t.m_momentumEndType))
+        return false;
     if (!decoder.decode(t.m_directionInvertedFromDevice))
         return false;
 #if PLATFORM(COCOA) || PLATFORM(GTK) || USE(LIBWPE)

Modified: branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEvent.h (287732 => 287733)


--- branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEvent.h	2022-01-07 00:34:21 UTC (rev 287732)
+++ branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEvent.h	2022-01-07 00:36:26 UTC (rev 287733)
@@ -29,6 +29,7 @@
 #include "WebEvent.h"
 #include <WebCore/FloatSize.h>
 #include <WebCore/IntPoint.h>
+#include <wtf/EnumTraits.h>
 
 namespace WebKit {
 
@@ -49,11 +50,17 @@
         PhaseMayBegin    = 1 << 5,
     };
 
+    enum class MomentumEndType : uint8_t {
+        Unknown,
+        Interrupted,
+        Natural,
+    };
+
     WebWheelEvent() = default;
 
     WebWheelEvent(Type, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, const WebCore::FloatSize& delta, const WebCore::FloatSize& wheelTicks, Granularity, OptionSet<Modifier>, WallTime timestamp);
 #if PLATFORM(COCOA)
-    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);
+    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);
 #elif PLATFORM(GTK) || USE(LIBWPE)
     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);
 #endif
@@ -66,6 +73,7 @@
     bool directionInvertedFromDevice() const { return m_directionInvertedFromDevice; }
     Phase phase() const { return static_cast<Phase>(m_phase); }
     Phase momentumPhase() const { return static_cast<Phase>(m_momentumPhase); }
+    MomentumEndType momentumEndType() const { return m_momentumEndType; }
 #if PLATFORM(COCOA) || PLATFORM(GTK) || USE(LIBWPE)
     bool hasPreciseScrollingDeltas() const { return m_hasPreciseScrollingDeltas; }
 #endif
@@ -90,6 +98,7 @@
     uint32_t m_phase { Phase::PhaseNone };
     uint32_t m_momentumPhase { Phase::PhaseNone };
 
+    MomentumEndType m_momentumEndType { MomentumEndType::Unknown };
     bool m_directionInvertedFromDevice { false };
 #if PLATFORM(COCOA) || PLATFORM(GTK) || USE(LIBWPE)
     bool m_hasPreciseScrollingDeltas { false };
@@ -103,3 +112,16 @@
 };
 
 } // namespace WebKit
+
+namespace WTF {
+
+template<> struct EnumTraits<WebKit::WebWheelEvent::MomentumEndType> {
+    using values = EnumValues<
+    WebKit::WebWheelEvent::MomentumEndType,
+    WebKit::WebWheelEvent::MomentumEndType::Unknown,
+    WebKit::WebWheelEvent::MomentumEndType::Interrupted,
+    WebKit::WebWheelEvent::MomentumEndType::Natural
+    >;
+};
+
+} // namespace WTF

Modified: branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEventCoalescer.cpp (287732 => 287733)


--- branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEventCoalescer.cpp	2022-01-07 00:34:21 UTC (rev 287732)
+++ branches/safari-612.4.9.1-branch/Source/WebKit/Shared/WebWheelEventCoalescer.cpp	2022-01-07 00:36:26 UTC (rev 287733)
@@ -81,7 +81,7 @@
     if (a.rawPlatformDelta() && b.rawPlatformDelta())
         mergedRawPlatformScrollingDelta = a.rawPlatformDelta().value() + b.rawPlatformDelta().value();
 
-    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);
+    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());
 #elif PLATFORM(GTK) || USE(LIBWPE)
     return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.phase(), b.momentumPhase(), b.granularity(), b.hasPreciseScrollingDeltas(), b.modifiers(), b.timestamp());
 #else

Modified: branches/safari-612.4.9.1-branch/Source/WebKit/Shared/mac/WebEventFactory.mm (287732 => 287733)


--- branches/safari-612.4.9.1-branch/Source/WebKit/Shared/mac/WebEventFactory.mm	2022-01-07 00:34:21 UTC (rev 287732)
+++ branches/safari-612.4.9.1-branch/Source/WebKit/Shared/mac/WebEventFactory.mm	2022-01-07 00:36:26 UTC (rev 287733)
@@ -410,33 +410,31 @@
 
     auto modifiers = modifiersForEvent(event);
     auto timestamp = WebCore::eventTimeStampSince1970(event.timestamp);
-
-    auto ioHIDEventTimestamp = [&]() {
+    
+    auto ioHIDEventWallTime = timestamp;
+    std::optional<WebCore::FloatSize> rawPlatformDelta;
+    auto momentumEndType = WebWheelEvent::MomentumEndType::Unknown;
+    
+    ([&] {
         auto cgEvent = event.CGEvent;
         if (!cgEvent)
-            return event.timestamp;
+            return;
 
         auto ioHIDEvent = adoptCF(CGEventCopyIOHIDEvent(cgEvent));
         if (!ioHIDEvent)
-            return event.timestamp;
+            return;
 
         auto ioHIDEventTimestamp = IOHIDEventGetTimeStamp(ioHIDEvent.get()); // IOEventRef timestamp is mach_absolute_time units.
-        return MonotonicTime::fromMachAbsoluteTime(ioHIDEventTimestamp).secondsSinceEpoch().seconds();
-    }();
-
-    auto rawPlatformDelta = [&]() -> std::optional<WebCore::FloatSize> {
-        auto cgEvent = event.CGEvent;
-        if (!cgEvent)
-            return std::nullopt;
-
-        auto ioHIDEvent = adoptCF(CGEventCopyIOHIDEvent(cgEvent));
-        if (!ioHIDEvent)
-            return std::nullopt;
+        auto monotonicIOHIDEventTimestamp = MonotonicTime::fromMachAbsoluteTime(ioHIDEventTimestamp).secondsSinceEpoch().seconds();
+        ioHIDEventWallTime = WebCore::eventTimeStampSince1970(monotonicIOHIDEventTimestamp);
         
-        return { WebCore::FloatSize(-IOHIDEventGetFloatValue(ioHIDEvent.get(), kIOHIDEventFieldScrollX), -IOHIDEventGetFloatValue(ioHIDEvent.get(), kIOHIDEventFieldScrollY)) };
-    }();
+        rawPlatformDelta = { WebCore::FloatSize(-IOHIDEventGetFloatValue(ioHIDEvent.get(), kIOHIDEventFieldScrollX), -IOHIDEventGetFloatValue(ioHIDEvent.get(), kIOHIDEventFieldScrollY)) };
 
-    auto ioHIDEventWallTime = WebCore::eventTimeStampSince1970(ioHIDEventTimestamp);
+#if HAVE(PLATFORM_SCROLL_MOMENTUM_INTERRUPTION_REASON)
+        bool momentumWasInterrupted = IOHIDEventGetScrollMomentum(ioHIDEvent.get()) & kIOHIDEventScrollMomentumInterrupted;
+        momentumEndType = momentumWasInterrupted ? WebWheelEvent::MomentumEndType::Interrupted : WebWheelEvent::MomentumEndType::Natural;
+#endif
+    })();
 
     if (phase == WebWheelEvent::PhaseCancelled) {
         deltaX = 0;
@@ -449,7 +447,7 @@
 
     return WebWheelEvent(WebEvent::Wheel, WebCore::IntPoint(position), WebCore::IntPoint(globalPosition), WebCore::FloatSize(deltaX, deltaY), WebCore::FloatSize(wheelTicksX, wheelTicksY),
         granularity, directionInvertedFromDevice, phase, momentumPhase, hasPreciseScrollingDeltas,
-        scrollCount, unacceleratedScrollingDelta, modifiers, timestamp, ioHIDEventWallTime, rawPlatformDelta);
+        scrollCount, unacceleratedScrollingDelta, modifiers, timestamp, ioHIDEventWallTime, rawPlatformDelta, momentumEndType);
 }
 
 WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(NSEvent *event, bool handledByInputMethod, bool replacesSoftSpace, const Vector<WebCore::KeypressCommand>& commands)

Modified: branches/safari-612.4.9.1-branch/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp (287732 => 287733)


--- branches/safari-612.4.9.1-branch/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp	2022-01-07 00:34:21 UTC (rev 287732)
+++ branches/safari-612.4.9.1-branch/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp	2022-01-07 00:36:26 UTC (rev 287733)
@@ -87,8 +87,23 @@
         // momentumPhase == PhaseEnded that interrupts.
         bool eventShouldInterruptGesture = !isMomentumEvent || event.momentumPhase() != WebWheelEvent::PhaseChanged;
 
-        if (pageIdentifierChanged || eventShouldInterruptGesture)
+        if (event.momentumPhase() == WebWheelEvent::PhaseEnded) {
+#if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
+            RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher saw momentum ended phase, interrupted=%d", static_cast<int>(event.momentumEndType()));
+#endif
+
+            // Ignore momentumPhase == PhaseEnded if it was due to the natural
+            // end of the animation (as opposed to interruption by placing fingers
+            // on the trackpad), so that our momentum is not cut short if the
+            // deceleration runs longer than the system curve.
+            if (event.momentumEndType() == WebWheelEvent::MomentumEndType::Natural)
+                eventShouldInterruptGesture = false;
+        }
+
+        if (pageIdentifierChanged || eventShouldInterruptGesture) {
+            RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher interrupting synthetic momentum phase");
             didEndMomentumPhase();
+        }
     }
 
     if (event.phase() == WebWheelEvent::PhaseBegan || event.phase() == WebWheelEvent::PhaseChanged) {
@@ -100,18 +115,26 @@
 #endif
     }
 
-    if (eventShouldStartSyntheticMomentumPhase(pageIdentifier, event))
+    if (eventShouldStartSyntheticMomentumPhase(pageIdentifier, event)) {
         didStartMomentumPhase(pageIdentifier, event);
+        m_isInOverriddenPlatformMomentumGesture = true;
+    }
 
-    bool isMomentumEventDuringSyntheticGesture = isMomentumEvent && m_currentGesture.active;
+    // Consume any incoming momentum events while we're generating a synthetic
+    // momentum gesture *or* a platform momentum phase that was overridden
+    // is still running after we finished the synthetic gesture.
+    bool shouldIgnoreIncomingPlatformEvent = isMomentumEvent && (m_isInOverriddenPlatformMomentumGesture || m_currentGesture.active);
 
+    if (event.momentumPhase() == WebWheelEvent::PhaseEnded)
+        m_isInOverriddenPlatformMomentumGesture = false;
+
 #if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
-    if (isMomentumEventDuringSyntheticGesture)
+    if (shouldIgnoreIncomingPlatformEvent)
         m_currentGesture.accumulatedEventOffset += event.delta();
 
     auto combinedPhase = (event.phase() << 8) | (event.momentumPhase());
     m_currentLogState.totalEventOffset += event.delta().height();
-    if (!isMomentumEventDuringSyntheticGesture) {
+    if (!shouldIgnoreIncomingPlatformEvent) {
         // Log events that we don't block to the generated offsets log as well,
         // even though we didn't technically generate them, just passed them through.
         m_currentLogState.totalGeneratedOffset += event.delta().height();
@@ -121,8 +144,7 @@
     
 #endif
 
-    // Consume any normal momentum events while we're inside a synthetic momentum gesture.
-    return isMomentumEventDuringSyntheticGesture;
+    return shouldIgnoreIncomingPlatformEvent;
 }
 
 static float appKitScrollMultiplierForEvent(const WebWheelEvent& event)
@@ -170,7 +192,8 @@
         m_lastIncomingEvent->modifiers(),
         time,
         time,
-        { });
+        { },
+        WebWheelEvent::MomentumEndType::Unknown);
     m_dispatcher.internalWheelEvent(m_currentGesture.pageIdentifier, syntheticEvent, m_lastRubberBandableEdges, EventDispatcher::WheelEventOrigin::MomentumEventDispatcher);
 
 #if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
@@ -223,7 +246,7 @@
     dispatchSyntheticMomentumEvent(WebWheelEvent::PhaseEnded, { });
 
 #if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
-    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());
+    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());
     m_dispatcher.queue().dispatchAfter(1_s, [this] {
         flushLog();
     });
@@ -242,7 +265,7 @@
 #if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
     WTF::TextStream stream(WTF::TextStream::LineMode::SingleLine);
     stream << curve;
-    RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher set curve %s", stream.release().utf8().data());
+    RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher set curve %{public}s", stream.release().utf8().data());
 #endif
 }
 
@@ -299,7 +322,7 @@
         startDisplayLink();
 }
 
-WebCore::FloatSize MomentumEventDispatcher::consumeDeltaForCurrentTime()
+std::optional<WebCore::FloatSize> MomentumEventDispatcher::consumeDeltaForCurrentTime()
 {
     WebCore::FloatSize delta;
 
@@ -311,7 +334,7 @@
         if (m_currentGesture.currentTailDeltaIndex < m_currentGesture.tailDeltaTable.size())
             delta = -m_currentGesture.tailDeltaTable[m_currentGesture.currentTailDeltaIndex++];
         else
-            delta = { };
+            return std::nullopt;
     }
 
     m_currentGesture.currentOffset += delta;
@@ -331,7 +354,16 @@
     if (!displayProperties || displayID != displayProperties->displayID)
         return;
 
-    dispatchSyntheticMomentumEvent(WebWheelEvent::PhaseChanged, consumeDeltaForCurrentTime());
+    auto delta = consumeDeltaForCurrentTime();
+    if (!delta) {
+#if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
+        RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher completed synthetic momentum phase");
+#endif
+        didEndMomentumPhase();
+        return;
+    }
+
+    dispatchSyntheticMomentumEvent(WebWheelEvent::PhaseChanged, *delta);
 }
 
 void MomentumEventDispatcher::didReceiveScrollEventWithInterval(WebCore::FloatSize size, Seconds frameInterval)

Modified: branches/safari-612.4.9.1-branch/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h (287732 => 287733)


--- branches/safari-612.4.9.1-branch/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h	2022-01-07 00:34:21 UTC (rev 287732)
+++ branches/safari-612.4.9.1-branch/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h	2022-01-07 00:36:26 UTC (rev 287733)
@@ -86,7 +86,7 @@
     void equalizeTailGaps();
 
     // Once consumed, this delta *must* be dispatched in an event.
-    WebCore::FloatSize consumeDeltaForCurrentTime();
+    std::optional<WebCore::FloatSize> consumeDeltaForCurrentTime();
 
     WebCore::FloatSize offsetAtTime(Seconds);
     std::pair<WebCore::FloatSize, WebCore::FloatSize> computeNextDelta(WebCore::FloatSize currentUnacceleratedDelta);
@@ -125,6 +125,7 @@
     std::optional<WallTime> m_lastScrollTimestamp;
     std::optional<WebWheelEvent> m_lastIncomingEvent;
     WebCore::RectEdges<bool> m_lastRubberBandableEdges;
+    bool m_isInOverriddenPlatformMomentumGesture { false };
 
     struct {
         bool active { false };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to