Basic scrollability for async overflow scrolling on macOS
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Jan 2019 23:58:25 +0000 (23:58 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Jan 2019 23:58:25 +0000 (23:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=194093

Reviewed by Antti Koivisto.

Give a ScrollingTreeOverflowScrollingNodeMac a ScrollingTreeScrollingNodeDelegateMac and have it keep track
of its layers so basic scrolling works for async overflow scroll.

* page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h:
* page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm:
(WebCore::ScrollingTreeOverflowScrollingNodeMac::create):
(WebCore::ScrollingTreeOverflowScrollingNodeMac::ScrollingTreeOverflowScrollingNodeMac):
(WebCore::ScrollingTreeOverflowScrollingNodeMac::commitStateBeforeChildren):
(WebCore::ScrollingTreeOverflowScrollingNodeMac::commitStateAfterChildren):
(WebCore::ScrollingTreeOverflowScrollingNodeMac::handleWheelEvent):
(WebCore::ScrollingTreeOverflowScrollingNodeMac::scrollPosition const):
(WebCore::ScrollingTreeOverflowScrollingNodeMac::setScrollPosition):
(WebCore::ScrollingTreeOverflowScrollingNodeMac::setScrollPositionWithoutContentEdgeConstraints):
(WebCore::ScrollingTreeOverflowScrollingNodeMac::setScrollLayerPosition):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateScrollingLayers):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240826 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h
Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm
Source/WebCore/rendering/RenderLayerBacking.cpp

index 3cdfef7..33881fd 100644 (file)
@@ -1,5 +1,29 @@
 2019-01-31  Simon Fraser  <simon.fraser@apple.com>
 
+        Basic scrollability for async overflow scrolling on macOS
+        https://bugs.webkit.org/show_bug.cgi?id=194093
+
+        Reviewed by Antti Koivisto.
+
+        Give a ScrollingTreeOverflowScrollingNodeMac a ScrollingTreeScrollingNodeDelegateMac and have it keep track
+        of its layers so basic scrolling works for async overflow scroll.
+
+        * page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h:
+        * page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm:
+        (WebCore::ScrollingTreeOverflowScrollingNodeMac::create):
+        (WebCore::ScrollingTreeOverflowScrollingNodeMac::ScrollingTreeOverflowScrollingNodeMac):
+        (WebCore::ScrollingTreeOverflowScrollingNodeMac::commitStateBeforeChildren):
+        (WebCore::ScrollingTreeOverflowScrollingNodeMac::commitStateAfterChildren):
+        (WebCore::ScrollingTreeOverflowScrollingNodeMac::handleWheelEvent):
+        (WebCore::ScrollingTreeOverflowScrollingNodeMac::scrollPosition const):
+        (WebCore::ScrollingTreeOverflowScrollingNodeMac::setScrollPosition):
+        (WebCore::ScrollingTreeOverflowScrollingNodeMac::setScrollPositionWithoutContentEdgeConstraints):
+        (WebCore::ScrollingTreeOverflowScrollingNodeMac::setScrollLayerPosition):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::updateScrollingLayers):
+
+2019-01-31  Simon Fraser  <simon.fraser@apple.com>
+
         Generalize ScrollingTreeScrollingNodeDelegate for use in macOS too, add a macOS subclass for frame/overflow scrolling
         https://bugs.webkit.org/show_bug.cgi?id=194080
 
index ce397b9..c3aac03 100644 (file)
 #if ENABLE(ASYNC_SCROLLING) && PLATFORM(MAC)
 
 #include "ScrollingTreeOverflowScrollingNode.h"
