Diff
Modified: trunk/LayoutTests/ChangeLog (261131 => 261132)
--- trunk/LayoutTests/ChangeLog 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/LayoutTests/ChangeLog 2020-05-05 00:59:07 UTC (rev 261132)
@@ -1,3 +1,17 @@
+2020-05-04 Simon Fraser <[email protected]>
+
+ Overflow scrollbars don't grow when hovered
+ https://bugs.webkit.org/show_bug.cgi?id=210692
+ <rdar://problem/61977273>
+
+ Reviewed by Tim Horton.
+
+ * fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-hovered-expected.txt: Added.
+ * fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-hovered.html: Added.
+ * fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-reveal-expected.txt: Added.
+ * fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-reveal.html: Copied from LayoutTests/fast/scrolling/mac/scrollbars/overlay-scrollbar-reveal.html.
+ * fast/scrolling/mac/scrollbars/overlay-scrollbar-reveal.html:
+
2020-05-04 Jack Lee <[email protected]>
Nullptr crash in CompositeEditCommand::moveParagraphs when changing style on elements that are
Added: trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-hovered-expected.txt (0 => 261132)
--- trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-hovered-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-hovered-expected.txt 2020-05-05 00:59:07 UTC (rev 261132)
@@ -0,0 +1,15 @@
+Test hover over overlay scrollbar
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Initial state
+enabled
+Hovering vertical scrollbar should show expanded scrollbar
+PASS Scrollbar state: enabled,expanded,visible_track,visible_thumb
+Unhovering vertical scrollbar should hide it
+PASS Thumb and track hidden
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-hovered.html (0 => 261132)
--- trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-hovered.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-hovered.html 2020-05-05 00:59:07 UTC (rev 261132)
@@ -0,0 +1,82 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:useMockScrollbars=false internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <style>
+ body {
+ height: 1000px;
+ }
+ .scroller {
+ margin: 10px;
+ width: 200px;
+ height: 200px;
+ border: 1px solid black;
+ overflow: auto;
+ }
+ .contents {
+ width: 100%;
+ height: 200%;
+ }
+ </style>
+ <script src=""
+ <script src=""
+
+ <script>
+ jsTestIsAsync = true;
+
+ if (window.internals)
+ internals.setUsesOverlayScrollbars(true);
+
+ async function doTest()
+ {
+ description('Test hover over overlay scrollbar');
+ if (!window.internals) {
+ finishJSTest();
+ return;
+ }
+
+ const scroller = document.querySelector('.scroller');
+ const scrollerBounds = scroller.getBoundingClientRect();
+ const x = scrollerBounds.right - 8;
+ const y = scrollerBounds.top + 10;
+
+ debug('Initial state');
+ debug(internals.verticalScrollbarState(scroller));
+
+ debug('Hovering vertical scrollbar should show expanded scrollbar');
+ await UIHelper.mouseWheelScrollAt(x, y);
+ await UIHelper.waitForCondition(() => {
+ let state = internals.verticalScrollbarState(scroller);
+ let expanded = state.indexOf('expanded') != -1;
+ if (expanded)
+ testPassed('Scrollbar state: ' + state);
+ return expanded;
+ });
+
+ debug('Unhovering vertical scrollbar should hide it');
+ await UIHelper.moveMouseAndWaitForFrame(x - 10, y);
+ await UIHelper.moveMouseAndWaitForFrame(x - 20, y);
+ await UIHelper.waitForCondition(() => {
+ let state = internals.verticalScrollbarState(scroller);
+ let thumbHidden = state.indexOf('visible_thumb') == -1;
+ let trackHidden = state.indexOf('visible_track') == -1;
+ if (thumbHidden && trackHidden)
+ testPassed('Thumb and track hidden');
+ return thumbHidden && trackHidden;
+ });
+
+ finishJSTest();
+ }
+
+ window.addEventListener('load', () => {
+ doTest();
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="contents"></div>
+ </div>
+ <div id="console"></div>
+ <script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-reveal-expected.txt (0 => 261132)
--- trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-reveal-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-reveal-expected.txt 2020-05-05 00:59:07 UTC (rev 261132)
@@ -0,0 +1,15 @@
+Test maybegin and cancelled on overflow
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Initial state
+enabled
+MayBegin should show the scrollbar
+PASS Scrollbar state: enabled,visible_thumb
+Cancelled should hide the scrollbar
+PASS Scrollbar state: enabled
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Copied: trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-reveal.html (from rev 261131, trunk/LayoutTests/fast/scrolling/mac/scrollbars/overlay-scrollbar-reveal.html) (0 => 261132)
--- trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-reveal.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-reveal.html 2020-05-05 00:59:07 UTC (rev 261132)
@@ -0,0 +1,81 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:useMockScrollbars=false internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <style>
+ body {
+ height: 1000px;
+ }
+ .scroller {
+ margin: 10px;
+ width: 200px;
+ height: 200px;
+ border: 1px solid black;
+ overflow: auto;
+ }
+ .contents {
+ width: 100%;
+ height: 200%;
+ }
+ </style>
+ <script src=""
+ <script src=""
+
+ <script>
+ jsTestIsAsync = true;
+
+ if (window.internals)
+ internals.setUsesOverlayScrollbars(true);
+
+ async function doTest()
+ {
+ description('Test maybegin and cancelled on overflow');
+ if (!window.internals) {
+ finishJSTest();
+ return;
+ }
+
+ const scroller = document.querySelector('.scroller');
+ const scrollerBounds = scroller.getBoundingClientRect();
+ const x = scrollerBounds.left + 10;
+ const y = scrollerBounds.top + 10;
+
+ debug('Initial state');
+ debug(internals.verticalScrollbarState(scroller));
+
+ debug('MayBegin should show the scrollbar');
+ await UIHelper.mouseWheelMayBeginAt(x, y);
+ await UIHelper.waitForCondition(() => {
+ let state = internals.verticalScrollbarState(scroller);
+ let visible = state.indexOf('visible_thumb') != -1;
+ if (visible)
+ testPassed('Scrollbar state: ' + state);
+ return visible;
+ });
+
+ debug('Cancelled should hide the scrollbar');
+ await UIHelper.mouseWheelCancelAt(x, y);
+
+ await UIHelper.waitForCondition(() => {
+ let state = internals.verticalScrollbarState(scroller);
+ let hidden = state.indexOf('visible_thumb') == -1;
+ if (hidden)
+ testPassed('Scrollbar state: ' + state);
+ return hidden;
+ });
+
+ finishJSTest();
+ }
+
+ window.addEventListener('load', () => {
+ doTest();
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="contents"></div>
+ </div>
+ <div id="console"></div>
+ <script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/fast/scrolling/mac/scrollbars/overlay-scrollbar-reveal.html (261131 => 261132)
--- trunk/LayoutTests/fast/scrolling/mac/scrollbars/overlay-scrollbar-reveal.html 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/LayoutTests/fast/scrolling/mac/scrollbars/overlay-scrollbar-reveal.html 2020-05-05 00:59:07 UTC (rev 261132)
@@ -1,4 +1,4 @@
-<!DOCTYPE html> <!-- webkit-test-runner [ internal:useMockScrollbars=false ] -->
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:useMockScrollbars=false internal:AsyncOverflowScrollingEnabled=true ] -->
<html>
<head>
<style>
@@ -12,13 +12,16 @@
<script>
jsTestIsAsync = true;
- window.internals.setUsesOverlayScrollbars(true);
+ if (window.internals)
+ internals.setUsesOverlayScrollbars(true);
async function doTest()
{
description('Test maybegin and cancelled');
- if (!window.internals)
+ if (!window.internals) {
+ finishJSTest();
return;
+ }
debug('Initial state');
debug(internals.verticalScrollbarState());
Modified: trunk/Source/WebCore/ChangeLog (261131 => 261132)
--- trunk/Source/WebCore/ChangeLog 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/ChangeLog 2020-05-05 00:59:07 UTC (rev 261132)
@@ -1,3 +1,72 @@
+2020-05-04 Simon Fraser <[email protected]>
+
+ Overflow scrollbars don't grow when hovered
+ https://bugs.webkit.org/show_bug.cgi?id=210692
+ <rdar://problem/61977273>
+
+ Reviewed by Tim Horton.
+
+ Overlay scrollar interaction has a few behaviors that are mediated by ScrollAnimatorMac. These
+ are a trackpad two-finger tap, which sends a "MayBegin" wheel event (which can be followed by
+ a "Cancelled" on fingers up, if they didn't move), and hovering the scrollbar when visible, which
+ causes it to expand (unhovering causes it to fade out).
+
+ To track these gestures on the scrolling thread, give ScrollingTree a ScrollingTreeGestureState.
+
+ Flashing the scrollbars on "MayBegin" is driven by didBeginScrollGesture()/didEndScrollGesture().
+ This relies on sending these for the correct scrollable area, and matching the begin/cancel,
+ so use the normal scrolling tree event handling code path for "MayBegin", and always send
+ "Cancelled" on the node that received "MayBegin. Do the same for "Began" and "Ended".
+
+ Scrollbars expanding on hover is controlled by these functions on ScrollAnimatorMac:
+ void mouseEnteredContentArea();
+ void mouseExitedContentArea();
+ void mouseMovedInContentArea();
+ void mouseEnteredScrollbar(Scrollbar*) const;
+ void mouseExitedScrollbar(Scrollbar*) const;
+
+ This mostly (webkit.org/b/211347) works now that the mayBegin/Canceled state is updated correctly,
+ and is tested by a new test.
+
+ Tests: fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-hovered.html
+ fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-reveal.html
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * page/scrolling/ScrollingTree.cpp:
+ (WebCore::ScrollingTree::ScrollingTree):
+ (WebCore::ScrollingTree::handleWheelEvent):
+ * page/scrolling/ScrollingTree.h:
+ * page/scrolling/ScrollingTreeGestureState.cpp: Added.
+ (WebCore::ScrollingTreeGestureState::ScrollingTreeGestureState):
+ (WebCore::ScrollingTreeGestureState::receivedWheelEvent):
+ (WebCore::ScrollingTreeGestureState::handleGestureCancel):
+ (WebCore::ScrollingTreeGestureState::nodeDidHandleEvent):
+ (WebCore::ScrollingTreeGestureState::clearAllNodes):
+ * page/scrolling/ScrollingTreeGestureState.h: Copied from Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h.
+ * page/scrolling/ScrollingTreeLatchingController.cpp:
+ (WebCore::ScrollingTreeLatchingController::nodeDidHandleEvent):
+ * page/scrolling/ScrollingTreeLatchingController.h:
+ * page/scrolling/ScrollingTreeScrollingNode.cpp:
+ (WebCore::ScrollingTreeScrollingNode::canHandleWheelEvent const):
+ (WebCore::ScrollingTreeScrollingNode::canScrollWithWheelEvent const): Deleted.
+ * page/scrolling/ScrollingTreeScrollingNode.h:
+ * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
+ (WebCore::ScrollingTreeFrameScrollingNodeMac::handleWheelEvent):
+ * page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm:
+ (WebCore::ScrollingTreeOverflowScrollingNodeMac::handleWheelEvent):
+ * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
+ (WebCore::ScrollingTreeScrollingNodeDelegateMac::handleWheelEvent):
+ * platform/Logging.cpp:
+ (WebCore::initializeLogChannelsIfNecessary):
+ * platform/PlatformWheelEvent.h:
+ (WebCore::PlatformWheelEvent::isGestureStart const):
+ (WebCore::PlatformWheelEvent::isGestureCancel const):
+ * platform/cocoa/ScrollController.mm:
+ (WebCore::ScrollController::handleWheelEvent):
+ * platform/mac/ScrollAnimatorMac.mm:
+ (WebCore::scrollbarState):
+
2020-05-04 Commit Queue <[email protected]>
Unreviewed, reverting r261102.
Modified: trunk/Source/WebCore/Headers.cmake (261131 => 261132)
--- trunk/Source/WebCore/Headers.cmake 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/Headers.cmake 2020-05-05 00:59:07 UTC (rev 261132)
@@ -908,6 +908,7 @@
page/scrolling/ScrollingTree.h
page/scrolling/ScrollingTreeFrameHostingNode.h
page/scrolling/ScrollingTreeFrameScrollingNode.h
+ page/scrolling/ScrollingTreeGestureState.h
page/scrolling/ScrollingTreeLatchingController.h
page/scrolling/ScrollingTreeNode.h
page/scrolling/ScrollingTreeOverflowScrollingNode.h
Modified: trunk/Source/WebCore/Sources.txt (261131 => 261132)
--- trunk/Source/WebCore/Sources.txt 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/Sources.txt 2020-05-05 00:59:07 UTC (rev 261132)
@@ -1742,6 +1742,7 @@
page/scrolling/ScrollingTree.cpp
page/scrolling/ScrollingTreeFrameHostingNode.cpp
page/scrolling/ScrollingTreeFrameScrollingNode.cpp
+page/scrolling/ScrollingTreeGestureState.cpp
page/scrolling/ScrollingTreeLatchingController.cpp
page/scrolling/ScrollingTreeNode.cpp
page/scrolling/ScrollingTreeOverflowScrollingNode.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (261131 => 261132)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-05-05 00:59:07 UTC (rev 261132)
@@ -348,6 +348,7 @@
0FD41E6821F80C0E000C006D /* ScrollingTreeFrameHostingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD41E6621F80282000C006D /* ScrollingTreeFrameHostingNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FD41E6921F80D14000C006D /* ScrollingStateFrameHostingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD41E6521F80261000C006D /* ScrollingStateFrameHostingNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FD723820EC8BD9300CA5DD7 /* FloatQuad.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD723800EC8BD9300CA5DD7 /* FloatQuad.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FD975D5245CCB4700C42299 /* ScrollingTreeGestureState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD975D2245CBDAF00C42299 /* ScrollingTreeGestureState.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FDA7C17188322EB00C954B5 /* JSTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDA7C11188322EB00C954B5 /* JSTouch.h */; };
0FDA7C19188322EB00C954B5 /* JSTouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDA7C13188322EB00C954B5 /* JSTouchEvent.h */; };
0FDA7C1B188322EB00C954B5 /* JSTouchList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDA7C15188322EB00C954B5 /* JSTouchList.h */; };
@@ -5932,6 +5933,8 @@
0FD723800EC8BD9300CA5DD7 /* FloatQuad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FloatQuad.h; sourceTree = "<group>"; };
0FD723810EC8BD9300CA5DD7 /* FloatQuad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FloatQuad.cpp; sourceTree = "<group>"; };
0FD7C21D23CE41E30096D102 /* PlatformWheelEvent.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformWheelEvent.cpp; sourceTree = "<group>"; };
+ 0FD975D2245CBDAF00C42299 /* ScrollingTreeGestureState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeGestureState.h; sourceTree = "<group>"; };
+ 0FD975D4245CBDD700C42299 /* ScrollingTreeGestureState.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingTreeGestureState.cpp; sourceTree = "<group>"; };
0FDA7C10188322EB00C954B5 /* JSTouch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTouch.cpp; sourceTree = "<group>"; };
0FDA7C11188322EB00C954B5 /* JSTouch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTouch.h; sourceTree = "<group>"; };
0FDA7C12188322EB00C954B5 /* JSTouchEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTouchEvent.cpp; sourceTree = "<group>"; };
@@ -17636,6 +17639,8 @@
0FD41E6621F80282000C006D /* ScrollingTreeFrameHostingNode.h */,
0FEA3E85191B3BD7000F1B55 /* ScrollingTreeFrameScrollingNode.cpp */,
0FEA3E86191B3BD7000F1B55 /* ScrollingTreeFrameScrollingNode.h */,
+ 0FD975D4245CBDD700C42299 /* ScrollingTreeGestureState.cpp */,
+ 0FD975D2245CBDAF00C42299 /* ScrollingTreeGestureState.h */,
0FFD45A8243BF257000D4BEA /* ScrollingTreeLatchingController.cpp */,
0FFD45A7243BF257000D4BEA /* ScrollingTreeLatchingController.h */,
1AAADDE114DC8C8F00AF64B3 /* ScrollingTreeNode.cpp */,
@@ -32791,6 +32796,7 @@
0FD41E6821F80C0E000C006D /* ScrollingTreeFrameHostingNode.h in Headers */,
0FEA3E88191B3BD7000F1B55 /* ScrollingTreeFrameScrollingNode.h in Headers */,
93C4A4151629DF5A00C3EB6E /* ScrollingTreeFrameScrollingNodeMac.h in Headers */,
+ 0FD975D5245CCB4700C42299 /* ScrollingTreeGestureState.h in Headers */,
0FFD45AA243C3027000D4BEA /* ScrollingTreeLatchingController.h in Headers */,
0FE5806419327A6200DE32EB /* ScrollingTreeMac.h in Headers */,
1AAADDE414DC8C8F00AF64B3 /* ScrollingTreeNode.h in Headers */,
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (261131 => 261132)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2020-05-05 00:59:07 UTC (rev 261132)
@@ -56,7 +56,11 @@
OrphanScrollingNodeMap orphanNodes;
};
-ScrollingTree::ScrollingTree() = default;
+ScrollingTree::ScrollingTree()
+ : m_gestureState(*this)
+{
+}
+
ScrollingTree::~ScrollingTree() = default;
bool ScrollingTree::shouldHandleWheelEventSynchronously(const PlatformWheelEvent& wheelEvent)
@@ -106,11 +110,20 @@
return ScrollingEventResult::DidNotHandleEvent;
}
+ if (m_gestureState.handleGestureCancel(wheelEvent))
+ return ScrollingEventResult::DidHandleEvent;
+
+ m_gestureState.receivedWheelEvent(wheelEvent);
+
if (auto latchedNodeID = m_latchingController.latchedNodeForEvent(wheelEvent)) {
LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTree::handleWheelEvent: has latched node " << latchedNodeID);
- auto* node = nodeForID(latchedNodeID.value());
- if (is<ScrollingTreeScrollingNode>(node))
- return downcast<ScrollingTreeScrollingNode>(*node).handleWheelEvent(wheelEvent);
+ auto* node = nodeForID(*latchedNodeID);
+ if (is<ScrollingTreeScrollingNode>(node)) {
+ auto result = downcast<ScrollingTreeScrollingNode>(*node).handleWheelEvent(wheelEvent);
+ if (result == ScrollingEventResult::DidHandleEvent)
+ m_gestureState.nodeDidHandleEvent(*latchedNodeID, wheelEvent);
+ return result;
+ }
}
FloatPoint position = wheelEvent.position();
@@ -124,8 +137,10 @@
auto& scrollingNode = downcast<ScrollingTreeScrollingNode>(*node);
auto result = scrollingNode.handleWheelEvent(wheelEvent);
- if (result == ScrollingEventResult::DidHandleEvent)
- m_latchingController.nodeDidHandleEvent(wheelEvent, scrollingNode.scrollingNodeID());
+ if (result == ScrollingEventResult::DidHandleEvent) {
+ m_latchingController.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), wheelEvent);
+ m_gestureState.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), wheelEvent);
+ }
if (result != ScrollingEventResult::DidNotHandleEvent)
return result;
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (261131 => 261132)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2020-05-05 00:59:07 UTC (rev 261132)
@@ -34,6 +34,7 @@
#include "Region.h"
#include "ScrollTypes.h"
#include "ScrollingCoordinatorTypes.h"
+#include "ScrollingTreeGestureState.h"
#include "ScrollingTreeLatchingController.h"
#include "WheelEventTestMonitor.h"
#include <wtf/HashMap.h>
@@ -123,6 +124,8 @@
virtual void deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) { }
virtual void removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) { }
+#else
+ void handleWheelEventPhase(ScrollingNodeID, PlatformWheelEventPhase) { }
#endif
#if PLATFORM(COCOA)
@@ -201,6 +204,8 @@
ScrollingTreeNodeMap m_nodeMap;
ScrollingTreeLatchingController m_latchingController;
+ ScrollingTreeGestureState m_gestureState;
+
RelatedNodesMap m_overflowRelatedNodesMap;
HashSet<Ref<ScrollingTreeOverflowScrollProxyNode>> m_activeOverflowScrollProxyNodes;
Added: trunk/Source/WebCore/page/scrolling/ScrollingTreeGestureState.cpp (0 => 261132)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeGestureState.cpp (rev 0)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeGestureState.cpp 2020-05-05 00:59:07 UTC (rev 261132)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollingTreeGestureState.h"
+
+#if ENABLE(ASYNC_SCROLLING)
+
+#include "PlatformWheelEvent.h"
+
+namespace WebCore {
+
+
+ScrollingTreeGestureState::ScrollingTreeGestureState(ScrollingTree& scrollingTree)
+ : m_scrollingTree(scrollingTree)
+{
+}
+
+void ScrollingTreeGestureState::receivedWheelEvent(const PlatformWheelEvent& event)
+{
+ if (event.isGestureBegin()) {
+ clearAllNodes();
+ return;
+ }
+}
+
+bool ScrollingTreeGestureState::handleGestureCancel(const PlatformWheelEvent& event)
+{
+ if (event.isGestureCancel()) {
+ if (m_mayBeginNodeID)
+ m_scrollingTree.handleWheelEventPhase(*m_mayBeginNodeID, PlatformWheelEventPhaseCancelled);
+ return true;
+ }
+
+ return false;
+}
+
+void ScrollingTreeGestureState::nodeDidHandleEvent(ScrollingNodeID nodeID, const PlatformWheelEvent& event)
+{
+ switch (event.phase()) {
+ case PlatformWheelEventPhaseMayBegin:
+ m_mayBeginNodeID = nodeID;
+ m_scrollingTree.handleWheelEventPhase(nodeID, event.phase());
+ break;
+ case PlatformWheelEventPhaseCancelled:
+ // handleGestureCancel() should have been called first.
+ ASSERT_NOT_REACHED();
+ break;
+ case PlatformWheelEventPhaseBegan:
+ m_activeNodeID = nodeID;
+ m_scrollingTree.handleWheelEventPhase(nodeID, event.phase());
+ break;
+ case PlatformWheelEventPhaseEnded:
+ if (m_activeNodeID)
+ m_scrollingTree.handleWheelEventPhase(*m_activeNodeID, event.phase());
+ break;
+ case PlatformWheelEventPhaseChanged:
+ case PlatformWheelEventPhaseStationary:
+ case PlatformWheelEventPhaseNone:
+ break;
+ }
+
+ switch (event.momentumPhase()) {
+ case PlatformWheelEventPhaseMayBegin:
+ case PlatformWheelEventPhaseCancelled:
+ ASSERT_NOT_REACHED();
+ break;
+ case PlatformWheelEventPhaseBegan:
+ m_activeNodeID = nodeID;
+ m_scrollingTree.handleWheelEventPhase(nodeID, event.momentumPhase());
+ break;
+ case PlatformWheelEventPhaseEnded:
+ if (m_activeNodeID)
+ m_scrollingTree.handleWheelEventPhase(*m_activeNodeID, event.momentumPhase());
+ break;
+ case PlatformWheelEventPhaseChanged:
+ case PlatformWheelEventPhaseStationary:
+ case PlatformWheelEventPhaseNone:
+ break;
+ }
+}
+
+void ScrollingTreeGestureState::clearAllNodes()
+{
+ m_mayBeginNodeID = 0;
+ m_activeNodeID = 0;
+}
+
+};
+
+#endif // ENABLE(ASYNC_SCROLLING)
Copied: trunk/Source/WebCore/page/scrolling/ScrollingTreeGestureState.h (from rev 261131, trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h) (0 => 261132)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeGestureState.h (rev 0)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeGestureState.h 2020-05-05 00:59:07 UTC (rev 261132)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(ASYNC_SCROLLING)
+
+#include "ScrollTypes.h"
+#include <wtf/Markable.h>
+#include <wtf/Optional.h>
+
+namespace WebCore {
+
+class PlatformWheelEvent;
+class ScrollingTree;
+
+// This class tracks state related to MayBegin, Begin, Ended and Canceled wheel events, which
+// should propagate to the main thread in order to update overlay scrollbars.
+class ScrollingTreeGestureState {
+public:
+ ScrollingTreeGestureState(ScrollingTree&);
+
+ void receivedWheelEvent(const PlatformWheelEvent&);
+
+ bool handleGestureCancel(const PlatformWheelEvent&);
+
+ void nodeDidHandleEvent(ScrollingNodeID, const PlatformWheelEvent&);
+
+private:
+ void clearAllNodes();
+
+ ScrollingTree& m_scrollingTree;
+ Markable<ScrollingNodeID, IntegralMarkableTraits<ScrollingNodeID, 0>> m_mayBeginNodeID;
+ Markable<ScrollingNodeID, IntegralMarkableTraits<ScrollingNodeID, 0>> m_activeNodeID;
+};
+
+}
+
+#endif // ENABLE(ASYNC_SCROLLING)
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp (261131 => 261132)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp 2020-05-05 00:59:07 UTC (rev 261132)
@@ -74,7 +74,7 @@
return m_latchedNodeID;
}
-void ScrollingTreeLatchingController::nodeDidHandleEvent(const PlatformWheelEvent& wheelEvent, ScrollingNodeID scrollingNodeID)
+void ScrollingTreeLatchingController::nodeDidHandleEvent(ScrollingNodeID scrollingNodeID, const PlatformWheelEvent& wheelEvent)
{
LockHolder locker(m_latchedNodeMutex);
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h (261131 => 261132)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h 2020-05-05 00:59:07 UTC (rev 261132)
@@ -36,7 +36,6 @@
namespace WebCore {
class PlatformWheelEvent;
-class ScrollingTree;
class ScrollingTreeLatchingController {
public:
@@ -44,7 +43,7 @@
void receivedWheelEvent(const PlatformWheelEvent&);
Optional<ScrollingNodeID> latchedNodeForEvent(const PlatformWheelEvent&) const;
- void nodeDidHandleEvent(const PlatformWheelEvent&, ScrollingNodeID);
+ void nodeDidHandleEvent(ScrollingNodeID, const PlatformWheelEvent&);
Optional<ScrollingNodeID> latchedNodeID() const;
@@ -52,7 +51,6 @@
void clearLatchedNode();
private:
-
mutable Lock m_latchedNodeMutex;
Markable<ScrollingNodeID, IntegralMarkableTraits<ScrollingNodeID, 0>> m_latchedNodeID;
MonotonicTime m_lastLatchedNodeInterationTime;
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp (261131 => 261132)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp 2020-05-05 00:59:07 UTC (rev 261132)
@@ -129,11 +129,15 @@
return scrollingTree().latchedNodeID() == scrollingNodeID();
}
-bool ScrollingTreeScrollingNode::canScrollWithWheelEvent(const PlatformWheelEvent& wheelEvent) const
+bool ScrollingTreeScrollingNode::canHandleWheelEvent(const PlatformWheelEvent& wheelEvent) const
{
if (!canHaveScrollbars())
return false;
+ // MayBegin is used to flash scrollbars; if this node is scrollable, it can handle it.
+ if (wheelEvent.phase() == PlatformWheelEventPhaseMayBegin)
+ return true;
+
// We always rubber-band the latched node, or the root node.
if (isLatchedNode() || isRootNode())
return true;
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h (261131 => 261132)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h 2020-05-05 00:59:07 UTC (rev 261132)
@@ -53,7 +53,7 @@
void commitStateBeforeChildren(const ScrollingStateNode&) override;
void commitStateAfterChildren(const ScrollingStateNode&) override;
- virtual bool canScrollWithWheelEvent(const PlatformWheelEvent&) const;
+ virtual bool canHandleWheelEvent(const PlatformWheelEvent&) const;
virtual ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&);
FloatPoint currentScrollPosition() const { return m_currentScrollPosition; }
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm (261131 => 261132)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm 2020-05-05 00:59:07 UTC (rev 261132)
@@ -113,7 +113,7 @@
ScrollingEventResult ScrollingTreeFrameScrollingNodeMac::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
{
- if (!canScrollWithWheelEvent(wheelEvent))
+ if (!canHandleWheelEvent(wheelEvent))
return ScrollingEventResult::DidNotHandleEvent;
bool handled = m_delegate.handleWheelEvent(wheelEvent);
@@ -125,8 +125,6 @@
if (m_delegate.activeScrollSnapIndexDidChange())
scrollingTree().setActiveScrollSnapIndices(scrollingNodeID(), m_delegate.activeScrollSnapIndexForAxis(ScrollEventAxis::Horizontal), m_delegate.activeScrollSnapIndexForAxis(ScrollEventAxis::Vertical));
#endif
- scrollingTree().handleWheelEventPhase(scrollingNodeID(), wheelEvent.phase());
-
return handled ? ScrollingEventResult::DidHandleEvent : ScrollingEventResult::DidNotHandleEvent;
}
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm (261131 => 261132)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm 2020-05-05 00:59:07 UTC (rev 261132)
@@ -74,13 +74,10 @@
return ScrollingEventResult::SendToMainThread;
#endif
- if (!canScrollWithWheelEvent(wheelEvent))
+ if (!canHandleWheelEvent(wheelEvent))
return ScrollingEventResult::DidNotHandleEvent;
bool handled = m_delegate.handleWheelEvent(wheelEvent);
-
- scrollingTree().handleWheelEventPhase(scrollingNodeID(), wheelEvent.phase());
-
return handled ? ScrollingEventResult::DidHandleEvent : ScrollingEventResult::DidNotHandleEvent;
}
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm (261131 => 261132)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm 2020-05-05 00:59:07 UTC (rev 261132)
@@ -130,6 +130,11 @@
deferWheelEventTestCompletionForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(scrollingNode().scrollingNodeID()), WheelEventTestMonitor::HandlingWheelEvent);
#endif
+ // PlatformWheelEventPhaseMayBegin fires when two fingers touch the trackpad, and is used to flash overlay scrollbars.
+ // We know we're scrollable at this point, so handle the event.
+ if (wheelEvent.phase() == PlatformWheelEventPhaseMayBegin)
+ return true;
+
auto handled = m_scrollController.handleWheelEvent(wheelEvent);
#if ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)
Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp (261131 => 261132)
--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp 2020-05-05 00:59:07 UTC (rev 261132)
@@ -116,7 +116,7 @@
ScrollingEventResult ScrollingTreeFrameScrollingNodeNicosia::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
{
- if (!canScrollWithWheelEvent(wheelEvent))
+ if (!canHandleWheelEvent(wheelEvent))
return ScrollingEventResult::DidNotHandleEvent;
if (wheelEvent.deltaX() || wheelEvent.deltaY()) {
Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp (261131 => 261132)
--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp 2020-05-05 00:59:07 UTC (rev 261132)
@@ -101,7 +101,7 @@
ScrollingEventResult ScrollingTreeOverflowScrollingNodeNicosia::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
{
- if (!canScrollWithWheelEvent(wheelEvent))
+ if (!canHandleWheelEvent(wheelEvent))
return ScrollingEventResult::DidNotHandleEvent;
if (wheelEvent.deltaX() || wheelEvent.deltaY()) {
Modified: trunk/Source/WebCore/platform/PlatformWheelEvent.h (261131 => 261132)
--- trunk/Source/WebCore/platform/PlatformWheelEvent.h 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/platform/PlatformWheelEvent.h 2020-05-05 00:59:07 UTC (rev 261132)
@@ -155,6 +155,10 @@
#if ENABLE(KINETIC_SCROLLING)
PlatformWheelEventPhase phase() const { return m_phase; }
PlatformWheelEventPhase momentumPhase() const { return m_momentumPhase; }
+
+ bool isGestureBegin() const;
+ bool isGestureCancel() const;
+
bool isEndOfNonMomentumScroll() const;
bool isTransitioningToMomentumScroll() const;
FloatPoint swipeVelocity() const;
@@ -220,6 +224,17 @@
#if ENABLE(KINETIC_SCROLLING)
+inline bool PlatformWheelEvent::isGestureBegin() const
+{
+ return m_phase == PlatformWheelEventPhaseMayBegin
+ || m_phase == PlatformWheelEventPhaseBegan;
+}
+
+inline bool PlatformWheelEvent::isGestureCancel() const
+{
+ return m_phase == PlatformWheelEventPhaseCancelled;
+}
+
inline bool PlatformWheelEvent::isEndOfNonMomentumScroll() const
{
return m_phase == PlatformWheelEventPhaseEnded && m_momentumPhase == PlatformWheelEventPhaseNone;
Modified: trunk/Source/WebCore/platform/cocoa/ScrollController.mm (261131 => 261132)
--- trunk/Source/WebCore/platform/cocoa/ScrollController.mm 2020-05-05 00:36:26 UTC (rev 261131)
+++ trunk/Source/WebCore/platform/cocoa/ScrollController.mm 2020-05-05 00:59:07 UTC (rev 261132)
@@ -103,6 +103,9 @@
if (!processWheelEventForScrollSnap(wheelEvent))
return false;
#endif
+ if (wheelEvent.phase() == PlatformWheelEventPhaseMayBegin || wheelEvent.phase() == PlatformWheelEventPhaseCancelled)
+ return false;
+
if (wheelEvent.phase() == PlatformWheelEventPhaseBegan) {
// FIXME: Trying to decide if a gesture is horizontal or vertical at the "began" phase is very error-prone.
auto direction = directionFromEvent(wheelEvent, ScrollEventAxis::Horizontal);