Title: [287593] trunk
Revision
287593
Author
simon.fra...@apple.com
Date
2022-01-04 15:48:08 -0800 (Tue, 04 Jan 2022)

Log Message

"canceled" wheel events to non-zero deltas cause scrolling jumps in PDFs and CodeMirror
https://bugs.webkit.org/show_bug.cgi?id=234825

Reviewed by Tim Horton.

Source/WebKit:

On some macOS versions, interrupting a momentum scroll via a two-finger tap on the trackpad can
result in the following sequence of wheel events: momentumPhase:end -> phase:mayBegin -> phase:cancelled,
and that last canceled event can have non-zero deltas (rdar://86653042).

Protect against this by zeroing out the deltas for cancelled wheel events when constructing WebEvents
from NSEvents. Code in Element::dispatchWheelEvent() ensures that we don't dispatch wheel events with
zero deltas to script, fixing CodeMirror.

Jumps only affected PDFs (and scrollable selects) because those are the code paths that don't go via
ScrollingEffectsController, which already ignores Cancelled events.

Test: fast/scrolling/mac/canceled-event-with-non-zero-deltas.html

* Shared/mac/WebEventFactory.mm:
(WebKit::WebEventFactory::createWebWheelEvent):

LayoutTests:

* fast/scrolling/mac/canceled-event-with-non-zero-deltas-expected.txt: Added.
* fast/scrolling/mac/canceled-event-with-non-zero-deltas.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (287592 => 287593)


--- trunk/LayoutTests/ChangeLog	2022-01-04 23:31:23 UTC (rev 287592)
+++ trunk/LayoutTests/ChangeLog	2022-01-04 23:48:08 UTC (rev 287593)
@@ -1,3 +1,13 @@
+2022-01-04  Simon Fraser  <simon.fra...@apple.com>
+
+        "canceled" wheel events to non-zero deltas cause scrolling jumps in PDFs and CodeMirror
+        https://bugs.webkit.org/show_bug.cgi?id=234825
+
+        Reviewed by Tim Horton.
+
+        * fast/scrolling/mac/canceled-event-with-non-zero-deltas-expected.txt: Added.
+        * fast/scrolling/mac/canceled-event-with-non-zero-deltas.html: Added.
+
 2022-01-04  Devin Rousso  <drou...@apple.com>
 
         Web Inspector: Sources: expanding a grouping of blackboxed call frames should be persistent

Added: trunk/LayoutTests/fast/scrolling/mac/canceled-event-with-non-zero-deltas-expected.txt (0 => 287593)


--- trunk/LayoutTests/fast/scrolling/mac/canceled-event-with-non-zero-deltas-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/canceled-event-with-non-zero-deltas-expected.txt	2022-01-04 23:48:08 UTC (rev 287593)
@@ -0,0 +1,9 @@
+wheel event deltaY 10
+wheel event deltaY 30
+wheel event deltaY 40
+wheel event deltaY 32
+wheel event deltaY 20
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/scrolling/mac/canceled-event-with-non-zero-deltas.html (0 => 287593)


--- trunk/LayoutTests/fast/scrolling/mac/canceled-event-with-non-zero-deltas.html	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/canceled-event-with-non-zero-deltas.html	2022-01-04 23:48:08 UTC (rev 287593)
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        body {
+            height: 2000px;
+            width: 200%;
+        }
+    </style>
+    <script src=""
+    <script src=""
+    <script>
+        var jsTestIsAsync = true;
+
+        async function scrollTest()
+        {
+            const events = [
+                {
+                    type : "wheel",
+                    viewX : 100,
+                    viewY : 100,
+                    deltaY : -10,
+                    phase : "began"
+                },
+                {
+                    type : "wheel",
+                    deltaY : -30,
+                    phase : "changed"
+                },
+                {
+                    type : "wheel",
+                    phase : "ended"
+                },
+                {
+                    type : "wheel",
+                    deltaY : -40,
+                    momentumPhase : "began"
+                },
+                {
+                    type: "wheel",
+                    deltaY : -32,
+                    momentumPhase: "changed"
+                },
+                {
+                    type: "wheel",
+                    viewX : 101, // defeat coalescing
+                    deltaY : -20,
+                    momentumPhase: "changed"
+                },
+                {
+                    type: "wheel",
+                    momentumPhase: "ended"
+                },
+                {
+                    type: "wheel",
+                    phase: "maybegin"
+                },
+                {
+                    type: "wheel",
+                    deltaX : 10,
+                    deltaY : 100,
+                    phase: "cancelled"
+                }
+            ];
+
+            await UIHelper.mouseWheelSequence({ events });
+            finishJSTest();
+        }
+
+        window.addEventListener('load', () => {
+            window.addEventListener('wheel', (event) => {
+                debug('wheel event deltaY ' + event.deltaY);
+            }, { passive: true });
+
+            setTimeout(scrollTest, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <script src=""
+</body>
+</html>

Modified: trunk/Source/WebKit/ChangeLog (287592 => 287593)


--- trunk/Source/WebKit/ChangeLog	2022-01-04 23:31:23 UTC (rev 287592)
+++ trunk/Source/WebKit/ChangeLog	2022-01-04 23:48:08 UTC (rev 287593)
@@ -1,3 +1,26 @@
+2022-01-04  Simon Fraser  <simon.fra...@apple.com>
+
+        "canceled" wheel events to non-zero deltas cause scrolling jumps in PDFs and CodeMirror
+        https://bugs.webkit.org/show_bug.cgi?id=234825
+
+        Reviewed by Tim Horton.
+
+        On some macOS versions, interrupting a momentum scroll via a two-finger tap on the trackpad can
+        result in the following sequence of wheel events: momentumPhase:end -> phase:mayBegin -> phase:cancelled,
+        and that last canceled event can have non-zero deltas (rdar://86653042).
+
+        Protect against this by zeroing out the deltas for cancelled wheel events when constructing WebEvents
+        from NSEvents. Code in Element::dispatchWheelEvent() ensures that we don't dispatch wheel events with
+        zero deltas to script, fixing CodeMirror.
+
+        Jumps only affected PDFs (and scrollable selects) because those are the code paths that don't go via
+        ScrollingEffectsController, which already ignores Cancelled events.
+
+        Test: fast/scrolling/mac/canceled-event-with-non-zero-deltas.html
+
+        * Shared/mac/WebEventFactory.mm:
+        (WebKit::WebEventFactory::createWebWheelEvent):
+
 2022-01-04  Wenson Hsieh  <wenson_hs...@apple.com>
 
         Use ICU instead of relying on hard-coded string equality checks in ModalContainerControlClassifier

Modified: trunk/Source/WebKit/Shared/mac/WebEventFactory.mm (287592 => 287593)


--- trunk/Source/WebKit/Shared/mac/WebEventFactory.mm	2022-01-04 23:31:23 UTC (rev 287592)
+++ trunk/Source/WebKit/Shared/mac/WebEventFactory.mm	2022-01-04 23:48:08 UTC (rev 287593)
@@ -438,6 +438,15 @@
 
     auto ioHIDEventWallTime = WebCore::eventTimeStampSince1970(ioHIDEventTimestamp);
 
+    if (phase == WebWheelEvent::PhaseCancelled) {
+        deltaX = 0;
+        deltaY = 0;
+        wheelTicksX = 0;
+        wheelTicksY = 0;
+        unacceleratedScrollingDelta = { };
+        rawPlatformDelta = std::nullopt;
+    }
+
     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);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to