+#include "ScrollingTreeScrollingNodeDelegateMac.h"
+
+OBJC_CLASS CALayer;
 
 namespace WebCore {
 
-class ScrollingTreeOverflowScrollingNodeMac : public WebCore::ScrollingTreeOverflowScrollingNode {
+class ScrollingTreeOverflowScrollingNodeMac : public ScrollingTreeOverflowScrollingNode {
 public:
-    static Ref<ScrollingTreeOverflowScrollingNodeMac> create(WebCore::ScrollingTree&, WebCore::ScrollingNodeID);
+    static Ref<ScrollingTreeOverflowScrollingNodeMac> create(ScrollingTree&, ScrollingNodeID);
     virtual ~ScrollingTreeOverflowScrollingNodeMac();
 
 private:
-    ScrollingTreeOverflowScrollingNodeMac(WebCore::ScrollingTree&, WebCore::ScrollingNodeID);
+    ScrollingTreeOverflowScrollingNodeMac(ScrollingTree&, ScrollingNodeID);
 
-    void commitStateBeforeChildren(const WebCore::ScrollingStateNode&) override;
-    void commitStateAfterChildren(const WebCore::ScrollingStateNode&) override;
+    void commitStateBeforeChildren(const ScrollingStateNode&) override;
+    void commitStateAfterChildren(const ScrollingStateNode&) override;
     
-    WebCore::FloatPoint scrollPosition() const override;
+    FloatPoint scrollPosition() const override;
+    void setScrollPosition(const FloatPoint&) override;
+    void setScrollPositionWithoutContentEdgeConstraints(const FloatPoint&) override;
+
+    void setScrollLayerPosition(const FloatPoint&, const FloatRect& layoutViewport) override;
+
+    void updateLayersAfterViewportChange(const FloatRect&, double) override { }
+    void updateLayersAfterDelegatedScroll(const FloatPoint& scrollPosition) override;
+
+    void updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta) override;
+
+    ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) override;
+
 
-    void setScrollLayerPosition(const WebCore::FloatPoint&, const WebCore::FloatRect& layoutViewport) override;
+    RetainPtr<CALayer> m_scrollLayer;
+    RetainPtr<CALayer> m_scrolledContentsLayer;
 
-    void updateLayersAfterViewportChange(const WebCore::FloatRect&, double) override { }
-    void updateLayersAfterDelegatedScroll(const WebCore::FloatPoint& scrollPosition) override;
 
-    void updateLayersAfterAncestorChange(const WebCore::ScrollingTreeNode& changedNode, const WebCore::FloatRect& fixedPositionRect, const WebCore::FloatSize& cumulativeDelta) override;
+    ScrollingTreeScrollingNodeDelegateMac m_delegate;
 
-    ScrollingEventResult handleWheelEvent(const WebCore::PlatformWheelEvent&) override { return ScrollingEventResult::DidNotHandleEvent; }
 };
 
 } // namespace WebKit
index 56dbc51..b0a39b9 100644 (file)
 
 #if ENABLE(ASYNC_SCROLLING) && PLATFORM(MAC)
 
