Diff
Modified: trunk/LayoutTests/ChangeLog (266261 => 266262)
--- trunk/LayoutTests/ChangeLog 2020-08-27 23:43:34 UTC (rev 266261)
+++ trunk/LayoutTests/ChangeLog 2020-08-27 23:47:54 UTC (rev 266262)
@@ -1,3 +1,13 @@
+2020-08-27 Simon Fraser <[email protected]>
+
+ Scrolling on select element doesn't work after scrolling the page
+ https://bugs.webkit.org/show_bug.cgi?id=215900
+
+ Reviewed by Tim Horton.
+
+ * fast/scrolling/latching/latching-stuck-to-main-page-expected.txt: Added.
+ * fast/scrolling/latching/latching-stuck-to-main-page.html: Added.
+
2020-08-27 Joonghun Park <[email protected]>
Implement @supports selector().
Added: trunk/LayoutTests/fast/scrolling/latching/latching-stuck-to-main-page-expected.txt (0 => 266262)
--- trunk/LayoutTests/fast/scrolling/latching/latching-stuck-to-main-page-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/latching/latching-stuck-to-main-page-expected.txt 2020-08-27 23:47:54 UTC (rev 266262)
@@ -0,0 +1,21 @@
+
+Tests that scrolling doesn't get wrongly latched to the main page.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Checking wheel event over the select
+PASS selectScrollCount > 0 is true
+PASS pageScrollCount == 0 is true
+Triggering main page latch; scrolling down
+Triggering main page latch; scrolling up
+PASS selectScrollCount == 0 is true
+PASS pageScrollCount > 0 is true
+PASS document.scrollingElement.scrollTop == 0 is true
+Checking wheel event over the select again
+PASS selectScrollCount > 0 is true
+PASS pageScrollCount == 0 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/scrolling/latching/latching-stuck-to-main-page.html (0 => 266262)
--- trunk/LayoutTests/fast/scrolling/latching/latching-stuck-to-main-page.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/latching/latching-stuck-to-main-page.html 2020-08-27 23:47:54 UTC (rev 266262)
@@ -0,0 +1,111 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+<style>
+ body {
+ height: 2000px;
+ }
+ select {
+ margin-top: 100px;
+ font-size: 12pt;
+ }
+</style>
+<script src=""
+<script src=""
+<script>
+ jsTestIsAsync = true;
+
+ let selectScrollCount = 0;
+ let pageScrollCount = 0;
+
+ async function scrollTest()
+ {
+ let select = document.getElementsByTagName('select')[0];
+ select.addEventListener('scroll', () => {
+ ++selectScrollCount;
+ });
+
+ window.addEventListener('scroll', () => {
+ ++pageScrollCount;
+ });
+
+ debug('Checking wheel event over the select');
+ await UIHelper.mouseWheelScrollAt(50, 200);
+
+ shouldBeTrue('selectScrollCount > 0');
+ shouldBeTrue('pageScrollCount == 0');
+
+ selectScrollCount = 0;
+
+ debug('Triggering main page latch; scrolling down');
+ await UIHelper.mouseWheelScrollAt(400, 200);
+
+ await UIHelper.animationFrame();
+
+ debug('Triggering main page latch; scrolling up');
+
+ eventSender.mouseMoveTo(400, 200);
+ eventSender.monitorWheelEvents({ resetLatching: false });
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 2, 'began', 'none');
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 11, 'changed', 'none');
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none');
+ await UIHelper.waitForScrollCompletion();
+
+ shouldBeTrue('selectScrollCount == 0');
+ shouldBeTrue('pageScrollCount > 0');
+
+ shouldBeTrue('document.scrollingElement.scrollTop == 0');
+
+ // Stupid hack to reset the select back to the top (webkit.org/b/215898).
+ pageScrollCount = 0;
+ select.style.display = 'none';
+ document.body.offsetWidth;
+ select.style.display = 'inline';
+
+ // Delay for longer than resetLatchedStateTimeout.
+ await UIHelper.delayFor(150);
+
+ debug('Checking wheel event over the select again');
+ eventSender.mouseMoveTo(50, 200);
+ eventSender.monitorWheelEvents({ resetLatching: false });
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none');
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -5, 'changed', 'none');
+ eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none');
+ await UIHelper.waitForScrollCompletion();
+
+ shouldBeTrue('selectScrollCount > 0');
+ shouldBeTrue('pageScrollCount == 0');
+
+ finishJSTest();
+ }
+
+ window.addEventListener('load', () => {
+ description("Tests that scrolling doesn't get wrongly latched to the main page.");
+ setTimeout(scrollTest, 0);
+ }, false);
+</script>
+</head>
+<body>
+ <select size="10">
+ <option>first first first</option>
+ <option>two two two two</option>
+ <option>one one one one</option>
+ <option>two two two two</option>
+ <option>one one one one</option>
+ <option>two two two two</option>
+ <option>one one one one</option>
+ <option>two two two two</option>
+ <option>one one one one</option>
+ <option>two two two two</option>
+ <option>one one one one</option>
+ <option>two two two two</option>
+ <option>one one one one</option>
+ <option>two two two two</option>
+ <option>one one one one</option>
+ <option>two two two two</option>
+ <option>last last last</option>
+ </select>
+ <div id="console"></div>
+<script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (266261 => 266262)
--- trunk/Source/WebCore/ChangeLog 2020-08-27 23:43:34 UTC (rev 266261)
+++ trunk/Source/WebCore/ChangeLog 2020-08-27 23:47:54 UTC (rev 266262)
@@ -1,3 +1,22 @@
+2020-08-27 Simon Fraser <[email protected]>
+
+ Scrolling on select element doesn't work after scrolling the page
+ https://bugs.webkit.org/show_bug.cgi?id=215900
+ <rdar://problem/67766032>
+
+ Reviewed by Tim Horton.
+
+ The scrolling thread could use a node that was latched some time ago; we need to
+ check the freshness of the latched node before using it.
+
+ Test: fast/scrolling/latching/latching-stuck-to-main-page.html
+
+ * page/scrolling/ScrollingTreeLatchingController.cpp:
+ (WebCore::ScrollingTreeLatchingController::receivedWheelEvent):
+ (WebCore::ScrollingTreeLatchingController::latchedNodeForEvent const):
+ (WebCore::ScrollingTreeLatchingController::latchedNodeIsRelevant const):
+ * page/scrolling/ScrollingTreeLatchingController.h:
+
2020-08-27 Chris Dumez <[email protected]>
Fix AudioParam.linearRampToValueAtTime() formula to match specification
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp (266261 => 266262)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp 2020-08-27 23:43:34 UTC (rev 266261)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp 2020-08-27 23:47:54 UTC (rev 266262)
@@ -47,14 +47,9 @@
return;
LockHolder locker(m_latchedNodeMutex);
- if (wheelEvent.shouldConsiderLatching()) {
- if (m_latchedNodeID) {
- auto secondsSinceLastInteraction = MonotonicTime::now() - m_lastLatchedNodeInterationTime;
- if (secondsSinceLastInteraction > resetLatchedStateTimeout) {
- LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTreeLatchingController " << this << " receivedWheelEvent - " << secondsSinceLastInteraction.milliseconds() << "ms since last event, clearing latched node");
- m_latchedNodeID.reset();
- }
- }
+ if (wheelEvent.shouldConsiderLatching() && m_latchedNodeID && !latchedNodeIsRelevant()) {
+ LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTreeLatchingController " << this << " receivedWheelEvent - " << (MonotonicTime::now() - m_lastLatchedNodeInterationTime).milliseconds() << "ms since last event, clearing latched node");
+ m_latchedNodeID.reset();
}
}
@@ -66,7 +61,7 @@
LockHolder locker(m_latchedNodeMutex);
// If we have a latched node, use it.
- if (wheelEvent.useLatchedEventElement() && m_latchedNodeID) {
+ if (wheelEvent.useLatchedEventElement() && m_latchedNodeID && latchedNodeIsRelevant()) {
LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTreeLatchingController " << this << " latchedNodeForEvent: returning " << m_latchedNodeID);
return m_latchedNodeID.value();
}
@@ -114,6 +109,12 @@
m_latchedNodeID.reset();
}
-};
+bool ScrollingTreeLatchingController::latchedNodeIsRelevant() const
+{
+ auto secondsSinceLastInteraction = MonotonicTime::now() - m_lastLatchedNodeInterationTime;
+ return secondsSinceLastInteraction < resetLatchedStateTimeout;
+}
+} // namespace WebCore
+
#endif // ENABLE(ASYNC_SCROLLING)
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h (266261 => 266262)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h 2020-08-27 23:43:34 UTC (rev 266261)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h 2020-08-27 23:47:54 UTC (rev 266262)
@@ -51,6 +51,8 @@
void clearLatchedNode();
private:
+ bool latchedNodeIsRelevant() const;
+
mutable Lock m_latchedNodeMutex;
Markable<ScrollingNodeID, IntegralMarkableTraits<ScrollingNodeID, 0>> m_latchedNodeID;
MonotonicTime m_lastLatchedNodeInterationTime;