Implement visual-viewport based position:fixed handling for Mac async scrolling
[WebKit-https.git] / Source / WebCore / page / scrolling / AsyncScrollingCoordinator.h
1 /*
2  * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if ENABLE(ASYNC_SCROLLING)
29
30 #include "ScrollingCoordinator.h"
31 #include "ScrollingTree.h"
32 #include "Timer.h"
33 #include <wtf/PassRefPtr.h>
34 #include <wtf/RefPtr.h>
35
36 namespace WebCore {
37
38 class Page;
39 class Scrollbar;
40 class ScrollingStateNode;
41 class ScrollingStateScrollingNode;
42 class ScrollingStateTree;
43
44 // ScrollingCoordinator subclass that maintains a ScrollingStateTree and a ScrollingTree,
45 // allowing asynchronous scrolling (in another thread or process).
46 class AsyncScrollingCoordinator : public ScrollingCoordinator {
47 public:
48     static Ref<AsyncScrollingCoordinator> create(Page*);
49     WEBCORE_EXPORT virtual ~AsyncScrollingCoordinator();
50
51     ScrollingTree* scrollingTree() const { return m_scrollingTree.get(); }
52
53     void scrollingStateTreePropertiesChanged();
54
55     WEBCORE_EXPORT void scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, const Optional<FloatPoint>& layoutViewportOrigin, bool programmaticScroll, SetOrSyncScrollingLayerPosition);
56
57 #if PLATFORM(COCOA)
58     WEBCORE_EXPORT void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex);
59     void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
60     void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
61 #endif
62
63 #if ENABLE(CSS_SCROLL_SNAP)
64     WEBCORE_EXPORT void updateScrollSnapPropertiesWithFrameView(const FrameView&) override;
65 #endif
66
67 protected:
68     WEBCORE_EXPORT AsyncScrollingCoordinator(Page*);
69
70     void setScrollingTree(PassRefPtr<ScrollingTree> scrollingTree) { m_scrollingTree = scrollingTree; }
71
72     ScrollingStateTree* scrollingStateTree() { return m_scrollingStateTree.get(); }
73
74     PassRefPtr<ScrollingTree> releaseScrollingTree() { return WTFMove(m_scrollingTree); }
75
76     void updateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, Optional<FloatPoint> layoutViewportOrigin, bool programmaticScroll, SetOrSyncScrollingLayerPosition);
77
78     WEBCORE_EXPORT String scrollingStateTreeAsText() const override;
79     WEBCORE_EXPORT void willCommitTree() override;
80
81     bool eventTrackingRegionsDirty() const { return m_eventTrackingRegionsDirty; }
82
83 private:
84     bool isAsyncScrollingCoordinator() const override { return true; }
85
86     bool supportsFixedPositionLayers() const override { return true; }
87     bool hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView&) const override { return false; }
88     
89     bool visualViewportEnabled() const;
90
91     WEBCORE_EXPORT void frameViewLayoutUpdated(FrameView&) override;
92     WEBCORE_EXPORT void frameViewRootLayerDidChange(FrameView&) override;
93     WEBCORE_EXPORT void frameViewEventTrackingRegionsChanged(FrameView&) override;
94
95     WEBCORE_EXPORT bool requestScrollPositionUpdate(FrameView&, const IntPoint&) override;
96
97     WEBCORE_EXPORT ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID) override;
98     WEBCORE_EXPORT void detachFromStateTree(ScrollingNodeID) override;
99     WEBCORE_EXPORT void clearStateTree() override;
100     
101     WEBCORE_EXPORT void updateViewportConstrainedNode(ScrollingNodeID, const ViewportConstraints&, GraphicsLayer*) override;
102     
103     WEBCORE_EXPORT void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* scrollLayer, GraphicsLayer* scrolledContentsLayer, GraphicsLayer* counterScrollingLayer, GraphicsLayer* insetClipLayer, const ScrollingGeometry* = nullptr) override;
104     WEBCORE_EXPORT void updateOverflowScrollingNode(ScrollingNodeID, GraphicsLayer* scrollLayer, GraphicsLayer* scrolledContentsLayer, const ScrollingGeometry* = nullptr) override;
105     
106     bool isRubberBandInProgress() const override;
107     void setScrollPinningBehavior(ScrollPinningBehavior) override;
108
109 #if ENABLE(CSS_SCROLL_SNAP)
110     bool isScrollSnapInProgress() const override;
111 #endif
112
113     WEBCORE_EXPORT void syncChildPositions(const LayoutRect& viewportRect) override;
114     WEBCORE_EXPORT void scrollableAreaScrollbarLayerDidChange(ScrollableArea&, ScrollbarOrientation) override;
115
116     WEBCORE_EXPORT void setSynchronousScrollingReasons(SynchronousScrollingReasons) override;
117
118     virtual void scheduleTreeStateCommit() = 0;
119
120     void ensureRootStateNodeForFrameView(FrameView&);
121     void updateMainFrameScrollLayerPosition();
122
123     void updateScrollPositionAfterAsyncScrollTimerFired();
124     void setEventTrackingRegionsDirty();
125     void updateEventTrackingRegions();
126     
127     FrameView* frameViewForScrollingNode(ScrollingNodeID) const;
128
129     Timer m_updateNodeScrollPositionTimer;
130
131     struct ScheduledScrollUpdate {
132         ScheduledScrollUpdate() = default;
133         ScheduledScrollUpdate(ScrollingNodeID scrollingNodeID, FloatPoint point, Optional<FloatPoint> viewportOrigin, bool isProgrammatic, SetOrSyncScrollingLayerPosition udpateAction)
134             : nodeID(scrollingNodeID)
135             , scrollPosition(point)
136             , layoutViewportOrigin(viewportOrigin)
137             , isProgrammaticScroll(isProgrammatic)
138             , updateLayerPositionAction(udpateAction)
139         { }
140
141         ScrollingNodeID nodeID { 0 };
142         FloatPoint scrollPosition;
143         Optional<FloatPoint> layoutViewportOrigin;
144         bool isProgrammaticScroll { false };
145         SetOrSyncScrollingLayerPosition updateLayerPositionAction { SyncScrollingLayerPosition };
146         
147         bool matchesUpdateType(const ScheduledScrollUpdate& other) const
148         {
149             return nodeID == other.nodeID
150                 && isProgrammaticScroll == other.isProgrammaticScroll
151                 && updateLayerPositionAction == other.updateLayerPositionAction;
152         }
153     };
154
155     ScheduledScrollUpdate m_scheduledScrollUpdate;
156
157     std::unique_ptr<ScrollingStateTree> m_scrollingStateTree;
158     RefPtr<ScrollingTree> m_scrollingTree;
159
160     bool m_eventTrackingRegionsDirty { false };
161 };
162
163 } // namespace WebCore
164
165 SPECIALIZE_TYPE_TRAITS_SCROLLING_COORDINATOR(WebCore::AsyncScrollingCoordinator, isAsyncScrollingCoordinator());
166
167 #endif // ENABLE(ASYNC_SCROLLING)