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 };