diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/Scrolling')
4 files changed, 544 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp new file mode 100644 index 000000000..383df5894 --- /dev/null +++ b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2014 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 "RemoteScrollingCoordinatorProxy.h" + +#if ENABLE(ASYNC_SCROLLING) + +#include "ArgumentCoders.h" +#include "RemoteLayerTreeDrawingAreaProxy.h" +#include "RemoteScrollingCoordinator.h" +#include "RemoteScrollingCoordinatorMessages.h" +#include "RemoteScrollingCoordinatorTransaction.h" +#include "WebPageProxy.h" +#include "WebProcessProxy.h" +#include <WebCore/ScrollingStateFrameScrollingNode.h> +#include <WebCore/ScrollingStateOverflowScrollingNode.h> +#include <WebCore/ScrollingStateTree.h> +#include <WebCore/ScrollingTreeScrollingNode.h> + +using namespace WebCore; + +namespace WebKit { + +RemoteScrollingCoordinatorProxy::RemoteScrollingCoordinatorProxy(WebPageProxy& webPageProxy) + : m_webPageProxy(webPageProxy) + , m_scrollingTree(RemoteScrollingTree::create(*this)) + , m_requestedScrollInfo(nullptr) + , m_propagatesMainFrameScrolls(true) +{ +} + +RemoteScrollingCoordinatorProxy::~RemoteScrollingCoordinatorProxy() +{ +} + +ScrollingNodeID RemoteScrollingCoordinatorProxy::rootScrollingNodeID() const +{ + if (!m_scrollingTree->rootNode()) + return 0; + + return m_scrollingTree->rootNode()->scrollingNodeID(); +} + +const RemoteLayerTreeHost* RemoteScrollingCoordinatorProxy::layerTreeHost() const +{ + DrawingAreaProxy* drawingArea = m_webPageProxy.drawingArea(); + if (!is<RemoteLayerTreeDrawingAreaProxy>(drawingArea)) { + ASSERT_NOT_REACHED(); + return nullptr; + } + + RemoteLayerTreeDrawingAreaProxy& remoteDrawingArea = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea); + return &remoteDrawingArea.remoteLayerTreeHost(); +} + +void RemoteScrollingCoordinatorProxy::commitScrollingTreeState(const RemoteScrollingCoordinatorTransaction& transaction, RequestedScrollInfo& requestedScrollInfo) +{ + m_requestedScrollInfo = &requestedScrollInfo; + + // FIXME: There must be a better idiom for this. + std::unique_ptr<ScrollingStateTree> stateTree(const_cast<RemoteScrollingCoordinatorTransaction&>(transaction).scrollingStateTree().release()); + + const RemoteLayerTreeHost* layerTreeHost = this->layerTreeHost(); + if (!layerTreeHost) { + ASSERT_NOT_REACHED(); + return; + } + + connectStateNodeLayers(*stateTree, *layerTreeHost); + m_scrollingTree->commitTreeState(WTFMove(stateTree)); + + m_requestedScrollInfo = nullptr; +} + +#if !PLATFORM(IOS) +void RemoteScrollingCoordinatorProxy::connectStateNodeLayers(ScrollingStateTree& stateTree, const RemoteLayerTreeHost& layerTreeHost) +{ + for (auto& currNode : stateTree.nodeMap().values()) { + if (currNode->hasChangedProperty(ScrollingStateNode::ScrollLayer)) + currNode->setLayer(layerTreeHost.getLayer(currNode->layer())); + + switch (currNode->nodeType()) { + case FrameScrollingNode: { + ScrollingStateFrameScrollingNode& scrollingStateNode = downcast<ScrollingStateFrameScrollingNode>(*currNode); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::ScrolledContentsLayer)) + scrollingStateNode.setScrolledContentsLayer(layerTreeHost.getLayer(scrollingStateNode.scrolledContentsLayer())); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::CounterScrollingLayer)) + scrollingStateNode.setCounterScrollingLayer(layerTreeHost.getLayer(scrollingStateNode.counterScrollingLayer())); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer)) + scrollingStateNode.setInsetClipLayer(layerTreeHost.getLayer(scrollingStateNode.insetClipLayer())); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer)) + scrollingStateNode.setContentShadowLayer(layerTreeHost.getLayer(scrollingStateNode.contentShadowLayer())); + + // FIXME: we should never have header and footer layers coming from the WebProcess. + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::HeaderLayer)) + scrollingStateNode.setHeaderLayer(layerTreeHost.getLayer(scrollingStateNode.headerLayer())); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::FooterLayer)) + scrollingStateNode.setFooterLayer(layerTreeHost.getLayer(scrollingStateNode.footerLayer())); + break; + } + case OverflowScrollingNode: { + ScrollingStateOverflowScrollingNode& scrollingStateNode = downcast<ScrollingStateOverflowScrollingNode>(*currNode); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateOverflowScrollingNode::ScrolledContentsLayer)) + scrollingStateNode.setScrolledContentsLayer(layerTreeHost.getLayer(scrollingStateNode.scrolledContentsLayer())); + break; + } + case FixedNode: + case StickyNode: + break; + } + } +} +#endif + +bool RemoteScrollingCoordinatorProxy::handleWheelEvent(const PlatformWheelEvent& event) +{ + ScrollingTree::EventResult result = m_scrollingTree->tryToHandleWheelEvent(event); + return result == ScrollingTree::DidHandleEvent; // FIXME: handle other values. +} + +TrackingType RemoteScrollingCoordinatorProxy::eventTrackingTypeForPoint(const AtomicString& eventName, IntPoint p) const +{ + return m_scrollingTree->eventTrackingTypeForPoint(eventName, p); +} + +void RemoteScrollingCoordinatorProxy::viewportChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const FloatRect& fixedPositionRect, double scale) +{ + m_scrollingTree->viewportChangedViaDelegatedScrolling(nodeID, fixedPositionRect, scale); +} + +void RemoteScrollingCoordinatorProxy::currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical) +{ + m_webPageProxy.send(Messages::RemoteScrollingCoordinator::CurrentSnapPointIndicesChangedForNode(nodeID, horizontal, vertical)); +} + +// This comes from the scrolling tree. +void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll(ScrollingNodeID scrolledNodeID, const FloatPoint& newScrollPosition, const std::optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction scrollingLayerPositionAction) +{ + // Scroll updates for the main frame are sent via WebPageProxy::updateVisibleContentRects() + // so don't send them here. + if (!m_propagatesMainFrameScrolls && scrolledNodeID == rootScrollingNodeID()) + return; + +#if PLATFORM(IOS) + m_webPageProxy.overflowScrollViewDidScroll(); +#endif + m_webPageProxy.send(Messages::RemoteScrollingCoordinator::ScrollPositionChangedForNode(scrolledNodeID, newScrollPosition, scrollingLayerPositionAction == ScrollingLayerPositionAction::Sync)); +} + +void RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll(ScrollingNodeID scrolledNodeID, const FloatPoint& scrollPosition, bool representsProgrammaticScroll) +{ + if (scrolledNodeID == rootScrollingNodeID() && m_requestedScrollInfo) { + m_requestedScrollInfo->requestsScrollPositionUpdate = true; + m_requestedScrollInfo->requestIsProgrammaticScroll = representsProgrammaticScroll; + m_requestedScrollInfo->requestedScrollPosition = scrollPosition; + } +} + +String RemoteScrollingCoordinatorProxy::scrollingTreeAsText() const +{ + if (m_scrollingTree) + return m_scrollingTree->scrollingTreeAsText(); + + return emptyString(); +} + +} // namespace WebKit + +#endif // ENABLE(ASYNC_SCROLLING) diff --git a/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h new file mode 100644 index 000000000..e87bb2c2e --- /dev/null +++ b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2014-2015 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. + */ + +#ifndef RemoteScrollingCoordinatorProxy_h +#define RemoteScrollingCoordinatorProxy_h + +#if ENABLE(ASYNC_SCROLLING) + +#include "MessageReceiver.h" +#include "RemoteScrollingCoordinator.h" +#include "RemoteScrollingTree.h" +#include <wtf/Noncopyable.h> +#include <wtf/RefPtr.h> + +namespace WebCore { +class FloatPoint; +class PlatformWheelEvent; +} + +namespace WebKit { + +class RemoteLayerTreeHost; +class RemoteScrollingCoordinatorTransaction; +class RemoteScrollingTree; +class WebPageProxy; + +class RemoteScrollingCoordinatorProxy { + WTF_MAKE_NONCOPYABLE(RemoteScrollingCoordinatorProxy); +public: + explicit RemoteScrollingCoordinatorProxy(WebPageProxy&); + virtual ~RemoteScrollingCoordinatorProxy(); + + bool visualViewportEnabled() const { return m_scrollingTree && m_scrollingTree->visualViewportEnabled(); } + + // Inform the web process that the scroll position changed (called from the scrolling tree) + void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& newScrollPosition, const std::optional<WebCore::FloatPoint>& layoutViewportOrigin, WebCore::ScrollingLayerPositionAction); + void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll); + + WebCore::TrackingType eventTrackingTypeForPoint(const AtomicString& eventName, WebCore::IntPoint) const; + + // Called externally when native views move around. + void viewportChangedViaDelegatedScrolling(WebCore::ScrollingNodeID, const WebCore::FloatRect& fixedPositionRect, double scale); + + void currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID, unsigned horizontal, unsigned vertical); + + // FIXME: expose the tree and pass this to that? + bool handleWheelEvent(const WebCore::PlatformWheelEvent&); + + WebCore::ScrollingNodeID rootScrollingNodeID() const; + + const RemoteLayerTreeHost* layerTreeHost() const; + + struct RequestedScrollInfo { + bool requestsScrollPositionUpdate { }; + bool requestIsProgrammaticScroll { }; + WebCore::FloatPoint requestedScrollPosition; + }; + void commitScrollingTreeState(const RemoteScrollingCoordinatorTransaction&, RequestedScrollInfo&); + + void setPropagatesMainFrameScrolls(bool propagatesMainFrameScrolls) { m_propagatesMainFrameScrolls = propagatesMainFrameScrolls; } + bool propagatesMainFrameScrolls() const { return m_propagatesMainFrameScrolls; } + bool hasFixedOrSticky() const { return m_scrollingTree->hasFixedOrSticky(); } + +#if PLATFORM(IOS) + WebCore::FloatRect customFixedPositionRect() const; + void scrollingTreeNodeWillStartPanGesture(); + void scrollingTreeNodeWillStartScroll(); + void scrollingTreeNodeDidEndScroll(); +#if ENABLE(CSS_SCROLL_SNAP) + void adjustTargetContentOffsetForSnapping(CGSize maxScrollDimensions, CGPoint velocity, CGFloat topInset, CGPoint* targetContentOffset); + bool hasActiveSnapPoint() const; + CGPoint nearestActiveContentInsetAdjustedSnapPoint(CGFloat topInset, const CGPoint&) const; + bool shouldSetScrollViewDecelerationRateFast() const; +#endif +#endif + + String scrollingTreeAsText() const; + +private: + void connectStateNodeLayers(WebCore::ScrollingStateTree&, const RemoteLayerTreeHost&); +#if ENABLE(CSS_SCROLL_SNAP) + bool shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis) const; + float closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis, float scrollDestination, float velocity, unsigned& closestIndex) const; +#endif + + WebPageProxy& m_webPageProxy; + RefPtr<RemoteScrollingTree> m_scrollingTree; + RequestedScrollInfo* m_requestedScrollInfo; +#if ENABLE(CSS_SCROLL_SNAP) + unsigned m_currentHorizontalSnapPointIndex { 0 }; + unsigned m_currentVerticalSnapPointIndex { 0 }; +#endif + bool m_propagatesMainFrameScrolls; +}; + +} // namespace WebKit + +#endif // ENABLE(ASYNC_SCROLLING) + +#endif // RemoteScrollingCoordinatorProxy_h diff --git a/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp new file mode 100644 index 000000000..421c7457c --- /dev/null +++ b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2014 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 "RemoteScrollingTree.h" + +#if ENABLE(ASYNC_SCROLLING) + +#include "RemoteLayerTreeHost.h" +#include "RemoteScrollingCoordinatorProxy.h" +#include <WebCore/ScrollingTreeFixedNode.h> +#include <WebCore/ScrollingTreeStickyNode.h> + +#if PLATFORM(IOS) +#include "ScrollingTreeOverflowScrollingNodeIOS.h" +#include <WebCore/ScrollingTreeFrameScrollingNodeIOS.h> +#else +#include <WebCore/ScrollingTreeFrameScrollingNodeMac.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +Ref<RemoteScrollingTree> RemoteScrollingTree::create(RemoteScrollingCoordinatorProxy& scrollingCoordinator) +{ + return adoptRef(*new RemoteScrollingTree(scrollingCoordinator)); +} + +RemoteScrollingTree::RemoteScrollingTree(RemoteScrollingCoordinatorProxy& scrollingCoordinator) + : m_scrollingCoordinatorProxy(scrollingCoordinator) +{ +} + +RemoteScrollingTree::~RemoteScrollingTree() +{ +} + +ScrollingTree::EventResult RemoteScrollingTree::tryToHandleWheelEvent(const PlatformWheelEvent& wheelEvent) +{ + if (shouldHandleWheelEventSynchronously(wheelEvent)) + return SendToMainThread; + + if (willWheelEventStartSwipeGesture(wheelEvent)) + return DidNotHandleEvent; + + handleWheelEvent(wheelEvent); + return DidHandleEvent; +} + +#if PLATFORM(MAC) +void RemoteScrollingTree::handleWheelEventPhase(PlatformWheelEventPhase phase) +{ + // FIXME: hand off to m_scrollingCoordinatorProxy? +} +#endif + +#if PLATFORM(IOS) +WebCore::FloatRect RemoteScrollingTree::fixedPositionRect() +{ + return m_scrollingCoordinatorProxy.customFixedPositionRect(); +} + +void RemoteScrollingTree::scrollingTreeNodeWillStartPanGesture() +{ + m_scrollingCoordinatorProxy.scrollingTreeNodeWillStartPanGesture(); +} + +void RemoteScrollingTree::scrollingTreeNodeWillStartScroll() +{ + m_scrollingCoordinatorProxy.scrollingTreeNodeWillStartScroll(); +} + +void RemoteScrollingTree::scrollingTreeNodeDidEndScroll() +{ + m_scrollingCoordinatorProxy.scrollingTreeNodeDidEndScroll(); +} + +#endif + +void RemoteScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, const std::optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction scrollingLayerPositionAction) +{ + m_scrollingCoordinatorProxy.scrollingTreeNodeDidScroll(nodeID, scrollPosition, layoutViewportOrigin, scrollingLayerPositionAction); +} + +void RemoteScrollingTree::scrollingTreeNodeRequestsScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, bool representsProgrammaticScroll) +{ + m_scrollingCoordinatorProxy.scrollingTreeNodeRequestsScroll(nodeID, scrollPosition, representsProgrammaticScroll); +} + +Ref<ScrollingTreeNode> RemoteScrollingTree::createScrollingTreeNode(ScrollingNodeType nodeType, ScrollingNodeID nodeID) +{ + switch (nodeType) { + case FrameScrollingNode: +#if PLATFORM(IOS) + return ScrollingTreeFrameScrollingNodeIOS::create(*this, nodeID); +#else + return ScrollingTreeFrameScrollingNodeMac::create(*this, nodeID); +#endif + case OverflowScrollingNode: +#if PLATFORM(IOS) + return ScrollingTreeOverflowScrollingNodeIOS::create(*this, nodeID); +#else + ASSERT_NOT_REACHED(); + break; +#endif + case FixedNode: + return ScrollingTreeFixedNode::create(*this, nodeID); + case StickyNode: + return ScrollingTreeStickyNode::create(*this, nodeID); + } + ASSERT_NOT_REACHED(); + return ScrollingTreeFixedNode::create(*this, nodeID); +} + +void RemoteScrollingTree::currentSnapPointIndicesDidChange(ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical) +{ + m_scrollingCoordinatorProxy.currentSnapPointIndicesDidChange(nodeID, horizontal, vertical); +} + +} // namespace WebKit + +#endif // ENABLE(ASYNC_SCROLLING) diff --git a/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.h b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.h new file mode 100644 index 000000000..7318ccc81 --- /dev/null +++ b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2014 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. + */ + +#ifndef RemoteScrollingTree_h +#define RemoteScrollingTree_h + +#if ENABLE(ASYNC_SCROLLING) + +#include "RemoteScrollingCoordinator.h" +#include <WebCore/ScrollingConstraints.h> +#include <WebCore/ScrollingTree.h> + +namespace WebKit { + +class RemoteScrollingCoordinatorProxy; + +class RemoteScrollingTree final : public WebCore::ScrollingTree { +public: + static Ref<RemoteScrollingTree> create(RemoteScrollingCoordinatorProxy&); + virtual ~RemoteScrollingTree(); + + bool isRemoteScrollingTree() const override { return true; } + EventResult tryToHandleWheelEvent(const WebCore::PlatformWheelEvent&) override; + + const RemoteScrollingCoordinatorProxy& scrollingCoordinatorProxy() const { return m_scrollingCoordinatorProxy; } + + void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, const std::optional<WebCore::FloatPoint>& layoutViewportOrigin, WebCore::ScrollingLayerPositionAction = WebCore::ScrollingLayerPositionAction::Sync) override; + void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll) override; + + void currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID, unsigned horizontal, unsigned vertical) override; + +private: + explicit RemoteScrollingTree(RemoteScrollingCoordinatorProxy&); + +#if PLATFORM(MAC) + void handleWheelEventPhase(WebCore::PlatformWheelEventPhase) override; +#endif + +#if PLATFORM(IOS) + WebCore::FloatRect fixedPositionRect() override; + void scrollingTreeNodeWillStartPanGesture() override; + void scrollingTreeNodeWillStartScroll() override; + void scrollingTreeNodeDidEndScroll() override; +#endif + + Ref<WebCore::ScrollingTreeNode> createScrollingTreeNode(WebCore::ScrollingNodeType, WebCore::ScrollingNodeID) override; + + RemoteScrollingCoordinatorProxy& m_scrollingCoordinatorProxy; +}; + +} // namespace WebKit + +SPECIALIZE_TYPE_TRAITS_SCROLLING_TREE(WebKit::RemoteScrollingTree, isRemoteScrollingTree()); + +#endif // ENABLE(ASYNC_SCROLLING) + +#endif // RemoteScrollingTree_h |