ScrollingCoordinator.h [plain text]
#pragma once
#include "EventTrackingRegions.h"
#include "IntRect.h"
#include "LayoutRect.h"
#include "PlatformWheelEvent.h"
#include "ScrollTypes.h"
#include <wtf/Forward.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/TypeCasts.h>
#include <wtf/Variant.h>
#if ENABLE(ASYNC_SCROLLING)
#include <wtf/HashMap.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/Threading.h>
#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<ScrollingCoordinator> {
public:
static Ref<ScrollingCoordinator> create(Page*);
virtual ~ScrollingCoordinator();
WEBCORE_EXPORT virtual void pageDestroyed();
virtual bool isAsyncScrollingCoordinator() const { return false; }
virtual bool isRemoteScrollingCoordinator() const { return false; }
virtual bool coordinatesScrollingForFrameView(const FrameView&) const;
virtual void frameViewLayoutUpdated(FrameView&) { }
using LayoutViewportOriginOrOverrideRect = WTF::Variant<std::optional<FloatPoint>, std::optional<FloatRect>>;
virtual void reconcileScrollingState(FrameView&, const FloatPoint&, const LayoutViewportOriginOrOverrideRect&, bool , bool , ScrollingLayerPositionAction) { }
void frameViewHasSlowRepaintObjectsDidChange(FrameView&);
void frameViewFixedObjectsDidChange(FrameView&);
virtual void frameViewEventTrackingRegionsChanged(FrameView&) { }
virtual void frameViewRootLayerDidChange(FrameView&);
virtual bool supportsFixedPositionLayers() const { return false; }
#if PLATFORM(COCOA)
void handleWheelEventPhase(PlatformWheelEventPhase);
#endif
#if ENABLE(WEB_REPLAY)
void replaySessionStateDidChange();
#endif
WEBCORE_EXPORT void setForceSynchronousScrollLayerPositionUpdates(bool);
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 ) { return newNodeID; }
virtual void detachFromStateTree(ScrollingNodeID) { }
virtual void clearStateTree() { }
virtual void updateViewportConstrainedNode(ScrollingNodeID, const ViewportConstraints&, GraphicsLayer*) { }
struct ScrollingGeometry {
FloatSize scrollableAreaSize;
FloatSize contentSize;
FloatSize reachableContentSize; FloatPoint scrollPosition;
IntPoint scrollOrigin;
#if ENABLE(CSS_SCROLL_SNAP)
Vector<LayoutUnit> horizontalSnapOffsets;
Vector<LayoutUnit> verticalSnapOffsets;
unsigned currentHorizontalSnapPointIndex;
unsigned currentVerticalSnapPointIndex;
#endif
};
virtual void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* , GraphicsLayer* , GraphicsLayer* , GraphicsLayer* , const ScrollingGeometry* = nullptr) { }
virtual void updateOverflowScrollingNode(ScrollingNodeID, GraphicsLayer* , GraphicsLayer* , 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) { }
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;
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);
}
#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()