/* * Copyright (C) 2011, 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. */ #pragma once #include "EventTrackingRegions.h" #include "IntRect.h" #include "LayoutRect.h" #include "PlatformWheelEvent.h" #include "ScrollSnapOffsetsInfo.h" #include "ScrollTypes.h" #include #include #include #include #if ENABLE(ASYNC_SCROLLING) #include #include #include #endif #if ENABLE(CSS_SCROLL_SNAP) #include "AxisScrollSnapOffsets.h" #endif namespace WebCore { typedef unsigned SynchronousScrollingReasons; typedef uint64_t ScrollingNodeID; enum ScrollingNodeType { FrameScrollingNode, OverflowScrollingNode, FixedNode, StickyNode }; class Document; class Frame; class FrameView; class GraphicsLayer; class Page; class Region; class ScrollableArea; class TextStream; class ViewportConstraints; #if ENABLE(ASYNC_SCROLLING) class ScrollingTree; #endif enum class ScrollingLayerPositionAction { Set, SetApproximate, Sync }; struct ScrollableAreaParameters { ScrollElasticity horizontalScrollElasticity; ScrollElasticity verticalScrollElasticity; ScrollbarMode horizontalScrollbarMode; ScrollbarMode verticalScrollbarMode; bool hasEnabledHorizontalScrollbar; bool hasEnabledVerticalScrollbar; ScrollableAreaParameters() : horizontalScrollElasticity(ScrollElasticityNone) , verticalScrollElasticity(ScrollElasticityNone) , horizontalScrollbarMode(ScrollbarAuto) , verticalScrollbarMode(ScrollbarAuto) , hasEnabledHorizontalScrollbar(false) , hasEnabledVerticalScrollbar(false) { } bool operator==(const ScrollableAreaParameters& other) const { return horizontalScrollElasticity == other.horizontalScrollElasticity && verticalScrollElasticity == other.verticalScrollElasticity && horizontalScrollbarMode == other.horizontalScrollbarMode && verticalScrollbarMode == other.verticalScrollbarMode && hasEnabledHorizontalScrollbar == other.hasEnabledHorizontalScrollbar && hasEnabledVerticalScrollbar == other.hasEnabledVerticalScrollbar; } }; class ScrollingCoordinator : public ThreadSafeRefCounted { public: static Ref create(Page*); virtual ~ScrollingCoordinator(); WEBCORE_EXPORT virtual void pageDestroyed(); virtual bool isAsyncScrollingCoordinator() const { return false; } virtual bool isRemoteScrollingCoordinator() const { return false; } // Return whether this scrolling coordinator handles scrolling for the given frame view. virtual bool coordinatesScrollingForFrameView(const FrameView&) const; // Should be called whenever the given frame view has been laid out. virtual void frameViewLayoutUpdated(FrameView&) { } using LayoutViewportOriginOrOverrideRect = WTF::Variant, std::optional>; virtual void reconcileScrollingState(FrameView&, const FloatPoint&, const LayoutViewportOriginOrOverrideRect&, bool /* programmaticScroll */, bool /* inStableState*/, ScrollingLayerPositionAction) { } // Should be called whenever the slow repaint objects counter changes between zero and one. void frameViewHasSlowRepaintObjectsDidChange(FrameView&); // Should be called whenever the set of fixed objects changes. void frameViewFixedObjectsDidChange(FrameView&); // Called whenever the non-fast scrollable region changes for reasons other than layout. virtual void frameViewEventTrackingRegionsChanged(FrameView&) { } // Should be called whenever the root layer for the given frame view changes. virtual void frameViewRootLayerDidChange(FrameView&); // Return whether this scrolling coordinator can keep fixed position layers fixed to their // containers while scrolling. virtual bool supportsFixedPositionLayers() const { return false; } #if PLATFORM(COCOA) // Dispatched by the scrolling tree during handleWheelEvent. This is required as long as scrollbars are painted on the main thread. void handleWheelEventPhase(PlatformWheelEventPhase); #endif #if ENABLE(WEB_REPLAY) // Called when the page transitions between executing normally and deterministically. void replaySessionStateDidChange(); #endif // Force all scroll layer position updates to happen on the main thread. WEBCORE_EXPORT void setForceSynchronousScrollLayerPositionUpdates(bool); // These virtual functions are currently unique to the threaded scrolling architecture. // Their meaningful implementations are in ScrollingCoordinatorMac. virtual void commitTreeStateIfNeeded() { } virtual bool requestScrollPositionUpdate(FrameView&, const IntPoint&) { return false; } virtual bool handleWheelEvent(FrameView&, const PlatformWheelEvent&) { return true; } virtual ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID /*parentID*/) { return newNodeID; } virtual void detachFromStateTree(ScrollingNodeID) { } virtual void clearStateTree() { } virtual void updateViewportConstrainedNode(ScrollingNodeID, const ViewportConstraints&, GraphicsLayer*) { } struct ScrollingGeometry { FloatSize scrollableAreaSize; FloatSize contentSize; FloatSize reachableContentSize; // Smaller than contentSize when overflow is hidden on one axis. FloatPoint scrollPosition; IntPoint scrollOrigin; #if ENABLE(CSS_SCROLL_SNAP) Vector horizontalSnapOffsets; Vector verticalSnapOffsets; Vector> horizontalSnapOffsetRanges; Vector> verticalSnapOffsetRanges; unsigned currentHorizontalSnapPointIndex; unsigned currentVerticalSnapPointIndex; #endif }; virtual void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, GraphicsLayer* /*counterScrollingLayer*/, GraphicsLayer* /*insetClipLayer*/, const ScrollingGeometry* = nullptr) { } virtual void updateOverflowScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, const ScrollingGeometry* = nullptr) { } virtual void reconcileViewportConstrainedLayerPositions(const LayoutRect&, ScrollingLayerPositionAction) { } virtual String scrollingStateTreeAsText() const; virtual bool isRubberBandInProgress() const { return false; } virtual bool isScrollSnapInProgress() const { return false; } virtual void updateScrollSnapPropertiesWithFrameView(const FrameView&) { } virtual void setScrollPinningBehavior(ScrollPinningBehavior) { } // Generated a unique id for scroll layers. ScrollingNodeID uniqueScrollLayerID(); enum MainThreadScrollingReasonFlags { ForcedOnMainThread = 1 << 0, HasSlowRepaintObjects = 1 << 1, HasViewportConstrainedObjectsWithoutSupportingFixedLayers = 1 << 2, HasNonLayerViewportConstrainedObjects = 1 << 3, IsImageDocument = 1 << 4 }; SynchronousScrollingReasons synchronousScrollingReasons(const FrameView&) const; bool shouldUpdateScrollLayerPositionSynchronously(const FrameView&) const; virtual void willDestroyScrollableArea(ScrollableArea&) { } virtual void scrollableAreaScrollLayerDidChange(ScrollableArea&) { } virtual void scrollableAreaScrollbarLayerDidChange(ScrollableArea&, ScrollbarOrientation) { } static String synchronousScrollingReasonsAsText(SynchronousScrollingReasons); String synchronousScrollingReasonsAsText() const; EventTrackingRegions absoluteEventTrackingRegions() const; virtual void updateExpectsWheelEventTestTriggerWithFrameView(const FrameView&) { } protected: explicit ScrollingCoordinator(Page*); static GraphicsLayer* scrollLayerForScrollableArea(ScrollableArea&); GraphicsLayer* scrollLayerForFrameView(FrameView&); GraphicsLayer* counterScrollingLayerForFrameView(FrameView&); GraphicsLayer* insetClipLayerForFrameView(FrameView&); GraphicsLayer* rootContentLayerForFrameView(FrameView&); GraphicsLayer* contentShadowLayerForFrameView(FrameView&); GraphicsLayer* headerLayerForFrameView(FrameView&); GraphicsLayer* footerLayerForFrameView(FrameView&); virtual void willCommitTree() { } Page* m_page; // FIXME: ideally this would be a reference but it gets nulled on async teardown. private: virtual void setSynchronousScrollingReasons(SynchronousScrollingReasons) { } virtual bool hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView&) const; void updateSynchronousScrollingReasons(const FrameView&); EventTrackingRegions absoluteEventTrackingRegionsForFrame(const Frame&) const; bool m_forceSynchronousScrollLayerPositionUpdates { false }; }; WEBCORE_EXPORT TextStream& operator<<(TextStream&, ScrollingNodeType); WEBCORE_EXPORT TextStream& operator<<(TextStream&, ScrollingLayerPositionAction); } // namespace WebCore #define SPECIALIZE_TYPE_TRAITS_SCROLLING_COORDINATOR(ToValueTypeName, predicate) \ SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \ static bool isType(const WebCore::ScrollingCoordinator& value) { return value.predicate; } \ SPECIALIZE_TYPE_TRAITS_END()