[iOS WK2] A top fixed bar can flicker when scrolling with the keyboard up
[WebKit-https.git] / Source / WebCore / page / scrolling / ScrollingStateFrameScrollingNode.cpp
1 /*
2  * Copyright (C) 2014, 2016 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 #include "config.h"
27 #include "ScrollingStateFrameScrollingNode.h"
28
29 #if ENABLE(ASYNC_SCROLLING)
30
31 #include "ScrollingStateTree.h"
32 #include <wtf/text/TextStream.h>
33
34 namespace WebCore {
35
36 Ref<ScrollingStateFrameScrollingNode> ScrollingStateFrameScrollingNode::create(ScrollingStateTree& stateTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
37 {
38     return adoptRef(*new ScrollingStateFrameScrollingNode(stateTree, nodeType, nodeID));
39 }
40
41 ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode(ScrollingStateTree& stateTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
42     : ScrollingStateScrollingNode(stateTree, nodeType, nodeID)
43 {
44     ASSERT(isFrameScrollingNode());
45 }
46
47 ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode(const ScrollingStateFrameScrollingNode& stateNode, ScrollingStateTree& adoptiveTree)
48     : ScrollingStateScrollingNode(stateNode, adoptiveTree)
49     , m_eventTrackingRegions(stateNode.eventTrackingRegions())
50     , m_layoutViewport(stateNode.layoutViewport())
51     , m_minLayoutViewportOrigin(stateNode.minLayoutViewportOrigin())
52     , m_maxLayoutViewportOrigin(stateNode.maxLayoutViewportOrigin())
53     , m_overrideVisualViewportSize(stateNode.overrideVisualViewportSize())
54     , m_frameScaleFactor(stateNode.frameScaleFactor())
55     , m_topContentInset(stateNode.topContentInset())
56     , m_headerHeight(stateNode.headerHeight())
57     , m_footerHeight(stateNode.footerHeight())
58     , m_synchronousScrollingReasons(stateNode.synchronousScrollingReasons())
59     , m_behaviorForFixed(stateNode.scrollBehaviorForFixedElements())
60     , m_fixedElementsLayoutRelativeToFrame(stateNode.fixedElementsLayoutRelativeToFrame())
61     , m_visualViewportIsSmallerThanLayoutViewport(stateNode.visualViewportIsSmallerThanLayoutViewport())
62     , m_asyncFrameOrOverflowScrollingEnabled(stateNode.asyncFrameOrOverflowScrollingEnabled())
63 {
64     if (hasChangedProperty(RootContentsLayer))
65         setRootContentsLayer(stateNode.rootContentsLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
66
67     if (hasChangedProperty(CounterScrollingLayer))
68         setCounterScrollingLayer(stateNode.counterScrollingLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
69
70     if (hasChangedProperty(InsetClipLayer))
71         setInsetClipLayer(stateNode.insetClipLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
72
73     if (hasChangedProperty(ContentShadowLayer))
74         setContentShadowLayer(stateNode.contentShadowLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
75
76     if (hasChangedProperty(HeaderLayer))
77         setHeaderLayer(stateNode.headerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
78
79     if (hasChangedProperty(FooterLayer))
80         setFooterLayer(stateNode.footerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
81 }
82
83 ScrollingStateFrameScrollingNode::~ScrollingStateFrameScrollingNode() = default;
84
85 Ref<ScrollingStateNode> ScrollingStateFrameScrollingNode::clone(ScrollingStateTree& adoptiveTree)
86 {
87     return adoptRef(*new ScrollingStateFrameScrollingNode(*this, adoptiveTree));
88 }
89
90 void ScrollingStateFrameScrollingNode::setPropertyChangedBitsAfterReattach()
91 {
92     setPropertyChangedBit(FrameScaleFactor);
93     setPropertyChangedBit(EventTrackingRegion);
94     setPropertyChangedBit(ReasonsForSynchronousScrolling);
95     setPropertyChangedBit(RootContentsLayer);
96     setPropertyChangedBit(ScrolledContentsLayer);
97     setPropertyChangedBit(CounterScrollingLayer);
98     setPropertyChangedBit(InsetClipLayer);
99     setPropertyChangedBit(ContentShadowLayer);
100     setPropertyChangedBit(HeaderHeight);
101     setPropertyChangedBit(FooterHeight);
102     setPropertyChangedBit(HeaderLayer);
103     setPropertyChangedBit(FooterLayer);
104     setPropertyChangedBit(BehaviorForFixedElements);
105     setPropertyChangedBit(TopContentInset);
106     setPropertyChangedBit(FixedElementsLayoutRelativeToFrame);
107     setPropertyChangedBit(VisualViewportIsSmallerThanLayoutViewport);
108     setPropertyChangedBit(AsyncFrameOrOverflowScrollingEnabled);
109     setPropertyChangedBit(LayoutViewport);
110     setPropertyChangedBit(MinLayoutViewportOrigin);
111     setPropertyChangedBit(MaxLayoutViewportOrigin);
112     setPropertyChangedBit(OverrideVisualViewportSize);
113
114     ScrollingStateScrollingNode::setPropertyChangedBitsAfterReattach();
115 }
116
117 void ScrollingStateFrameScrollingNode::setFrameScaleFactor(float scaleFactor)
118 {
119     if (m_frameScaleFactor == scaleFactor)
120         return;
121
122     m_frameScaleFactor = scaleFactor;
123
124     setPropertyChanged(FrameScaleFactor);
125 }
126
127 void ScrollingStateFrameScrollingNode::setEventTrackingRegions(const EventTrackingRegions& eventTrackingRegions)
128 {
129     if (m_eventTrackingRegions == eventTrackingRegions)
130         return;
131
132     m_eventTrackingRegions = eventTrackingRegions;
133     setPropertyChanged(EventTrackingRegion);
134 }
135
136 void ScrollingStateFrameScrollingNode::setSynchronousScrollingReasons(SynchronousScrollingReasons reasons)
137 {
138     if (m_synchronousScrollingReasons == reasons)
139         return;
140
141     m_synchronousScrollingReasons = reasons;
142     setPropertyChanged(ReasonsForSynchronousScrolling);
143 }
144
145 void ScrollingStateFrameScrollingNode::setScrollBehaviorForFixedElements(ScrollBehaviorForFixedElements behaviorForFixed)
146 {
147     if (m_behaviorForFixed == behaviorForFixed)
148         return;
149
150     m_behaviorForFixed = behaviorForFixed;
151     setPropertyChanged(BehaviorForFixedElements);
152 }
153
154 void ScrollingStateFrameScrollingNode::setLayoutViewport(const FloatRect& r)
155 {
156     if (m_layoutViewport == r)
157         return;
158
159     m_layoutViewport = r;
160     setPropertyChanged(LayoutViewport);
161 }
162
163 void ScrollingStateFrameScrollingNode::setMinLayoutViewportOrigin(const FloatPoint& p)
164 {
165     if (m_minLayoutViewportOrigin == p)
166         return;
167
168     m_minLayoutViewportOrigin = p;
169     setPropertyChanged(MinLayoutViewportOrigin);
170 }
171
172 void ScrollingStateFrameScrollingNode::setMaxLayoutViewportOrigin(const FloatPoint& p)
173 {
174     if (m_maxLayoutViewportOrigin == p)
175         return;
176
177     m_maxLayoutViewportOrigin = p;
178     setPropertyChanged(MaxLayoutViewportOrigin);
179 }
180
181 void ScrollingStateFrameScrollingNode::setOverrideVisualViewportSize(Optional<FloatSize> viewportSize)
182 {
183     if (viewportSize == m_overrideVisualViewportSize)
184         return;
185
186     m_overrideVisualViewportSize = viewportSize;
187     setPropertyChanged(OverrideVisualViewportSize);
188 }
189
190 void ScrollingStateFrameScrollingNode::setHeaderHeight(int headerHeight)
191 {
192     if (m_headerHeight == headerHeight)
193         return;
194
195     m_headerHeight = headerHeight;
196     setPropertyChanged(HeaderHeight);
197 }
198
199 void ScrollingStateFrameScrollingNode::setFooterHeight(int footerHeight)
200 {
201     if (m_footerHeight == footerHeight)
202         return;
203
204     m_footerHeight = footerHeight;
205     setPropertyChanged(FooterHeight);
206 }
207
208 void ScrollingStateFrameScrollingNode::setTopContentInset(float topContentInset)
209 {
210     if (m_topContentInset == topContentInset)
211         return;
212
213     m_topContentInset = topContentInset;
214     setPropertyChanged(TopContentInset);
215 }
216
217 void ScrollingStateFrameScrollingNode::setRootContentsLayer(const LayerRepresentation& layerRepresentation)
218 {
219     if (layerRepresentation == m_rootContentsLayer)
220         return;
221
222     m_rootContentsLayer = layerRepresentation;
223     setPropertyChanged(RootContentsLayer);
224 }
225
226 void ScrollingStateFrameScrollingNode::setCounterScrollingLayer(const LayerRepresentation& layerRepresentation)
227 {
228     if (layerRepresentation == m_counterScrollingLayer)
229         return;
230     
231     m_counterScrollingLayer = layerRepresentation;
232     setPropertyChanged(CounterScrollingLayer);
233 }
234
235 void ScrollingStateFrameScrollingNode::setInsetClipLayer(const LayerRepresentation& layerRepresentation)
236 {
237     if (layerRepresentation == m_insetClipLayer)
238         return;
239     
240     m_insetClipLayer = layerRepresentation;
241     setPropertyChanged(InsetClipLayer);
242 }
243
244 void ScrollingStateFrameScrollingNode::setContentShadowLayer(const LayerRepresentation& layerRepresentation)
245 {
246     if (layerRepresentation == m_contentShadowLayer)
247         return;
248     
249     m_contentShadowLayer = layerRepresentation;
250     setPropertyChanged(ContentShadowLayer);
251 }
252
253 void ScrollingStateFrameScrollingNode::setHeaderLayer(const LayerRepresentation& layerRepresentation)
254 {
255     if (layerRepresentation == m_headerLayer)
256         return;
257     
258     m_headerLayer = layerRepresentation;
259     setPropertyChanged(HeaderLayer);
260 }
261
262 void ScrollingStateFrameScrollingNode::setFooterLayer(const LayerRepresentation& layerRepresentation)
263 {
264     if (layerRepresentation == m_footerLayer)
265         return;
266     
267     m_footerLayer = layerRepresentation;
268     setPropertyChanged(FooterLayer);
269 }
270
271 void ScrollingStateFrameScrollingNode::setVisualViewportIsSmallerThanLayoutViewport(bool visualViewportIsSmallerThanLayoutViewport)
272 {
273     if (visualViewportIsSmallerThanLayoutViewport == m_visualViewportIsSmallerThanLayoutViewport)
274         return;
275     
276     m_visualViewportIsSmallerThanLayoutViewport = visualViewportIsSmallerThanLayoutViewport;
277     setPropertyChanged(VisualViewportIsSmallerThanLayoutViewport);
278 }
279
280 void ScrollingStateFrameScrollingNode::setFixedElementsLayoutRelativeToFrame(bool fixedElementsLayoutRelativeToFrame)
281 {
282     if (fixedElementsLayoutRelativeToFrame == m_fixedElementsLayoutRelativeToFrame)
283         return;
284     
285     m_fixedElementsLayoutRelativeToFrame = fixedElementsLayoutRelativeToFrame;
286     setPropertyChanged(FixedElementsLayoutRelativeToFrame);
287 }
288
289 void ScrollingStateFrameScrollingNode::setAsyncFrameOrOverflowScrollingEnabled(bool enabled)
290 {
291     if (enabled == m_asyncFrameOrOverflowScrollingEnabled)
292         return;
293     
294     m_asyncFrameOrOverflowScrollingEnabled = enabled;
295     setPropertyChanged(AsyncFrameOrOverflowScrollingEnabled);
296 }
297
298 void ScrollingStateFrameScrollingNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
299 {
300     ts << "Frame scrolling node";
301     
302     ScrollingStateScrollingNode::dumpProperties(ts, behavior);
303     
304     if (behavior & ScrollingStateTreeAsTextBehaviorIncludeLayerIDs) {
305         ts.dumpProperty("root contents layer ID", m_rootContentsLayer.layerID());
306         ts.dumpProperty("counter scrolling layer ID", m_counterScrollingLayer.layerID());
307         ts.dumpProperty("inset clip layer ID", m_insetClipLayer.layerID());
308         ts.dumpProperty("content shadow layer ID", m_contentShadowLayer.layerID());
309         ts.dumpProperty("header layer ID", m_headerLayer.layerID());
310         ts.dumpProperty("footer layer ID", m_footerLayer.layerID());
311     }
312
313     if (m_frameScaleFactor != 1)
314         ts.dumpProperty("frame scale factor", m_frameScaleFactor);
315     if (m_topContentInset)
316         ts.dumpProperty("top content inset", m_topContentInset);
317     if (m_headerHeight)
318         ts.dumpProperty("header height", m_headerHeight);
319     if (m_footerHeight)
320         ts.dumpProperty("footer height", m_footerHeight);
321     
322     ts.dumpProperty("layout viewport", m_layoutViewport);
323     ts.dumpProperty("min layout viewport origin", m_minLayoutViewportOrigin);
324     ts.dumpProperty("max layout viewport origin", m_maxLayoutViewportOrigin);
325     
326     if (m_overrideVisualViewportSize)
327         ts.dumpProperty("override visual viewport size", m_overrideVisualViewportSize.value());
328
329     if (m_behaviorForFixed == StickToViewportBounds)
330         ts.dumpProperty("behavior for fixed", m_behaviorForFixed);
331
332     if (!m_eventTrackingRegions.asynchronousDispatchRegion.isEmpty()) {
333         TextStream::GroupScope scope(ts);
334         ts << "asynchronous event dispatch region";
335         for (auto rect : m_eventTrackingRegions.asynchronousDispatchRegion.rects()) {
336             ts << "\n";
337             ts << indent << rect;
338         }
339     }
340
341     if (!m_eventTrackingRegions.eventSpecificSynchronousDispatchRegions.isEmpty()) {
342         for (const auto& synchronousEventRegion : m_eventTrackingRegions.eventSpecificSynchronousDispatchRegions) {
343             TextStream::GroupScope scope(ts);
344             ts << "synchronous event dispatch region for event " << synchronousEventRegion.key;
345             for (auto rect : synchronousEventRegion.value.rects()) {
346                 ts << "\n";
347                 ts << indent << rect;
348             }
349         }
350     }
351
352     if (m_synchronousScrollingReasons)
353         ts.dumpProperty("Scrolling on main thread because:", ScrollingCoordinator::synchronousScrollingReasonsAsText(m_synchronousScrollingReasons));
354     
355     ts.dumpProperty("behavior for fixed", m_behaviorForFixed);
356
357     if (m_visualViewportIsSmallerThanLayoutViewport)
358         ts.dumpProperty("visual viewport smaller than layout viewport", m_visualViewportIsSmallerThanLayoutViewport);
359
360     if (m_fixedElementsLayoutRelativeToFrame)
361         ts.dumpProperty("fixed elements lay out relative to frame", m_fixedElementsLayoutRelativeToFrame);
362 }
363
364 } // namespace WebCore
365
366 #endif // ENABLE(ASYNC_SCROLLING)