+#import "Logging.h"
+#import "ScrollingStateOverflowScrollingNode.h"
+#import "ScrollingTree.h"
+#import <wtf/text/TextStream.h>
+
 namespace WebCore {
 
-Ref<ScrollingTreeOverflowScrollingNodeMac> ScrollingTreeOverflowScrollingNodeMac::create(WebCore::ScrollingTree& scrollingTree, WebCore::ScrollingNodeID nodeID)
+Ref<ScrollingTreeOverflowScrollingNodeMac> ScrollingTreeOverflowScrollingNodeMac::create(ScrollingTree& scrollingTree, ScrollingNodeID nodeID)
 {
     return adoptRef(*new ScrollingTreeOverflowScrollingNodeMac(scrollingTree, nodeID));
 }
 
-ScrollingTreeOverflowScrollingNodeMac::ScrollingTreeOverflowScrollingNodeMac(WebCore::ScrollingTree& scrollingTree, WebCore::ScrollingNodeID nodeID)
+ScrollingTreeOverflowScrollingNodeMac::ScrollingTreeOverflowScrollingNodeMac(ScrollingTree& scrollingTree, ScrollingNodeID nodeID)
     : ScrollingTreeOverflowScrollingNode(scrollingTree, nodeID)
+    , m_delegate(*this)
 {
 }
 
@@ -44,16 +50,55 @@ ScrollingTreeOverflowScrollingNodeMac::~ScrollingTreeOverflowScrollingNodeMac()
 {
 }
 
-void ScrollingTreeOverflowScrollingNodeMac::commitStateBeforeChildren(const WebCore::ScrollingStateNode& stateNode)
+void ScrollingTreeOverflowScrollingNodeMac::commitStateBeforeChildren(const ScrollingStateNode& stateNode)
 {
     ScrollingTreeOverflowScrollingNode::commitStateBeforeChildren(stateNode);
+    const auto& scrollingStateNode = downcast<ScrollingStateOverflowScrollingNode>(stateNode);
+
+    if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::ScrollLayer))
+        m_scrollLayer = scrollingStateNode.layer();
+
+    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrolledContentsLayer))
+        m_scrolledContentsLayer = scrollingStateNode.scrolledContentsLayer();
+
+    // FIXME: Scroll snap data.
 }
 
 void ScrollingTreeOverflowScrollingNodeMac::commitStateAfterChildren(const ScrollingStateNode& stateNode)
 {
     ScrollingTreeOverflowScrollingNode::commitStateAfterChildren(stateNode);
+    
+    // FIXME: RequestedScrollPosition etc.
+}
+
+ScrollingEventResult ScrollingTreeOverflowScrollingNodeMac::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
+{
+    if (!canHaveScrollbars())
+        return ScrollingEventResult::DidNotHandleEvent;
+
+
+#if ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)
+    if (expectsWheelEventTestTrigger()) {
+        if (scrollingTree().shouldHandleWheelEventSynchronously(wheelEvent))
+            m_delegate.removeTestDeferralForReason(reinterpret_cast<WheelEventTestTrigger::ScrollableAreaIdentifier>(scrollingNodeID()), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
+        else
+            m_delegate.deferTestsForReason(reinterpret_cast<WheelEventTestTrigger::ScrollableAreaIdentifier>(scrollingNodeID()), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
+    }
+#endif
+
+    m_delegate.handleWheelEvent(wheelEvent);
+
+    // FIXME: Scroll snap
+
+    scrollingTree().setOrClearLatchedNode(wheelEvent, scrollingNodeID());
+    scrollingTree().handleWheelEventPhase(wheelEvent.phase());
+    
+    // FIXME: This needs to return whether the event was handled.
+    return ScrollingEventResult::DidHandleEvent;
 }
 
+
+
 void ScrollingTreeOverflowScrollingNodeMac::updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta)
 {
     UNUSED_PARAM(changedNode);
@@ -63,12 +108,34 @@ void ScrollingTreeOverflowScrollingNodeMac::updateLayersAfterAncestorChange(cons
 
 FloatPoint ScrollingTreeOverflowScrollingNodeMac::scrollPosition() const
 {
-    return { };
+    return -m_scrolledContentsLayer.get().position;
 }
 
-void ScrollingTreeOverflowScrollingNodeMac::setScrollLayerPosition(const FloatPoint& scrollPosition, const FloatRect&)
+void ScrollingTreeOverflowScrollingNodeMac::setScrollPosition(const FloatPoint& scrollPosition)
 {
-    UNUSED_PARAM(scrollPosition);
+    LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeOverflowScrollingNodeMac::setScrollPosition " << scrollPosition << " scrollPosition(): " << this->scrollPosition() << " min: " << minimumScrollPosition() << " max: " << maximumScrollPosition());
+
+    // Scroll deltas can be non-integral with some input devices, so scrollPosition may not be integral.
+    // FIXME: when we support half-pixel scroll positions on Retina displays, this will need to round to half pixels.
+    FloatPoint roundedPosition(roundf(scrollPosition.x()), roundf(scrollPosition.y()));
+
+    ScrollingTreeOverflowScrollingNode::setScrollPosition(roundedPosition);
+}
+
+void ScrollingTreeOverflowScrollingNodeMac::setScrollPositionWithoutContentEdgeConstraints(const FloatPoint& scrollPosition)
+{
+    setScrollLayerPosition(scrollPosition, { });
+    scrollingTree().scrollingTreeNodeDidScroll(scrollingNodeID(), scrollPosition, { });
+}
+
+void ScrollingTreeOverflowScrollingNodeMac::setScrollLayerPosition(const FloatPoint& scrollPosition, const FloatRect& fixedPositionRect)
+{
+    m_scrolledContentsLayer.get().position = -scrollPosition;
+    if (!m_children)
+        return;
+
+    for (auto& child : *m_children)
+        child->updateLayersAfterAncestorChange(*this, fixedPositionRect, { });
 }
 
 void ScrollingTreeOverflowScrollingNodeMac::updateLayersAfterDelegatedScroll(const FloatPoint& scrollPosition)
index 53311f5..6b906ab 100644 (file)
@@ -1745,7 +1745,7 @@ bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
         m_scrollingLayer->setMasksToBounds(true);
 
         // Inner layer which renders the content that scrolls.
-        m_scrollingContentsLayer = createGraphicsLayer("scrolled Contents");
+        m_scrollingContentsLayer = createGraphicsLayer("scrolled contents");
         m_scrollingContentsLayer->setDrawsContent(true);
         m_scrollingContentsLayer->setAnchorPoint({ });