[Mac] Implement basic hit testing in the scrolling tree
[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/RefPtr.h>
34
35 namespace WebCore {
36
37 class Page;
38 class Scrollbar;
39 class ScrollingStateNode;
40 class ScrollingStateScrollingNode;
41 class ScrollingStateTree;
42
43 // ScrollingCoordinator subclass that maintains a ScrollingStateTree and a ScrollingTree,
44 // allowing asynchronous scrolling (in another thread or process).
45 class AsyncScrollingCoordinator : public ScrollingCoordinator {
46 public:
47     static Ref<AsyncScrollingCoordinator> create(Page*);
48     WEBCORE_EXPORT virtual ~AsyncScrollingCoordinator();
49
50     ScrollingTree* scrollingTree() const { return m_scrollingTree.get(); }
51
52     void scrollingStateTreePropertiesChanged();
53
54     WEBCORE_EXPORT void scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, const Optional<FloatPoint>& layoutViewportOrigin, bool programmaticScroll, ScrollingLayerPositionAction);
55
56 #if PLATFORM(COCOA)
57     WEBCORE_EXPORT void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex);
58     void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
59     void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
60 #endif
61
62 #if ENABLE(CSS_SCROLL_SNAP)
63     WEBCORE_EXPORT void updateScrollSnapPropertiesWithFrameView(const FrameView&) override;
64 #endif
65
66     WEBCORE_EXPORT void updateExpectsWheelEventTestTriggerWithFrameView(const FrameView&) override;
67
68     void reportExposedUnfilledArea(MonotonicTime, unsigned unfilledArea);
69     void reportSynchronousScrollingReasonsChanged(MonotonicTime, SynchronousScrollingReasons);
70
71 protected:
72     WEBCORE_EXPORT AsyncScrollingCoordinator(Page*);
73
74     void setScrollingTree(Ref<ScrollingTree>&& scrollingTree) { m_scrollingTree = WTFMove(scrollingTree); }
75
76     ScrollingStateTree* scrollingStateTree() { return m_scrollingStateTree.get(); }
77
78     RefPtr<ScrollingTree> releaseScrollingTree() { return WTFMove(m_scrollingTree); }
79
80     void updateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, Optional<FloatPoint> layoutViewportOrigin, bool programmaticScroll, ScrollingLayerPositionAction);
81
82     WEBCORE_EXPORT String scrollingStateTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal) const override;
83     WEBCORE_EXPORT void willCommitTree() override;
84
85     bool eventTrackingRegionsDirty() const { return m_eventTrackingRegionsDirty; }
86
87 private:
88     bool isAsyncScrollingCoordinator() const override { return true; }
89
90     bool hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView&) const override { return false; }
91     
92     bool visualViewportEnabled() const;
93     bool asyncFrameOrOverflowScrollingEnabled() const;
94
95     WEBCORE_EXPORT void frameViewLayoutUpdated(FrameView&) override;
96     WEBCORE_EXPORT void frameViewRootLayerDidChange(FrameView&) override;
97     WEBCORE_EXPORT void frameViewEventTrackingRegionsChanged(FrameView&) override;
98
99     WEBCORE_EXPORT bool requestScrollPositionUpdate(FrameView&, const IntPoint&) override;
100
101     WEBCORE_EXPORT ScrollingNodeID createNode(ScrollingNodeType, ScrollingNodeID newNodeID) override;
102     WEBCORE_EXPORT ScrollingNodeID insertNode(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID, size_t childIndex) override;
103     WEBCORE_EXPORT void unparentNode(ScrollingNodeID) override;
104     WEBCORE_EXPORT void unparentChildrenAndDestroyNode(ScrollingNodeID) override;
105     WEBCORE_EXPORT void detachAndDestroySubtree(ScrollingNodeID) override;
106     WEBCORE_EXPORT void clearAllNodes() override;
107
108     WEBCORE_EXPORT ScrollingNodeID parentOfNode(ScrollingNodeID) const override;
109     WEBCORE_EXPORT Vector<ScrollingNodeID> childrenOfNode(ScrollingNodeID) const override;
110
111     WEBCORE_EXPORT void setNodeLayers(ScrollingNodeID, GraphicsLayer* /*layer*/, GraphicsLayer* /*scrolledContentsLayer*/ = nullptr, GraphicsLayer* /*counterScrollingLayer*/ = nullptr, GraphicsLayer* /*insetClipLayer*/ = nullptr) override;
112     WEBCORE_EXPORT void setScrollingNodeGeometry(ScrollingNodeID, const ScrollingGeometry&) override;
113     WEBCORE_EXPORT void setViewportConstraintedNodeGeometry(ScrollingNodeID, const ViewportConstraints&) override;
114
115     WEBCORE_EXPORT void reconcileScrollingState(FrameView&, const FloatPoint&, const LayoutViewportOriginOrOverrideRect&, bool programmaticScroll, ViewportRectStability, ScrollingLayerPositionAction) override;
116
117     bool isRubberBandInProgress() const override;
118     void setScrollPinningBehavior(ScrollPinningBehavior) override;
119
120 #if ENABLE(CSS_SCROLL_SNAP)
121     bool isScrollSnapInProgress() const override;
122 #endif
123
124     WEBCORE_EXPORT void reconcileViewportConstrainedLayerPositions(ScrollingNodeID, const LayoutRect& viewportRect, ScrollingLayerPositionAction) override;
125     WEBCORE_EXPORT void scrollableAreaScrollbarLayerDidChange(ScrollableArea&, ScrollbarOrientation) override;
126
127     WEBCORE_EXPORT void setSynchronousScrollingReasons(FrameView&, SynchronousScrollingReasons) final;
128
129     virtual void scheduleTreeStateCommit() = 0;
130
131     void ensureRootStateNodeForFrameView(FrameView&);
132     void updateScrollLayerPosition(FrameView&);
133
134     void updateScrollPositionAfterAsyncScrollTimerFired();
135     void setEventTrackingRegionsDirty();
136     void updateEventTrackingRegions();
137     
138     FrameView* frameViewForScrollingNode(ScrollingNodeID) const;
139
140     Timer m_updateNodeScrollPositionTimer;
141
142     struct ScheduledScrollUpdate {
143         ScheduledScrollUpdate() = default;
144         ScheduledScrollUpdate(ScrollingNodeID scrollingNodeID, FloatPoint point, Optional<FloatPoint> viewportOrigin, bool isProgrammatic, ScrollingLayerPositionAction udpateAction)
145             : nodeID(scrollingNodeID)
146             , scrollPosition(point)
147             , layoutViewportOrigin(viewportOrigin)
148             , isProgrammaticScroll(isProgrammatic)
149             , updateLayerPositionAction(udpateAction)
150         { }
151
152         ScrollingNodeID nodeID { 0 };
153         FloatPoint scrollPosition;
154         Optional<FloatPoint> layoutViewportOrigin;
155         bool isProgrammaticScroll { false };
156         ScrollingLayerPositionAction updateLayerPositionAction { ScrollingLayerPositionAction::Sync };
157         
158         bool matchesUpdateType(const ScheduledScrollUpdate& other) const
159         {
160             return nodeID == other.nodeID
161                 && isProgrammaticScroll == other.isProgrammaticScroll
162                 && updateLayerPositionAction == other.updateLayerPositionAction;
163         }
164     };
165
166     ScheduledScrollUpdate m_scheduledScrollUpdate;
167
168     std::unique_ptr<ScrollingStateTree> m_scrollingStateTree;
169     RefPtr<ScrollingTree> m_scrollingTree;
170
171     bool m_eventTrackingRegionsDirty { false };
172 };
173
174 } // namespace WebCore
175
176 SPECIALIZE_TYPE_TRAITS_SCROLLING_COORDINATOR(WebCore::AsyncScrollingCoordinator, isAsyncScrollingCoordinator());
177
178 #endif // ENABLE(ASYNC_SCROLLING)