blob: 98d4ecae887c81197bdfc4a7ff7d2c319b90554d [file] [log] [blame]
hyatt@apple.com912c1b12008-09-25 07:38:56 +00001/*
darin@apple.com6c71ce22017-01-14 03:35:54 +00002 * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
hyatt@apple.com912c1b12008-09-25 07:38:56 +00003 *
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 *
mjs@apple.com92047332014-03-15 04:08:27 +000013 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
hyatt@apple.com912c1b12008-09-25 07:38:56 +000014 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
mjs@apple.com92047332014-03-15 04:08:27 +000016 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
hyatt@apple.com912c1b12008-09-25 07:38:56 +000017 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "ScrollView.h"
28
hyatt@apple.com3b82dce2008-10-01 17:51:02 +000029#include "GraphicsContext.h"
jamesr@google.come53ce642011-04-14 06:51:50 +000030#include "GraphicsLayer.h"
hyatt@apple.com70936b52008-09-30 20:09:42 +000031#include "HostWindow.h"
simon.fraser@apple.com37f52692015-12-24 00:35:04 +000032#include "Logging.h"
hyatt@apple.com880cbb12008-09-28 03:51:41 +000033#include "PlatformMouseEvent.h"
hyatt@apple.comaede3de2008-09-28 08:21:09 +000034#include "PlatformWheelEvent.h"
bdakin@apple.com32167522011-02-01 20:35:25 +000035#include "ScrollAnimator.h"
hyatt@apple.com79be62c2008-09-25 22:25:22 +000036#include "Scrollbar.h"
hyatt@apple.com3b82dce2008-10-01 17:51:02 +000037#include "ScrollbarTheme.h"
bolsinga@apple.com4f657472008-11-17 01:05:20 +000038#include <wtf/StdLibExtras.h>
don.olmstead@sony.comd57eb472017-08-10 01:15:14 +000039#include <wtf/text/TextStream.h>
hyatt@apple.com79be62c2008-09-25 22:25:22 +000040
hyatt@apple.com912c1b12008-09-25 07:38:56 +000041namespace WebCore {
42
dbates@webkit.orgf21f3ae2017-10-19 23:48:45 +000043ScrollView::ScrollView() = default;
hyatt@apple.com64a3be22008-09-25 20:49:17 +000044
dbates@webkit.orgf21f3ae2017-10-19 23:48:45 +000045ScrollView::~ScrollView() = default;
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +000046
darin@apple.com6c71ce22017-01-14 03:35:54 +000047void ScrollView::addChild(Widget& child)
hyatt@apple.com912c1b12008-09-25 07:38:56 +000048{
darin@apple.com6c71ce22017-01-14 03:35:54 +000049 ASSERT(&child != this);
50 ASSERT(!child.parent());
51 child.setParent(this);
52 m_children.add(child);
53 if (child.platformWidget())
54 platformAddChild(&child);
hyatt@apple.com912c1b12008-09-25 07:38:56 +000055}
56
cdumez@apple.com63c654d2014-10-09 16:45:32 +000057void ScrollView::removeChild(Widget& child)
hyatt@apple.com912c1b12008-09-25 07:38:56 +000058{
cdumez@apple.com63c654d2014-10-09 16:45:32 +000059 ASSERT(child.parent() == this);
60 child.setParent(nullptr);
61 m_children.remove(&child);
62 if (child.platformWidget())
63 platformRemoveChild(&child);
hyatt@apple.com912c1b12008-09-25 07:38:56 +000064}
65
simon.fraser@apple.com0cdf36c2013-09-20 21:47:47 +000066bool ScrollView::setHasHorizontalScrollbar(bool hasBar, bool* contentSizeAffected)
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +000067{
tonikitoo@webkit.orgbcbbf832016-07-15 20:19:29 +000068 return setHasScrollbarInternal(m_horizontalScrollbar, HorizontalScrollbar, hasBar, contentSizeAffected);
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +000069}
70
simon.fraser@apple.com0cdf36c2013-09-20 21:47:47 +000071bool ScrollView::setHasVerticalScrollbar(bool hasBar, bool* contentSizeAffected)
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +000072{
tonikitoo@webkit.orgbcbbf832016-07-15 20:19:29 +000073 return setHasScrollbarInternal(m_verticalScrollbar, VerticalScrollbar, hasBar, contentSizeAffected);
74}
75
76bool ScrollView::setHasScrollbarInternal(RefPtr<Scrollbar>& scrollbar, ScrollbarOrientation orientation, bool hasBar, bool* contentSizeAffected)
77{
ryuan.choi@samsung.com2d22b11c2011-07-06 19:04:47 +000078 ASSERT(!hasBar || !avoidScrollbarCreation());
tonikitoo@webkit.orgbcbbf832016-07-15 20:19:29 +000079
80 if (hasBar && !scrollbar) {
81 scrollbar = createScrollbar(orientation);
darin@apple.com6c71ce22017-01-14 03:35:54 +000082 addChild(*scrollbar);
tonikitoo@webkit.orgbcbbf832016-07-15 20:19:29 +000083 didAddScrollbar(scrollbar.get(), orientation);
84 scrollbar->styleChanged();
simon.fraser@apple.com0cdf36c2013-09-20 21:47:47 +000085 if (contentSizeAffected)
tonikitoo@webkit.orgbcbbf832016-07-15 20:19:29 +000086 *contentSizeAffected = !scrollbar->isOverlayScrollbar();
simon.fraser@apple.com0cdf36c2013-09-20 21:47:47 +000087 return true;
simon.fraser@apple.com80188472013-09-12 23:28:32 +000088 }
89
tonikitoo@webkit.orgbcbbf832016-07-15 20:19:29 +000090 if (!hasBar && scrollbar) {
91 bool wasOverlayScrollbar = scrollbar->isOverlayScrollbar();
92 willRemoveScrollbar(scrollbar.get(), orientation);
93 removeChild(*scrollbar);
94 scrollbar = nullptr;
simon.fraser@apple.com0cdf36c2013-09-20 21:47:47 +000095 if (contentSizeAffected)
96 *contentSizeAffected = !wasOverlayScrollbar;
97 return true;
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +000098 }
simon.fraser@apple.com80188472013-09-12 23:28:32 +000099
100 return false;
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000101}
102
akling@apple.com2799ae92016-10-25 10:27:12 +0000103Ref<Scrollbar> ScrollView::createScrollbar(ScrollbarOrientation orientation)
hyatt@apple.com0f97fcc2008-12-08 22:36:54 +0000104{
bfulgham@apple.com3cb8c992015-02-21 03:34:09 +0000105 return Scrollbar::createNativeScrollbar(*this, orientation, RegularScrollbar);
hyatt@apple.com0f97fcc2008-12-08 22:36:54 +0000106}
107
tonikitoo@webkit.org18656ae2010-04-08 14:38:12 +0000108void ScrollView::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode,
109 bool horizontalLock, bool verticalLock)
hyatt@apple.com01adde82008-09-26 20:49:34 +0000110{
tonikitoo@webkit.org18656ae2010-04-08 14:38:12 +0000111 bool needsUpdate = false;
112
113 if (horizontalMode != horizontalScrollbarMode() && !m_horizontalScrollbarLock) {
114 m_horizontalScrollbarMode = horizontalMode;
115 needsUpdate = true;
116 }
117
118 if (verticalMode != verticalScrollbarMode() && !m_verticalScrollbarLock) {
119 m_verticalScrollbarMode = verticalMode;
120 needsUpdate = true;
121 }
122
123 if (horizontalLock)
124 setHorizontalScrollbarLock();
125
126 if (verticalLock)
127 setVerticalScrollbarLock();
128
129 if (!needsUpdate)
hyatt@apple.com4ce2a1d2008-09-29 20:09:59 +0000130 return;
tonikitoo@webkit.org18656ae2010-04-08 14:38:12 +0000131
hyatt@apple.com01adde82008-09-26 20:49:34 +0000132 if (platformWidget())
133 platformSetScrollbarModes();
134 else
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000135 updateScrollbars(scrollPosition());
hyatt@apple.com01adde82008-09-26 20:49:34 +0000136}
137
138void ScrollView::scrollbarModes(ScrollbarMode& horizontalMode, ScrollbarMode& verticalMode) const
139{
140 if (platformWidget()) {
141 platformScrollbarModes(horizontalMode, verticalMode);
142 return;
143 }
144 horizontalMode = m_horizontalScrollbarMode;
145 verticalMode = m_verticalScrollbarMode;
146}
147
hyatt@apple.com2f029122008-10-01 22:12:23 +0000148void ScrollView::setCanHaveScrollbars(bool canScroll)
hyatt@apple.comb37db692008-09-27 04:43:00 +0000149{
150 ScrollbarMode newHorizontalMode;
151 ScrollbarMode newVerticalMode;
152
153 scrollbarModes(newHorizontalMode, newVerticalMode);
154
155 if (canScroll && newVerticalMode == ScrollbarAlwaysOff)
156 newVerticalMode = ScrollbarAuto;
157 else if (!canScroll)
158 newVerticalMode = ScrollbarAlwaysOff;
159
160 if (canScroll && newHorizontalMode == ScrollbarAlwaysOff)
161 newHorizontalMode = ScrollbarAuto;
162 else if (!canScroll)
163 newHorizontalMode = ScrollbarAlwaysOff;
164
165 setScrollbarModes(newHorizontalMode, newVerticalMode);
166}
167
hyatt@apple.com64a3be22008-09-25 20:49:17 +0000168void ScrollView::setCanBlitOnScroll(bool b)
169{
cwzwarich@webkit.orgd96b94e2008-12-11 21:56:07 +0000170 if (platformWidget()) {
171 platformSetCanBlitOnScroll(b);
hyatt@apple.com64a3be22008-09-25 20:49:17 +0000172 return;
cwzwarich@webkit.orgd96b94e2008-12-11 21:56:07 +0000173 }
174
hyatt@apple.com64a3be22008-09-25 20:49:17 +0000175 m_canBlitOnScroll = b;
cwzwarich@webkit.orgd96b94e2008-12-11 21:56:07 +0000176}
177
178bool ScrollView::canBlitOnScroll() const
179{
hyatt@apple.com64a3be22008-09-25 20:49:17 +0000180 if (platformWidget())
cwzwarich@webkit.orgd96b94e2008-12-11 21:56:07 +0000181 return platformCanBlitOnScroll();
182
183 return m_canBlitOnScroll;
hyatt@apple.com64a3be22008-09-25 20:49:17 +0000184}
185
kenneth@webkit.org9ba62222009-12-03 14:25:50 +0000186void ScrollView::setPaintsEntireContents(bool paintsEntireContents)
187{
188 m_paintsEntireContents = paintsEntireContents;
189}
190
andreas.kling@nokia.com51bae852010-11-23 16:58:46 +0000191void ScrollView::setDelegatesScrolling(bool delegatesScrolling)
192{
noam.rosenthal@nokia.com91de1b52012-01-27 15:35:40 +0000193 if (m_delegatesScrolling == delegatesScrolling)
194 return;
195
andreas.kling@nokia.com51bae852010-11-23 16:58:46 +0000196 m_delegatesScrolling = delegatesScrolling;
noam.rosenthal@nokia.com91de1b52012-01-27 15:35:40 +0000197 delegatesScrollingDidChange();
andreas.kling@nokia.com51bae852010-11-23 16:58:46 +0000198}
simon.fraser@apple.com53149ac2014-03-21 18:56:04 +0000199
simon.fraser@apple.com947a90e2014-04-18 20:31:35 +0000200IntPoint ScrollView::contentsScrollPosition() const
201{
ap@apple.com1e8475922018-10-18 21:38:50 +0000202#if PLATFORM(IOS_FAMILY)
simon.fraser@apple.com947a90e2014-04-18 20:31:35 +0000203 if (platformWidget())
204 return actualScrollPosition();
205#endif
206 return scrollPosition();
207}
208
209void ScrollView::setContentsScrollPosition(const IntPoint& position)
210{
ap@apple.com1e8475922018-10-18 21:38:50 +0000211#if PLATFORM(IOS_FAMILY)
simon.fraser@apple.com947a90e2014-04-18 20:31:35 +0000212 if (platformWidget())
213 setActualScrollPosition(position);
214#endif
215 setScrollPosition(position);
216}
217
ap@apple.com1e8475922018-10-18 21:38:50 +0000218#if !PLATFORM(IOS_FAMILY)
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000219IntRect ScrollView::unobscuredContentRect(VisibleContentRectIncludesScrollbars scrollbarInclusion) const
220{
simon.fraser@apple.com53149ac2014-03-21 18:56:04 +0000221 return unobscuredContentRectInternal(scrollbarInclusion);
222}
223#endif
224
225IntRect ScrollView::unobscuredContentRectInternal(VisibleContentRectIncludesScrollbars scrollbarInclusion) const
226{
simon.fraser@apple.com82c0d2d2016-11-05 00:55:43 +0000227 FloatSize visibleContentSize = sizeForUnobscuredContent(scrollbarInclusion);
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000228 visibleContentSize.scale(1 / visibleContentScaleFactor());
simon.fraser@apple.com149e80d2015-12-31 18:50:10 +0000229 return IntRect(m_scrollPosition, expandedIntSize(visibleContentSize));
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000230}
simon.fraser@apple.com53149ac2014-03-21 18:56:04 +0000231
simon.fraser@apple.com82c0d2d2016-11-05 00:55:43 +0000232IntSize ScrollView::sizeForVisibleContent(VisibleContentRectIncludesScrollbars scrollbarInclusion) const
hyatt@apple.com79be62c2008-09-25 22:25:22 +0000233{
234 if (platformWidget())
bdakin@apple.com3834ce72014-08-01 22:47:57 +0000235 return platformVisibleContentSizeIncludingObscuredArea(scrollbarInclusion == IncludeScrollbars);
andreas.kling@nokia.com7f1b0a42010-11-11 12:38:58 +0000236
ryuan.choi@navercorp.com05ea83f2015-04-29 05:05:48 +0000237#if USE(COORDINATED_GRAPHICS)
commit-queue@webkit.org1c60f942016-07-23 15:25:42 +0000238 if (m_useFixedLayout && !m_fixedVisibleContentRect.isEmpty())
aelias@chromium.orgd230b352013-01-29 06:19:10 +0000239 return m_fixedVisibleContentRect.size();
dbates@webkit.orgb8ade582014-01-09 22:59:07 +0000240#endif
andreas.kling@nokia.come066ecf2010-11-17 22:02:28 +0000241
simon.fraser@apple.com870034d2015-12-16 23:41:05 +0000242 IntSize scrollbarSpace;
243 if (scrollbarInclusion == ExcludeScrollbars)
244 scrollbarSpace = scrollbarIntrusion();
kling@webkit.org8c0a7db2011-12-07 16:40:31 +0000245
simon.fraser@apple.com870034d2015-12-16 23:41:05 +0000246 return IntSize(width() - scrollbarSpace.width(), height() - scrollbarSpace.height()).expandedTo(IntSize());
hyatt@apple.comc01fb232008-09-26 04:28:25 +0000247}
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000248
simon.fraser@apple.com82c0d2d2016-11-05 00:55:43 +0000249IntSize ScrollView::sizeForUnobscuredContent(VisibleContentRectIncludesScrollbars scrollbarInclusion) const
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000250{
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000251 if (platformWidget())
bdakin@apple.com35d64202014-08-01 22:39:52 +0000252 return platformVisibleContentSize(scrollbarInclusion == IncludeScrollbars);
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000253
simon.fraser@apple.com82c0d2d2016-11-05 00:55:43 +0000254 IntSize visibleContentSize = sizeForVisibleContent(scrollbarInclusion);
255
ryuan.choi@navercorp.com05ea83f2015-04-29 05:05:48 +0000256#if USE(COORDINATED_GRAPHICS)
commit-queue@webkit.org1c60f942016-07-23 15:25:42 +0000257 if (m_useFixedLayout && !m_fixedVisibleContentRect.isEmpty())
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000258 return visibleContentSize;
259#endif
260
261 visibleContentSize.setHeight(visibleContentSize.height() - topContentInset());
262 return visibleContentSize;
263}
aelias@chromium.orgd230b352013-01-29 06:19:10 +0000264
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000265IntRect ScrollView::visibleContentRectInternal(VisibleContentRectIncludesScrollbars scrollbarInclusion, VisibleContentRectBehavior visibleContentRectBehavior) const
aelias@chromium.orgd230b352013-01-29 06:19:10 +0000266{
ap@apple.com1e8475922018-10-18 21:38:50 +0000267#if PLATFORM(IOS_FAMILY)
simon.fraser@apple.com846bdab2014-01-24 00:39:46 +0000268 if (visibleContentRectBehavior == LegacyIOSDocumentViewRect) {
269 if (platformWidget())
commit-queue@webkit.org13f92152014-10-02 06:10:59 +0000270 return platformVisibleContentRect(scrollbarInclusion == IncludeScrollbars);
simon.fraser@apple.com846bdab2014-01-24 00:39:46 +0000271 }
272
273 if (platformWidget())
simon.fraser@apple.com53149ac2014-03-21 18:56:04 +0000274 return unobscuredContentRect(scrollbarInclusion);
simon.fraser@apple.com846bdab2014-01-24 00:39:46 +0000275#else
276 UNUSED_PARAM(visibleContentRectBehavior);
277#endif
278
aelias@chromium.orgd230b352013-01-29 06:19:10 +0000279 if (platformWidget())
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000280 return platformVisibleContentRect(scrollbarInclusion == IncludeScrollbars);
aelias@chromium.orgd230b352013-01-29 06:19:10 +0000281
ryuan.choi@navercorp.com05ea83f2015-04-29 05:05:48 +0000282#if USE(COORDINATED_GRAPHICS)
commit-queue@webkit.org1c60f942016-07-23 15:25:42 +0000283 if (m_useFixedLayout && !m_fixedVisibleContentRect.isEmpty())
aelias@chromium.orgd230b352013-01-29 06:19:10 +0000284 return m_fixedVisibleContentRect;
dbates@webkit.orgb8ade582014-01-09 22:59:07 +0000285#endif
aelias@chromium.orgd230b352013-01-29 06:19:10 +0000286
benjamin@webkit.org78113d02014-05-16 21:39:43 +0000287 return unobscuredContentRect(scrollbarInclusion);
aelias@chromium.orgd230b352013-01-29 06:19:10 +0000288}
hyatt@apple.comc01fb232008-09-26 04:28:25 +0000289
simon.fraser@apple.comece04672012-06-07 17:57:00 +0000290IntSize ScrollView::layoutSize() const
291{
simon.fraser@apple.com82c0d2d2016-11-05 00:55:43 +0000292 return m_fixedLayoutSize.isEmpty() || !m_useFixedLayout ? sizeForUnobscuredContent() : m_fixedLayoutSize;
treat@webkit.org17db32f2009-01-04 17:25:30 +0000293}
294
eae@chromium.org92a579f2011-11-08 02:11:06 +0000295IntSize ScrollView::fixedLayoutSize() const
treat@webkit.org17db32f2009-01-04 17:25:30 +0000296{
297 return m_fixedLayoutSize;
298}
299
eae@chromium.org92a579f2011-11-08 02:11:06 +0000300void ScrollView::setFixedLayoutSize(const IntSize& newSize)
treat@webkit.org17db32f2009-01-04 17:25:30 +0000301{
302 if (fixedLayoutSize() == newSize)
303 return;
simon.fraser@apple.com677f0422017-12-02 17:55:24 +0000304
305 LOG_WITH_STREAM(Layout, stream << "ScrollView " << this << " setFixedLayoutSize " << newSize);
treat@webkit.org17db32f2009-01-04 17:25:30 +0000306 m_fixedLayoutSize = newSize;
aelias@chromium.org3d1c26a2013-01-31 19:25:41 +0000307 if (m_useFixedLayout)
simon.fraser@apple.com448c42e2015-02-25 05:35:38 +0000308 availableContentSizeChanged(AvailableSizeChangeReason::AreaSizeChanged);
treat@webkit.org17db32f2009-01-04 17:25:30 +0000309}
310
311bool ScrollView::useFixedLayout() const
312{
313 return m_useFixedLayout;
314}
315
316void ScrollView::setUseFixedLayout(bool enable)
317{
318 if (useFixedLayout() == enable)
319 return;
320 m_useFixedLayout = enable;
allan.jensen@digia.com970a0bf2013-08-14 11:29:32 +0000321 if (!m_fixedLayoutSize.isEmpty())
simon.fraser@apple.com448c42e2015-02-25 05:35:38 +0000322 availableContentSizeChanged(AvailableSizeChangeReason::AreaSizeChanged);
allan.jensen@digia.com970a0bf2013-08-14 11:29:32 +0000323}
324
simon.fraser@apple.com448c42e2015-02-25 05:35:38 +0000325void ScrollView::availableContentSizeChanged(AvailableSizeChangeReason reason)
allan.jensen@digia.com970a0bf2013-08-14 11:29:32 +0000326{
simon.fraser@apple.com448c42e2015-02-25 05:35:38 +0000327 ScrollableArea::availableContentSizeChanged(reason);
simon.fraser@apple.com346c8be2015-03-01 04:36:39 +0000328
329 if (platformWidget())
330 return;
331
simon.fraser@apple.com448c42e2015-02-25 05:35:38 +0000332 if (reason != AvailableSizeChangeReason::ScrollbarsChanged)
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000333 updateScrollbars(scrollPosition());
treat@webkit.org17db32f2009-01-04 17:25:30 +0000334}
335
eae@chromium.org92a579f2011-11-08 02:11:06 +0000336IntSize ScrollView::contentsSize() const
hyatt@apple.comc01fb232008-09-26 04:28:25 +0000337{
hyatt@apple.comc01fb232008-09-26 04:28:25 +0000338 return m_contentsSize;
hyatt@apple.com79be62c2008-09-25 22:25:22 +0000339}
340
eae@chromium.org92a579f2011-11-08 02:11:06 +0000341void ScrollView::setContentsSize(const IntSize& newSize)
hyatt@apple.com25cd25e2008-09-26 06:07:14 +0000342{
343 if (contentsSize() == newSize)
344 return;
345 m_contentsSize = newSize;
346 if (platformWidget())
347 platformSetContentsSize();
348 else
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000349 updateScrollbars(scrollPosition());
commit-queue@webkit.orgc1e94362012-02-22 20:18:30 +0000350 updateOverhangAreas();
hyatt@apple.com25cd25e2008-09-26 06:07:14 +0000351}
352
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000353ScrollPosition ScrollView::maximumScrollPosition() const
hyatt@apple.com7eedf8f2008-09-26 05:40:50 +0000354{
simon.fraser@apple.comefc492b2015-12-30 20:15:27 +0000355 ScrollPosition maximumPosition = ScrollableArea::maximumScrollPosition();
356 // FIXME: can this be moved into the base class?
357 maximumPosition.clampNegativeToZero();
358 return maximumPosition;
xji@chromium.org506e6f62010-11-30 01:11:08 +0000359}
360
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000361ScrollPosition ScrollView::adjustScrollPositionWithinRange(const ScrollPosition& scrollPoint) const
xji@chromium.org506e6f62010-11-30 01:11:08 +0000362{
simon.fraser@apple.comd61b65e2017-01-30 19:46:40 +0000363 if (!constrainsScrollingToContentEdge() || m_allowsUnclampedScrollPosition)
tonikitoo@webkit.orgc45e9b32012-04-20 19:11:52 +0000364 return scrollPoint;
365
simon.fraser@apple.come84dd142015-12-24 03:43:23 +0000366 return scrollPoint.constrainedBetween(minimumScrollPosition(), maximumScrollPosition());
hyatt@apple.com7eedf8f2008-09-26 05:40:50 +0000367}
368
simon.fraser@apple.com94cc9c22016-01-01 03:17:31 +0000369ScrollPosition ScrollView::documentScrollPositionRelativeToViewOrigin() const
bdakin@apple.comb622f312013-04-10 20:57:25 +0000370{
mmaxfield@apple.com11fab7d2016-03-18 01:02:32 +0000371 return scrollPosition() - IntSize(
mmaxfield@apple.com4195a702016-04-27 01:25:26 +0000372 shouldPlaceBlockDirectionScrollbarOnLeft() && m_verticalScrollbar ? m_verticalScrollbar->occupiedWidth() : 0,
mmaxfield@apple.com11fab7d2016-03-18 01:02:32 +0000373 headerHeight() + topContentInset(TopContentInsetType::WebCoreOrPlatformContentInset));
bdakin@apple.comb622f312013-04-10 20:57:25 +0000374}
375
simon.fraser@apple.com94cc9c22016-01-01 03:17:31 +0000376ScrollPosition ScrollView::documentScrollPositionRelativeToScrollableAreaOrigin() const
bdakin@apple.comfd0dfc82013-04-17 23:23:20 +0000377{
simon.fraser@apple.com94cc9c22016-01-01 03:17:31 +0000378 return scrollPosition() - IntSize(0, headerHeight());
bdakin@apple.com19403f82014-05-14 00:13:56 +0000379}
380
commit-queue@webkit.org1bf3b4b2010-09-08 19:31:47 +0000381int ScrollView::scrollSize(ScrollbarOrientation orientation) const
382{
tonikitoo@webkit.orgb65231f2012-04-27 03:08:47 +0000383 // If no scrollbars are present, it does not indicate content is not be scrollable.
384 if (!m_horizontalScrollbar && !m_verticalScrollbar && !prohibitsScrolling()) {
aestes@apple.com0f23b262014-01-29 03:06:01 +0000385 IntSize scrollSize = m_contentsSize - visibleContentRect(LegacyIOSDocumentVisibleRect).size();
tonikitoo@webkit.orgb65231f2012-04-27 03:08:47 +0000386 scrollSize.clampNegativeToZero();
387 return orientation == HorizontalScrollbar ? scrollSize.width() : scrollSize.height();
388 }
389
390 Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_horizontalScrollbar : m_verticalScrollbar).get();
391 return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
commit-queue@webkit.org1bf3b4b2010-09-08 19:31:47 +0000392}
393
bdakin@apple.com9e05cff2011-03-16 02:21:59 +0000394void ScrollView::notifyPageThatContentAreaWillPaint() const
395{
396}
397
simon.fraser@apple.coma10a6d42016-01-02 04:45:36 +0000398void ScrollView::setScrollOffset(const ScrollOffset& offset)
commit-queue@webkit.org1bf3b4b2010-09-08 19:31:47 +0000399{
simon.fraser@apple.comd61b65e2017-01-30 19:46:40 +0000400 LOG_WITH_STREAM(Scrolling, stream << "\nScrollView::setScrollOffset " << offset << " constrains " << constrainsScrollingToContentEdge());
simon.fraser@apple.coma10a6d42016-01-02 04:45:36 +0000401
simon.fraser@apple.comefc492b2015-12-30 20:15:27 +0000402 IntPoint constrainedOffset = offset;
403 if (constrainsScrollingToContentEdge())
404 constrainedOffset = constrainedOffset.constrainedBetween(IntPoint(), maximumScrollOffset());
weinig@apple.com2a13aa82011-01-20 23:14:47 +0000405
simon.fraser@apple.com149e80d2015-12-31 18:50:10 +0000406 scrollTo(scrollPositionFromOffset(constrainedOffset));
commit-queue@webkit.org1bf3b4b2010-09-08 19:31:47 +0000407}
408
simon.fraser@apple.com3d2abaa2015-12-31 19:35:18 +0000409void ScrollView::scrollOffsetChangedViaPlatformWidget(const ScrollOffset& oldOffset, const ScrollOffset& newOffset)
bfulgham@apple.coma41524c2015-01-19 20:02:01 +0000410{
411 // We should not attempt to actually modify (paint) platform widgets if the layout phase
412 // is not complete. Instead, defer the scroll event until the layout finishes.
413 if (shouldDeferScrollUpdateAfterContentSizeChange()) {
414 // We only care about the most recent scroll position change request
cdumez@apple.comcaf90682016-05-16 20:24:52 +0000415 m_deferredScrollOffsets = std::make_pair(oldOffset, newOffset);
bfulgham@apple.coma41524c2015-01-19 20:02:01 +0000416 return;
417 }
418
simon.fraser@apple.com3d2abaa2015-12-31 19:35:18 +0000419 scrollOffsetChangedViaPlatformWidgetImpl(oldOffset, newOffset);
bfulgham@apple.coma41524c2015-01-19 20:02:01 +0000420}
421
422void ScrollView::handleDeferredScrollUpdateAfterContentSizeChange()
423{
424 ASSERT(!shouldDeferScrollUpdateAfterContentSizeChange());
425
simon.fraser@apple.com3d2abaa2015-12-31 19:35:18 +0000426 if (!m_deferredScrollDelta && !m_deferredScrollOffsets)
bfulgham@apple.coma41524c2015-01-19 20:02:01 +0000427 return;
428
simon.fraser@apple.com3d2abaa2015-12-31 19:35:18 +0000429 ASSERT(static_cast<bool>(m_deferredScrollDelta) != static_cast<bool>(m_deferredScrollOffsets));
bfulgham@apple.coma41524c2015-01-19 20:02:01 +0000430
431 if (m_deferredScrollDelta)
cdumez@apple.comcaf90682016-05-16 20:24:52 +0000432 completeUpdatesAfterScrollTo(m_deferredScrollDelta.value());
simon.fraser@apple.com3d2abaa2015-12-31 19:35:18 +0000433 else if (m_deferredScrollOffsets)
cdumez@apple.comcaf90682016-05-16 20:24:52 +0000434 scrollOffsetChangedViaPlatformWidgetImpl(m_deferredScrollOffsets.value().first, m_deferredScrollOffsets.value().second);
bfulgham@apple.coma41524c2015-01-19 20:02:01 +0000435
utatane.tea@gmail.com43926962016-11-27 06:08:16 +0000436 m_deferredScrollDelta = std::nullopt;
437 m_deferredScrollOffsets = std::nullopt;
bfulgham@apple.coma41524c2015-01-19 20:02:01 +0000438}
439
simon.fraser@apple.com149e80d2015-12-31 18:50:10 +0000440void ScrollView::scrollTo(const ScrollPosition& newPosition)
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000441{
simon.fraser@apple.coma10a6d42016-01-02 04:45:36 +0000442 LOG_WITH_STREAM(Scrolling, stream << "ScrollView::scrollTo " << newPosition << " min: " << minimumScrollPosition() << " max: " << maximumScrollPosition());
443
simon.fraser@apple.com149e80d2015-12-31 18:50:10 +0000444 IntSize scrollDelta = newPosition - m_scrollPosition;
bfulgham@apple.coma41524c2015-01-19 20:02:01 +0000445 if (scrollDelta.isZero())
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000446 return;
simon.fraser@apple.com149e80d2015-12-31 18:50:10 +0000447
448 m_scrollPosition = newPosition;
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000449
450 if (scrollbarsSuppressed())
451 return;
452
ryuan.choi@navercorp.com05ea83f2015-04-29 05:05:48 +0000453#if USE(COORDINATED_GRAPHICS)
commit-queue@webkit.orgf03960f2012-05-15 15:07:59 +0000454 if (delegatesScrolling()) {
simon.fraser@apple.com149e80d2015-12-31 18:50:10 +0000455 requestScrollPositionUpdate(newPosition);
commit-queue@webkit.orgf03960f2012-05-15 15:07:59 +0000456 return;
457 }
458#endif
bfulgham@apple.coma41524c2015-01-19 20:02:01 +0000459 // We should not attempt to actually modify layer contents if the layout phase
460 // is not complete. Instead, defer the scroll event until the layout finishes.
461 if (shouldDeferScrollUpdateAfterContentSizeChange()) {
462 ASSERT(!m_deferredScrollDelta);
cdumez@apple.comcaf90682016-05-16 20:24:52 +0000463 m_deferredScrollDelta = scrollDelta;
bfulgham@apple.coma41524c2015-01-19 20:02:01 +0000464 return;
465 }
466
467 completeUpdatesAfterScrollTo(scrollDelta);
468}
469
470void ScrollView::completeUpdatesAfterScrollTo(const IntSize& scrollDelta)
471{
simon.fraser@apple.com71ffa3d2013-11-13 22:22:14 +0000472 updateLayerPositionsAfterScrolling();
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000473 scrollContents(scrollDelta);
simon.fraser@apple.com71ffa3d2013-11-13 22:22:14 +0000474 updateCompositingLayersAfterScrolling();
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000475}
476
simon.fraser@apple.com936d9212016-01-03 19:50:51 +0000477int ScrollView::scrollOffset(ScrollbarOrientation orientation) const
commit-queue@webkit.org4a8bb262010-09-13 06:24:41 +0000478{
simon.fraser@apple.com936d9212016-01-03 19:50:51 +0000479 ScrollOffset offset = scrollOffsetFromPosition(scrollPosition());
480
481 if (orientation == HorizontalScrollbar)
482 return offset.x();
483
484 if (orientation == VerticalScrollbar)
485 return offset.y();
486
weinig@apple.com2a13aa82011-01-20 23:14:47 +0000487 return 0;
commit-queue@webkit.org4a8bb262010-09-13 06:24:41 +0000488}
489
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000490void ScrollView::setScrollPosition(const ScrollPosition& scrollPosition)
hyatt@apple.com90abd562008-09-29 19:46:37 +0000491{
simon.fraser@apple.coma10a6d42016-01-02 04:45:36 +0000492 LOG_WITH_STREAM(Scrolling, stream << "ScrollView::setScrollPosition " << scrollPosition);
493
hyatt@apple.comdeb39ee2008-10-01 22:30:56 +0000494 if (prohibitsScrolling())
495 return;
496
hyatt@apple.com90abd562008-09-29 19:46:37 +0000497 if (platformWidget()) {
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000498 platformSetScrollPosition(scrollPosition);
hyatt@apple.com90abd562008-09-29 19:46:37 +0000499 return;
500 }
501
simon.fraser@apple.com3d2abaa2015-12-31 19:35:18 +0000502 ScrollPosition newScrollPosition = !delegatesScrolling() ? adjustScrollPositionWithinRange(scrollPosition) : scrollPosition;
andreas.kling@nokia.com7d61c562010-11-17 21:16:11 +0000503
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000504 if ((!delegatesScrolling() || !inProgrammaticScroll()) && newScrollPosition == this->scrollPosition())
hyatt@apple.com90abd562008-09-29 19:46:37 +0000505 return;
506
benjamin@webkit.orge0b04c12013-06-09 19:52:49 +0000507 if (requestScrollPositionUpdate(newScrollPosition))
508 return;
509
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000510 updateScrollbars(newScrollPosition);
hyatt@apple.com90abd562008-09-29 19:46:37 +0000511}
512
513bool ScrollView::scroll(ScrollDirection direction, ScrollGranularity granularity)
514{
tonikitoo@webkit.org3d484882010-10-10 14:23:49 +0000515 if (platformWidget())
hyatt@apple.com90abd562008-09-29 19:46:37 +0000516 return platformScroll(direction, granularity);
weinig@apple.com2a13aa82011-01-20 23:14:47 +0000517
weinig@apple.comd7d77c32011-01-21 20:15:04 +0000518 return ScrollableArea::scroll(direction, granularity);
hyatt@apple.com90abd562008-09-29 19:46:37 +0000519}
520
hyatt@apple.coma60d0ce2010-12-13 20:14:28 +0000521bool ScrollView::logicalScroll(ScrollLogicalDirection direction, ScrollGranularity granularity)
522{
523 return scroll(logicalToPhysical(direction, isVerticalDocument(), isFlippedDocument()), granularity);
524}
525
eae@chromium.org92a579f2011-11-08 02:11:06 +0000526IntSize ScrollView::overhangAmount() const
weinig@apple.comcc0f1402011-01-28 19:05:43 +0000527{
eae@chromium.org92a579f2011-11-08 02:11:06 +0000528 IntSize stretch;
weinig@apple.comcc0f1402011-01-28 19:05:43 +0000529
simon.fraser@apple.comefc492b2015-12-30 20:15:27 +0000530 // FIXME: use maximumScrollOffset()
531 ScrollOffset scrollOffset = scrollOffsetFromPosition(scrollPosition());
532 if (scrollOffset.y() < 0)
533 stretch.setHeight(scrollOffset.y());
534 else if (totalContentsSize().height() && scrollOffset.y() > totalContentsSize().height() - visibleHeight())
535 stretch.setHeight(scrollOffset.y() - (totalContentsSize().height() - visibleHeight()));
weinig@apple.com8c019242011-03-10 21:43:37 +0000536
simon.fraser@apple.comefc492b2015-12-30 20:15:27 +0000537 if (scrollOffset.x() < 0)
538 stretch.setWidth(scrollOffset.x());
539 else if (contentsWidth() && scrollOffset.x() > contentsWidth() - visibleWidth())
540 stretch.setWidth(scrollOffset.x() - (contentsWidth() - visibleWidth()));
weinig@apple.comcc0f1402011-01-28 19:05:43 +0000541
542 return stretch;
543}
544
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000545void ScrollView::updateScrollbars(const ScrollPosition& desiredPosition)
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000546{
simon.fraser@apple.coma10a6d42016-01-02 04:45:36 +0000547 LOG_WITH_STREAM(Scrolling, stream << "ScrollView::updateScrollbars " << desiredPosition);
548
simon.fraser@apple.com0235bd52016-03-19 00:00:46 +0000549 if (m_inUpdateScrollbars || prohibitsScrolling() || platformWidget())
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000550 return;
simon.fraser@apple.com0235bd52016-03-19 00:00:46 +0000551
552 if (delegatesScrolling()) {
553 if (scrollOriginChanged()) {
554 ScrollableArea::scrollToOffsetWithoutAnimation(scrollOffsetFromPosition(desiredPosition));
555 resetScrollOriginChanged();
556 }
557 return;
558 }
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000559
antti@apple.comdf985172014-01-22 13:07:25 +0000560 bool hasOverlayScrollbars = (!m_horizontalScrollbar || m_horizontalScrollbar->isOverlayScrollbar()) && (!m_verticalScrollbar || m_verticalScrollbar->isOverlayScrollbar());
561
simon.fraser@apple.com03e61032015-04-05 20:17:11 +0000562 // If we came in here with the view already needing a layout then do that first.
563 // (This will be the common case, e.g., when the page changes due to window resizing for example).
dglazkov@chromium.orgf0234eb2009-09-04 17:59:46 +0000564 // This layout will not re-enter updateScrollbars and does not count towards our max layout pass total.
antti@apple.comdf985172014-01-22 13:07:25 +0000565 if (!m_scrollbarsSuppressed && !hasOverlayScrollbars) {
dglazkov@chromium.orgf0234eb2009-09-04 17:59:46 +0000566 m_inUpdateScrollbars = true;
simon.fraser@apple.com448c42e2015-02-25 05:35:38 +0000567 updateContentsSize();
dglazkov@chromium.orgf0234eb2009-09-04 17:59:46 +0000568 m_inUpdateScrollbars = false;
569 }
570
eae@chromium.org92a579f2011-11-08 02:11:06 +0000571 IntRect oldScrollCornerRect = scrollCornerRect();
simon.fraser@apple.comc8bf6392011-09-27 19:00:56 +0000572
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000573 bool hasHorizontalScrollbar = m_horizontalScrollbar;
hyatt@apple.com82b02812009-04-08 22:33:48 +0000574 bool hasVerticalScrollbar = m_verticalScrollbar;
575
576 bool newHasHorizontalScrollbar = hasHorizontalScrollbar;
577 bool newHasVerticalScrollbar = hasVerticalScrollbar;
578
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000579 ScrollbarMode hScroll = m_horizontalScrollbarMode;
580 ScrollbarMode vScroll = m_verticalScrollbarMode;
581
dglazkov@chromium.orgc0e2d522009-04-23 22:33:25 +0000582 if (hScroll != ScrollbarAuto)
583 newHasHorizontalScrollbar = (hScroll == ScrollbarAlwaysOn);
584 if (vScroll != ScrollbarAuto)
585 newHasVerticalScrollbar = (vScroll == ScrollbarAlwaysOn);
586
simon.fraser@apple.com0cdf36c2013-09-20 21:47:47 +0000587 bool scrollbarAddedOrRemoved = false;
588
hyatt@apple.com82b02812009-04-08 22:33:48 +0000589 if (m_scrollbarsSuppressed || (hScroll != ScrollbarAuto && vScroll != ScrollbarAuto)) {
simon.fraser@apple.com0cdf36c2013-09-20 21:47:47 +0000590 if (hasHorizontalScrollbar != newHasHorizontalScrollbar && (hasHorizontalScrollbar || !avoidScrollbarCreation())) {
591 if (setHasHorizontalScrollbar(newHasHorizontalScrollbar))
592 scrollbarAddedOrRemoved = true;
593 }
594
595 if (hasVerticalScrollbar != newHasVerticalScrollbar && (hasVerticalScrollbar || !avoidScrollbarCreation())) {
596 if (setHasVerticalScrollbar(newHasVerticalScrollbar))
597 scrollbarAddedOrRemoved = true;
598 }
hyatt@apple.com82b02812009-04-08 22:33:48 +0000599 } else {
600 bool sendContentResizedNotification = false;
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000601
bdakin@apple.com9d3bf062013-03-28 00:42:35 +0000602 IntSize docSize = totalContentsSize();
benjamin@webkit.org25bc57c2014-03-10 21:25:24 +0000603 IntSize fullVisibleSize = unobscuredContentRectIncludingScrollbars().size();
hyatt@apple.comf931bc72009-05-26 18:16:58 +0000604
antti@apple.comdf985172014-01-22 13:07:25 +0000605 if (hScroll == ScrollbarAuto)
hyatt@apple.com82b02812009-04-08 22:33:48 +0000606 newHasHorizontalScrollbar = docSize.width() > visibleWidth();
antti@apple.comdf985172014-01-22 13:07:25 +0000607 if (vScroll == ScrollbarAuto)
commit-queue@webkit.orga0590002014-01-21 18:06:06 +0000608 newHasVerticalScrollbar = docSize.height() > visibleHeight();
commit-queue@webkit.orga0590002014-01-21 18:06:06 +0000609
commit-queue@webkit.orga0590002014-01-21 18:06:06 +0000610 bool needAnotherPass = false;
antti@apple.comdf985172014-01-22 13:07:25 +0000611 if (!hasOverlayScrollbars) {
commit-queue@webkit.org9c71a892017-10-31 20:27:18 +0000612 // If we ever turn one scrollbar off, do not turn the other one on. Never ever
antti@apple.comdf985172014-01-22 13:07:25 +0000613 // try to both gain/lose a scrollbar in the same pass.
614 if (!m_updateScrollbarsPass && docSize.width() <= fullVisibleSize.width() && docSize.height() <= fullVisibleSize.height()) {
615 if (hScroll == ScrollbarAuto)
616 newHasHorizontalScrollbar = false;
617 if (vScroll == ScrollbarAuto)
618 newHasVerticalScrollbar = false;
619 }
commit-queue@webkit.orgfc726872017-11-03 18:32:19 +0000620 if (!newHasHorizontalScrollbar && hasHorizontalScrollbar && vScroll != ScrollbarAlwaysOn && !hasVerticalScrollbar) {
antti@apple.comdf985172014-01-22 13:07:25 +0000621 newHasVerticalScrollbar = false;
622 needAnotherPass = true;
623 }
commit-queue@webkit.org9c71a892017-10-31 20:27:18 +0000624 if (!newHasVerticalScrollbar && hasVerticalScrollbar && hScroll != ScrollbarAlwaysOn && !hasHorizontalScrollbar) {
antti@apple.comdf985172014-01-22 13:07:25 +0000625 newHasHorizontalScrollbar = false;
626 needAnotherPass = true;
627 }
simon.fraser@apple.comf760ec12013-11-08 23:53:54 +0000628 }
hyatt@apple.com82b02812009-04-08 22:33:48 +0000629
ryuan.choi@samsung.com2d22b11c2011-07-06 19:04:47 +0000630 if (hasHorizontalScrollbar != newHasHorizontalScrollbar && (hasHorizontalScrollbar || !avoidScrollbarCreation())) {
xji@chromium.org85d87542011-11-01 22:06:46 +0000631 if (scrollOrigin().y() && !newHasHorizontalScrollbar)
simon.fraser@apple.comfc5a7a32015-12-17 06:56:55 +0000632 ScrollableArea::setScrollOrigin(IntPoint(scrollOrigin().x(), scrollOrigin().y() - m_horizontalScrollbar->occupiedHeight()));
simon.fraser@apple.com3c063c22011-10-10 20:05:16 +0000633 if (m_horizontalScrollbar)
634 m_horizontalScrollbar->invalidate();
simon.fraser@apple.com80188472013-09-12 23:28:32 +0000635
simon.fraser@apple.com0cdf36c2013-09-20 21:47:47 +0000636 bool changeAffectsContentSize = false;
637 if (setHasHorizontalScrollbar(newHasHorizontalScrollbar, &changeAffectsContentSize)) {
638 scrollbarAddedOrRemoved = true;
639 sendContentResizedNotification |= changeAffectsContentSize;
640 }
hyatt@apple.com82b02812009-04-08 22:33:48 +0000641 }
dglazkov@chromium.orgc0e2d522009-04-23 22:33:25 +0000642
ryuan.choi@samsung.com2d22b11c2011-07-06 19:04:47 +0000643 if (hasVerticalScrollbar != newHasVerticalScrollbar && (hasVerticalScrollbar || !avoidScrollbarCreation())) {
xji@chromium.org85d87542011-11-01 22:06:46 +0000644 if (scrollOrigin().x() && !newHasVerticalScrollbar)
simon.fraser@apple.comfc5a7a32015-12-17 06:56:55 +0000645 ScrollableArea::setScrollOrigin(IntPoint(scrollOrigin().x() - m_verticalScrollbar->occupiedWidth(), scrollOrigin().y()));
simon.fraser@apple.com3c063c22011-10-10 20:05:16 +0000646 if (m_verticalScrollbar)
647 m_verticalScrollbar->invalidate();
simon.fraser@apple.com80188472013-09-12 23:28:32 +0000648
simon.fraser@apple.com0cdf36c2013-09-20 21:47:47 +0000649 bool changeAffectsContentSize = false;
650 if (setHasVerticalScrollbar(newHasVerticalScrollbar, &changeAffectsContentSize)) {
651 scrollbarAddedOrRemoved = true;
652 sendContentResizedNotification |= changeAffectsContentSize;
653 }
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000654 }
655
benjamin@webkit.org34ad5622014-04-17 03:26:53 +0000656 const unsigned cMaxUpdateScrollbarsPass = 2;
simon.fraser@apple.comf760ec12013-11-08 23:53:54 +0000657 if ((sendContentResizedNotification || needAnotherPass) && m_updateScrollbarsPass < cMaxUpdateScrollbarsPass) {
hyatt@apple.com82b02812009-04-08 22:33:48 +0000658 m_updateScrollbarsPass++;
simon.fraser@apple.com448c42e2015-02-25 05:35:38 +0000659 availableContentSizeChanged(AvailableSizeChangeReason::ScrollbarsChanged);
660 updateContentsSize();
bdakin@apple.com9d3bf062013-03-28 00:42:35 +0000661 IntSize newDocSize = totalContentsSize();
hyatt@apple.com3d454b72009-04-08 23:06:52 +0000662 if (newDocSize == docSize) {
hyatt@apple.com82b02812009-04-08 22:33:48 +0000663 // The layout with the new scroll state had no impact on
664 // the document's overall size, so updateScrollbars didn't get called.
665 // Recur manually.
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000666 updateScrollbars(desiredPosition);
hyatt@apple.com82b02812009-04-08 22:33:48 +0000667 }
668 m_updateScrollbarsPass--;
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000669 }
670 }
jer.noble@apple.combfdbdad2014-01-07 22:31:49 +0000671
672 if (scrollbarAddedOrRemoved)
673 addedOrRemovedScrollbar();
674
hyatt@apple.com82b02812009-04-08 22:33:48 +0000675 // Set up the range (and page step/line step), but only do this if we're not in a nested call (to avoid
676 // doing it multiple times).
677 if (m_updateScrollbarsPass)
678 return;
679
hyatt@apple.comaa5afdb2009-04-13 21:34:21 +0000680 m_inUpdateScrollbars = true;
xji@chromium.org506e6f62010-11-30 01:11:08 +0000681
zecke@webkit.org815d9a12009-05-27 05:25:48 +0000682 if (m_horizontalScrollbar) {
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000683 int clientWidth = visibleWidth();
bfulgham@apple.com0ef31c32014-08-06 23:04:05 +0000684 int pageStep = Scrollbar::pageStep(clientWidth);
eae@chromium.org92a579f2011-11-08 02:11:06 +0000685 IntRect oldRect(m_horizontalScrollbar->frameRect());
mmaxfield@apple.com4195a702016-04-27 01:25:26 +0000686 IntRect hBarRect(shouldPlaceBlockDirectionScrollbarOnLeft() && m_verticalScrollbar ? m_verticalScrollbar->occupiedWidth() : 0,
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000687 height() - m_horizontalScrollbar->height(),
carlosgc@webkit.org93bbb732016-01-27 10:28:49 +0000688 width() - (m_verticalScrollbar ? m_verticalScrollbar->occupiedWidth() : 0),
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000689 m_horizontalScrollbar->height());
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000690 m_horizontalScrollbar->setFrameRect(hBarRect);
691 if (!m_scrollbarsSuppressed && oldRect != m_horizontalScrollbar->frameRect())
692 m_horizontalScrollbar->invalidate();
693
694 if (m_scrollbarsSuppressed)
695 m_horizontalScrollbar->setSuppressInvalidation(true);
mitz@apple.comb26148f2011-10-06 23:42:57 +0000696 m_horizontalScrollbar->setEnabled(contentsWidth() > clientWidth);
mitz@apple.comed850032010-02-04 17:35:58 +0000697 m_horizontalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000698 m_horizontalScrollbar->setProportion(clientWidth, contentsWidth());
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000699 if (m_scrollbarsSuppressed)
700 m_horizontalScrollbar->setSuppressInvalidation(false);
701 }
702
zecke@webkit.org815d9a12009-05-27 05:25:48 +0000703 if (m_verticalScrollbar) {
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000704 int clientHeight = visibleHeight();
bfulgham@apple.com0ef31c32014-08-06 23:04:05 +0000705 int pageStep = Scrollbar::pageStep(clientHeight);
eae@chromium.org92a579f2011-11-08 02:11:06 +0000706 IntRect oldRect(m_verticalScrollbar->frameRect());
mmaxfield@apple.com4195a702016-04-27 01:25:26 +0000707 IntRect vBarRect(shouldPlaceBlockDirectionScrollbarOnLeft() ? 0 : width() - m_verticalScrollbar->width(),
bdakin@apple.com572c9f32014-03-20 23:19:04 +0000708 topContentInset(),
709 m_verticalScrollbar->width(),
carlosgc@webkit.org93bbb732016-01-27 10:28:49 +0000710 height() - topContentInset() - (m_horizontalScrollbar ? m_horizontalScrollbar->occupiedHeight() : 0));
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000711 m_verticalScrollbar->setFrameRect(vBarRect);
712 if (!m_scrollbarsSuppressed && oldRect != m_verticalScrollbar->frameRect())
713 m_verticalScrollbar->invalidate();
714
715 if (m_scrollbarsSuppressed)
716 m_verticalScrollbar->setSuppressInvalidation(true);
bdakin@apple.com9d3bf062013-03-28 00:42:35 +0000717 m_verticalScrollbar->setEnabled(totalContentsSize().height() > clientHeight);
mitz@apple.comed850032010-02-04 17:35:58 +0000718 m_verticalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
bdakin@apple.com9d3bf062013-03-28 00:42:35 +0000719 m_verticalScrollbar->setProportion(clientHeight, totalContentsSize().height());
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000720 if (m_scrollbarsSuppressed)
721 m_verticalScrollbar->setSuppressInvalidation(false);
722 }
723
commit-queue@webkit.orgc977b8f2013-01-30 06:30:43 +0000724 if (hasHorizontalScrollbar != newHasHorizontalScrollbar || hasVerticalScrollbar != newHasVerticalScrollbar) {
aroben@apple.com9f9a70a2011-05-13 17:24:55 +0000725 // FIXME: Is frameRectsChanged really necessary here? Have any frame rects changed?
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000726 frameRectsChanged();
aroben@apple.com9f9a70a2011-05-13 17:24:55 +0000727 positionScrollbarLayers();
andersca@apple.com7d8fe982009-08-20 00:04:48 +0000728 updateScrollCorner();
simon.fraser@apple.comc8bf6392011-09-27 19:00:56 +0000729 if (!m_horizontalScrollbar && !m_verticalScrollbar)
730 invalidateScrollCornerRect(oldScrollCornerRect);
andersca@apple.com7d8fe982009-08-20 00:04:48 +0000731 }
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000732
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000733 IntPoint adjustedScrollPosition = desiredPosition;
bdakin@apple.comc975f552013-01-23 20:17:01 +0000734 if (!isRubberBandInProgress())
735 adjustedScrollPosition = adjustScrollPositionWithinRange(adjustedScrollPosition);
andersca@apple.com84d12b82012-03-14 20:07:42 +0000736
xji@chromium.org24f57402011-11-08 22:22:24 +0000737 if (adjustedScrollPosition != scrollPosition() || scrollOriginChanged()) {
simon.fraser@apple.comefc492b2015-12-30 20:15:27 +0000738 ScrollableArea::scrollToOffsetWithoutAnimation(scrollOffsetFromPosition(adjustedScrollPosition));
bdakin@apple.com096c9622011-12-08 19:19:05 +0000739 resetScrollOriginChanged();
xji@chromium.org24f57402011-11-08 22:22:24 +0000740 }
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000741
weinig@apple.com155785f2011-02-04 00:11:25 +0000742 // Make sure the scrollbar offsets are up to date.
743 if (m_horizontalScrollbar)
744 m_horizontalScrollbar->offsetDidChange();
745 if (m_verticalScrollbar)
746 m_verticalScrollbar->offsetDidChange();
747
hyatt@apple.comaa5afdb2009-04-13 21:34:21 +0000748 m_inUpdateScrollbars = false;
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000749}
750
eric@webkit.orgac25cf22009-08-21 19:02:20 +0000751const int panIconSizeLength = 16;
hyatt@apple.com98682b32008-10-02 20:17:08 +0000752
simon.fraser@apple.com856ca862011-04-24 05:53:06 +0000753IntRect ScrollView::rectToCopyOnScroll() const
754{
andersca@apple.comfdd25eb2011-11-15 17:54:52 +0000755 IntRect scrollViewRect = convertToRootView(IntRect(0, 0, visibleWidth(), visibleHeight()));
simon.fraser@apple.com856ca862011-04-24 05:53:06 +0000756 if (hasOverlayScrollbars()) {
eae@chromium.org92a579f2011-11-08 02:11:06 +0000757 int verticalScrollbarWidth = (verticalScrollbar() && !hasLayerForVerticalScrollbar()) ? verticalScrollbar()->width() : 0;
758 int horizontalScrollbarHeight = (horizontalScrollbar() && !hasLayerForHorizontalScrollbar()) ? horizontalScrollbar()->height() : 0;
simon.fraser@apple.com856ca862011-04-24 05:53:06 +0000759
760 scrollViewRect.setWidth(scrollViewRect.width() - verticalScrollbarWidth);
761 scrollViewRect.setHeight(scrollViewRect.height() - horizontalScrollbarHeight);
762 }
763 return scrollViewRect;
764}
765
hyatt@apple.com98682b32008-10-02 20:17:08 +0000766void ScrollView::scrollContents(const IntSize& scrollDelta)
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000767{
commit-queue@webkit.org6121dfd2013-06-28 11:14:18 +0000768 HostWindow* window = hostWindow();
769 if (!window)
darin@chromium.orgfbf46582009-02-26 19:32:49 +0000770 return;
771
hyatt@apple.com98682b32008-10-02 20:17:08 +0000772 // Since scrolling is double buffered, we will be blitting the scroll view's intersection
773 // with the clip rect every time to keep it smooth.
hyatt@apple.com6fa40c52008-10-03 07:06:28 +0000774 IntRect clipRect = windowClipRect();
simon.fraser@apple.com856ca862011-04-24 05:53:06 +0000775 IntRect scrollViewRect = rectToCopyOnScroll();
hyatt@apple.com98682b32008-10-02 20:17:08 +0000776 IntRect updateRect = clipRect;
777 updateRect.intersect(scrollViewRect);
778
andersca@apple.comfdd25eb2011-11-15 17:54:52 +0000779 // Invalidate the root view (not the backing store).
commit-queue@webkit.org4149b932014-02-24 19:05:21 +0000780 window->invalidateRootView(updateRect);
hyatt@apple.com98682b32008-10-02 20:17:08 +0000781
782 if (m_drawPanScrollIcon) {
simon.fraser@apple.com2fb2dbf2010-10-26 01:06:30 +0000783 // FIXME: the pan icon is broken when accelerated compositing is on, since it will draw under the compositing layers.
784 // https://bugs.webkit.org/show_bug.cgi?id=47837
andersca@apple.com86298632013-11-10 19:32:33 +0000785 int panIconDirtySquareSizeLength = 2 * (panIconSizeLength + std::max(abs(scrollDelta.width()), abs(scrollDelta.height()))); // We only want to repaint what's necessary
eae@chromium.org92a579f2011-11-08 02:11:06 +0000786 IntPoint panIconDirtySquareLocation = IntPoint(m_panScrollIconPoint.x() - (panIconDirtySquareSizeLength / 2), m_panScrollIconPoint.y() - (panIconDirtySquareSizeLength / 2));
787 IntRect panScrollIconDirtyRect = IntRect(panIconDirtySquareLocation, IntSize(panIconDirtySquareSizeLength, panIconDirtySquareSizeLength));
hyatt@apple.com98682b32008-10-02 20:17:08 +0000788 panScrollIconDirtyRect.intersect(clipRect);
commit-queue@webkit.org4149b932014-02-24 19:05:21 +0000789 window->invalidateContentsAndRootView(panScrollIconDirtyRect);
hyatt@apple.com98682b32008-10-02 20:17:08 +0000790 }
791
eric@webkit.orgd14c4c62010-01-14 12:15:03 +0000792 if (canBlitOnScroll()) { // The main frame can just blit the WebView window
eric@webkit.org3754c522010-03-12 07:07:06 +0000793 // FIXME: Find a way to scroll subframes with this faster path
benjamin.poulain@nokia.com3e960352010-06-23 14:11:26 +0000794 if (!scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect))
simon.fraser@apple.com2fb2dbf2010-10-26 01:06:30 +0000795 scrollContentsSlowPath(updateRect);
hyatt@apple.com98682b32008-10-02 20:17:08 +0000796 } else {
simon.fraser@apple.com03e61032015-04-05 20:17:11 +0000797 // We need to repaint the entire backing store. Do it now before moving the windowed plugins.
798 scrollContentsSlowPath(updateRect);
hyatt@apple.com98682b32008-10-02 20:17:08 +0000799 }
800
weinig@apple.com69c853d2011-02-22 01:18:23 +0000801 // Invalidate the overhang areas if they are visible.
commit-queue@webkit.orgc1e94362012-02-22 20:18:30 +0000802 updateOverhangAreas();
weinig@apple.com69c853d2011-02-22 01:18:23 +0000803
hyatt@apple.com98682b32008-10-02 20:17:08 +0000804 // This call will move children with native widgets (plugins) and invalidate them as well.
805 frameRectsChanged();
806
treat@webkit.orgea795242010-03-08 19:43:43 +0000807 // Now blit the backingstore into the window which should be very fast.
commit-queue@webkit.org4149b932014-02-24 19:05:21 +0000808 window->invalidateRootView(IntRect());
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000809}
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +0000810
simon.fraser@apple.com2fb2dbf2010-10-26 01:06:30 +0000811void ScrollView::scrollContentsSlowPath(const IntRect& updateRect)
812{
commit-queue@webkit.org4149b932014-02-24 19:05:21 +0000813 hostWindow()->invalidateContentsForSlowScroll(updateRect);
simon.fraser@apple.com2fb2dbf2010-10-26 01:06:30 +0000814}
815
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000816IntPoint ScrollView::viewToContents(const IntPoint& point) const
817{
simon.fraser@apple.com94cc9c22016-01-01 03:17:31 +0000818 return point + toIntSize(documentScrollPositionRelativeToViewOrigin());
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000819}
820
821IntPoint ScrollView::contentsToView(const IntPoint& point) const
822{
simon.fraser@apple.com94cc9c22016-01-01 03:17:31 +0000823 return point - toIntSize(documentScrollPositionRelativeToViewOrigin());
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000824}
825
826IntRect ScrollView::viewToContents(IntRect rect) const
827{
simon.fraser@apple.com94cc9c22016-01-01 03:17:31 +0000828 rect.moveBy(documentScrollPositionRelativeToViewOrigin());
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000829 return rect;
830}
831
ajuma@chromium.org5eefc542018-11-02 16:55:13 +0000832FloatRect ScrollView::viewToContents(FloatRect rect) const
833{
834 rect.moveBy(documentScrollPositionRelativeToViewOrigin());
835 return rect;
836}
837
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000838IntRect ScrollView::contentsToView(IntRect rect) const
839{
simon.fraser@apple.com94cc9c22016-01-01 03:17:31 +0000840 rect.moveBy(-documentScrollPositionRelativeToViewOrigin());
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000841 return rect;
842}
843
ajuma@chromium.org5eefc542018-11-02 16:55:13 +0000844FloatRect ScrollView::contentsToView(FloatRect rect) const
845{
846 rect.moveBy(-documentScrollPositionRelativeToViewOrigin());
847 return rect;
848}
849
simon.fraser@apple.com37f52692015-12-24 00:35:04 +0000850IntPoint ScrollView::contentsToContainingViewContents(const IntPoint& point) const
851{
852 if (const ScrollView* parentScrollView = parent()) {
853 IntPoint pointInContainingView = convertToContainingView(contentsToView(point));
854 return parentScrollView->viewToContents(pointInContainingView);
855 }
856
857 return contentsToView(point);
858}
859
860IntRect ScrollView::contentsToContainingViewContents(IntRect rect) const
861{
n_wang@apple.come626f712018-06-29 23:33:30 +0000862 if (delegatesScrolling())
863 return convertToContainingView(contentsToView(rect));
864
simon.fraser@apple.com37f52692015-12-24 00:35:04 +0000865 if (const ScrollView* parentScrollView = parent()) {
866 IntRect rectInContainingView = convertToContainingView(contentsToView(rect));
867 return parentScrollView->viewToContents(rectInContainingView);
868 }
869
870 return contentsToView(rect);
871}
872
jeffm@apple.com13f98eb2011-10-14 22:11:12 +0000873IntPoint ScrollView::rootViewToContents(const IntPoint& rootViewPoint) const
874{
enrica@apple.com2a78a512014-02-12 22:37:20 +0000875 if (delegatesScrolling())
876 return convertFromRootView(rootViewPoint);
877
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000878 return viewToContents(convertFromRootView(rootViewPoint));
jeffm@apple.com13f98eb2011-10-14 22:11:12 +0000879}
880
881IntPoint ScrollView::contentsToRootView(const IntPoint& contentsPoint) const
882{
enrica@apple.com2a78a512014-02-12 22:37:20 +0000883 if (delegatesScrolling())
884 return convertToRootView(contentsPoint);
885
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000886 return convertToRootView(contentsToView(contentsPoint));
jeffm@apple.com13f98eb2011-10-14 22:11:12 +0000887}
888
889IntRect ScrollView::rootViewToContents(const IntRect& rootViewRect) const
890{
enrica@apple.com2a78a512014-02-12 22:37:20 +0000891 if (delegatesScrolling())
892 return convertFromRootView(rootViewRect);
893
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000894 return viewToContents(convertFromRootView(rootViewRect));
jeffm@apple.com13f98eb2011-10-14 22:11:12 +0000895}
896
ajuma@chromium.org5eefc542018-11-02 16:55:13 +0000897FloatRect ScrollView::rootViewToContents(const FloatRect& rootViewRect) const
898{
899 if (delegatesScrolling())
900 return convertFromRootView(rootViewRect);
901
902 return viewToContents(convertFromRootView(rootViewRect));
903}
904
weinig@apple.com29098d32013-05-01 01:24:57 +0000905IntPoint ScrollView::rootViewToTotalContents(const IntPoint& rootViewPoint) const
906{
enrica@apple.com2a78a512014-02-12 22:37:20 +0000907 if (delegatesScrolling())
908 return convertFromRootView(rootViewPoint);
909
weinig@apple.com29098d32013-05-01 01:24:57 +0000910 IntPoint viewPoint = convertFromRootView(rootViewPoint);
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000911 // Like rootViewToContents(), but ignores headerHeight.
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +0000912 return viewPoint + toIntSize(scrollPosition()) - IntSize(0, topContentInset(TopContentInsetType::WebCoreOrPlatformContentInset));
weinig@apple.com29098d32013-05-01 01:24:57 +0000913}
914
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000915IntRect ScrollView::contentsToRootView(const IntRect& contentsRect) const
916{
917 if (delegatesScrolling())
918 return convertToRootView(contentsRect);
919
920 return convertToRootView(contentsToView(contentsRect));
921}
922
hyatt@apple.com0315e532008-09-27 06:23:58 +0000923IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const
924{
zeno.albisser@nokia.com1bbb63c2011-11-17 14:15:36 +0000925 if (delegatesScrolling())
926 return convertFromContainingWindow(windowPoint);
927
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000928 return viewToContents(convertFromContainingWindow(windowPoint));
hyatt@apple.com0315e532008-09-27 06:23:58 +0000929}
930
931IntPoint ScrollView::contentsToWindow(const IntPoint& contentsPoint) const
932{
zeno.albisser@nokia.com1bbb63c2011-11-17 14:15:36 +0000933 if (delegatesScrolling())
934 return convertToContainingWindow(contentsPoint);
935
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000936 return convertToContainingWindow(contentsToView(contentsPoint));
hyatt@apple.com0315e532008-09-27 06:23:58 +0000937}
938
939IntRect ScrollView::windowToContents(const IntRect& windowRect) const
940{
zeno.albisser@nokia.com1bbb63c2011-11-17 14:15:36 +0000941 if (delegatesScrolling())
942 return convertFromContainingWindow(windowRect);
943
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000944 return viewToContents(convertFromContainingWindow(windowRect));
hyatt@apple.com0315e532008-09-27 06:23:58 +0000945}
946
947IntRect ScrollView::contentsToWindow(const IntRect& contentsRect) const
948{
zeno.albisser@nokia.com1bbb63c2011-11-17 14:15:36 +0000949 if (delegatesScrolling())
950 return convertToContainingWindow(contentsRect);
951
simon.fraser@apple.comf06ee4b2015-04-28 21:51:04 +0000952 return convertToContainingWindow(contentsToView(contentsRect));
hyatt@apple.com0315e532008-09-27 06:23:58 +0000953}
954
hyatt@apple.comfe9c1302008-10-01 20:34:07 +0000955IntRect ScrollView::contentsToScreen(const IntRect& rect) const
956{
commit-queue@webkit.org6121dfd2013-06-28 11:14:18 +0000957 HostWindow* window = hostWindow();
hyatt@apple.comfe9c1302008-10-01 20:34:07 +0000958 if (platformWidget())
959 return platformContentsToScreen(rect);
commit-queue@webkit.org6121dfd2013-06-28 11:14:18 +0000960 if (!window)
alice.liu@apple.com3c49db42009-06-21 05:42:39 +0000961 return IntRect();
commit-queue@webkit.org6121dfd2013-06-28 11:14:18 +0000962 return window->rootViewToScreen(contentsToRootView(rect));
hyatt@apple.comfe9c1302008-10-01 20:34:07 +0000963}
964
eae@chromium.org92a579f2011-11-08 02:11:06 +0000965IntPoint ScrollView::screenToContents(const IntPoint& point) const
hyatt@apple.comfe9c1302008-10-01 20:34:07 +0000966{
commit-queue@webkit.org6121dfd2013-06-28 11:14:18 +0000967 HostWindow* window = hostWindow();
hyatt@apple.comfe9c1302008-10-01 20:34:07 +0000968 if (platformWidget())
969 return platformScreenToContents(point);
commit-queue@webkit.org6121dfd2013-06-28 11:14:18 +0000970 if (!window)
eae@chromium.org92a579f2011-11-08 02:11:06 +0000971 return IntPoint();
commit-queue@webkit.org6121dfd2013-06-28 11:14:18 +0000972 return rootViewToContents(window->screenToRootView(point));
hyatt@apple.comfe9c1302008-10-01 20:34:07 +0000973}
974
hyatt@apple.come6f04e52008-09-28 01:07:05 +0000975void ScrollView::setScrollbarsSuppressed(bool suppressed, bool repaintOnUnsuppress)
976{
977 if (suppressed == m_scrollbarsSuppressed)
978 return;
979
980 m_scrollbarsSuppressed = suppressed;
981
982 if (platformWidget())
983 platformSetScrollbarsSuppressed(repaintOnUnsuppress);
984 else if (repaintOnUnsuppress && !suppressed) {
985 if (m_horizontalScrollbar)
986 m_horizontalScrollbar->invalidate();
987 if (m_verticalScrollbar)
988 m_verticalScrollbar->invalidate();
989
990 // Invalidate the scroll corner too on unsuppress.
andersca@apple.com7d8fe982009-08-20 00:04:48 +0000991 invalidateRect(scrollCornerRect());
hyatt@apple.come6f04e52008-09-28 01:07:05 +0000992 }
993}
994
bweinstein@apple.com817c6022009-06-30 18:23:49 +0000995Scrollbar* ScrollView::scrollbarAtPoint(const IntPoint& windowPoint)
hyatt@apple.com880cbb12008-09-28 03:51:41 +0000996{
997 if (platformWidget())
998 return 0;
999
bdakin@apple.com92001822015-12-16 18:08:57 +00001000 // convertFromContainingWindow doesn't do what it sounds like it does. We need it here just to get this
1001 // point into the right coordinates if this is the ScrollView of a sub-frame.
1002 IntPoint convertedPoint = convertFromContainingWindow(windowPoint);
1003 if (m_horizontalScrollbar && m_horizontalScrollbar->shouldParticipateInHitTesting() && m_horizontalScrollbar->frameRect().contains(convertedPoint))
hyatt@apple.com880cbb12008-09-28 03:51:41 +00001004 return m_horizontalScrollbar.get();
bdakin@apple.com92001822015-12-16 18:08:57 +00001005 if (m_verticalScrollbar && m_verticalScrollbar->shouldParticipateInHitTesting() && m_verticalScrollbar->frameRect().contains(convertedPoint))
hyatt@apple.com880cbb12008-09-28 03:51:41 +00001006 return m_verticalScrollbar.get();
1007 return 0;
1008}
1009
commit-queue@webkit.orgb31092d2011-07-21 01:32:17 +00001010void ScrollView::setScrollbarOverlayStyle(ScrollbarOverlayStyle overlayStyle)
1011{
1012 ScrollableArea::setScrollbarOverlayStyle(overlayStyle);
1013 platformSetScrollbarOverlayStyle(overlayStyle);
1014}
1015
eae@chromium.org92a579f2011-11-08 02:11:06 +00001016void ScrollView::setFrameRect(const IntRect& newRect)
hyatt@apple.comc5a54f42008-10-01 19:23:05 +00001017{
beidson@apple.com7bd3d3b2016-05-13 23:42:17 +00001018 Ref<ScrollView> protectedThis(*this);
eae@chromium.org92a579f2011-11-08 02:11:06 +00001019 IntRect oldRect = frameRect();
hyatt@apple.comc5a54f42008-10-01 19:23:05 +00001020
1021 if (newRect == oldRect)
1022 return;
1023
1024 Widget::setFrameRect(newRect);
aroben@apple.com9f9a70a2011-05-13 17:24:55 +00001025 frameRectsChanged();
timothy_horton@apple.combd1cdca2015-04-03 06:37:15 +00001026
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +00001027 updateScrollbars(scrollPosition());
simon.fraser@apple.com448c42e2015-02-25 05:35:38 +00001028
mitz@apple.com2153ba02012-03-01 22:42:44 +00001029 if (!m_useFixedLayout && oldRect.size() != newRect.size())
simon.fraser@apple.com448c42e2015-02-25 05:35:38 +00001030 availableContentSizeChanged(AvailableSizeChangeReason::AreaSizeChanged);
mitz@apple.comeb5f9a52011-02-21 03:06:48 +00001031}
1032
vestbo@webkit.org70da8f02008-12-11 10:09:50 +00001033void ScrollView::frameRectsChanged()
hyatt@apple.com2225aef2008-09-28 08:52:26 +00001034{
1035 if (platformWidget())
1036 return;
darin@apple.com6c71ce22017-01-14 03:35:54 +00001037 for (auto& child : m_children)
1038 child->frameRectsChanged();
hyatt@apple.com2225aef2008-09-28 08:52:26 +00001039}
1040
commit-queue@webkit.org216b5ea2013-02-27 22:05:07 +00001041void ScrollView::clipRectChanged()
1042{
darin@apple.com6c71ce22017-01-14 03:35:54 +00001043 for (auto& child : m_children)
1044 child->clipRectChanged();
commit-queue@webkit.org216b5ea2013-02-27 22:05:07 +00001045}
1046
jamesr@google.come53ce642011-04-14 06:51:50 +00001047static void positionScrollbarLayer(GraphicsLayer* graphicsLayer, Scrollbar* scrollbar)
1048{
1049 if (!graphicsLayer || !scrollbar)
1050 return;
andersca@apple.comeda9e812011-12-21 23:02:33 +00001051
eae@chromium.org92a579f2011-11-08 02:11:06 +00001052 IntRect scrollbarRect = scrollbar->frameRect();
jamesr@google.come53ce642011-04-14 06:51:50 +00001053 graphicsLayer->setPosition(scrollbarRect.location());
andersca@apple.comeda9e812011-12-21 23:02:33 +00001054
1055 if (scrollbarRect.size() == graphicsLayer->size())
1056 return;
1057
jamesr@google.come53ce642011-04-14 06:51:50 +00001058 graphicsLayer->setSize(scrollbarRect.size());
andersca@apple.comeda9e812011-12-21 23:02:33 +00001059
simon.fraser@apple.comff549312014-04-19 05:31:39 +00001060 if (graphicsLayer->usesContentsLayer()) {
andersca@apple.comeda9e812011-12-21 23:02:33 +00001061 graphicsLayer->setContentsRect(IntRect(0, 0, scrollbarRect.width(), scrollbarRect.height()));
1062 return;
1063 }
1064
1065 graphicsLayer->setDrawsContent(true);
1066 graphicsLayer->setNeedsDisplay();
jamesr@google.come53ce642011-04-14 06:51:50 +00001067}
1068
eae@chromium.org92a579f2011-11-08 02:11:06 +00001069static void positionScrollCornerLayer(GraphicsLayer* graphicsLayer, const IntRect& cornerRect)
jamesr@google.come53ce642011-04-14 06:51:50 +00001070{
1071 if (!graphicsLayer)
1072 return;
1073 graphicsLayer->setDrawsContent(!cornerRect.isEmpty());
1074 graphicsLayer->setPosition(cornerRect.location());
1075 if (cornerRect.size() != graphicsLayer->size())
1076 graphicsLayer->setNeedsDisplay();
1077 graphicsLayer->setSize(cornerRect.size());
1078}
jamesr@google.come53ce642011-04-14 06:51:50 +00001079
1080void ScrollView::positionScrollbarLayers()
1081{
jamesr@google.come53ce642011-04-14 06:51:50 +00001082 positionScrollbarLayer(layerForHorizontalScrollbar(), horizontalScrollbar());
1083 positionScrollbarLayer(layerForVerticalScrollbar(), verticalScrollbar());
1084 positionScrollCornerLayer(layerForScrollCorner(), scrollCornerRect());
jamesr@google.come53ce642011-04-14 06:51:50 +00001085}
1086
commit-queue@webkit.org4149b932014-02-24 19:05:21 +00001087void ScrollView::repaintContentRectangle(const IntRect& rect)
hyatt@apple.com70936b52008-09-30 20:09:42 +00001088{
eae@chromium.org92a579f2011-11-08 02:11:06 +00001089 IntRect paintRect = rect;
simon.fraser@apple.com69bbc012017-08-16 02:05:28 +00001090 if (!paintsEntireContents())
aestes@apple.com0f23b262014-01-29 03:06:01 +00001091 paintRect.intersect(visibleContentRect(LegacyIOSDocumentVisibleRect));
kenneth@webkit.org9ba62222009-12-03 14:25:50 +00001092 if (paintRect.isEmpty())
hyatt@apple.com70936b52008-09-30 20:09:42 +00001093 return;
1094
hyatt@apple.com70936b52008-09-30 20:09:42 +00001095 if (platformWidget()) {
commit-queue@webkit.org277ad992011-07-16 05:15:36 +00001096 notifyPageThatContentAreaWillPaint();
commit-queue@webkit.org4149b932014-02-24 19:05:21 +00001097 platformRepaintContentRectangle(paintRect);
hyatt@apple.com70936b52008-09-30 20:09:42 +00001098 return;
1099 }
1100
commit-queue@webkit.org6121dfd2013-06-28 11:14:18 +00001101 if (HostWindow* window = hostWindow())
commit-queue@webkit.org4149b932014-02-24 19:05:21 +00001102 window->invalidateContentsAndRootView(contentsToWindow(paintRect));
hyatt@apple.com70936b52008-09-30 20:09:42 +00001103}
1104
eae@chromium.org92a579f2011-11-08 02:11:06 +00001105IntRect ScrollView::scrollCornerRect() const
andersca@apple.com7d8fe982009-08-20 00:04:48 +00001106{
eae@chromium.org92a579f2011-11-08 02:11:06 +00001107 IntRect cornerRect;
bdakin@apple.coma9d8d852011-01-19 18:49:35 +00001108
bdakin@apple.com1592fa22011-02-22 22:28:52 +00001109 if (hasOverlayScrollbars())
bdakin@apple.coma9d8d852011-01-19 18:49:35 +00001110 return cornerRect;
1111
bdakin@apple.com572c9f32014-03-20 23:19:04 +00001112 int heightTrackedByScrollbar = height() - topContentInset();
1113
andersca@apple.com98f7e262011-09-22 17:09:22 +00001114 if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) {
mmaxfield@apple.com4195a702016-04-27 01:25:26 +00001115 cornerRect.unite(IntRect(shouldPlaceBlockDirectionScrollbarOnLeft() ? 0 : m_horizontalScrollbar->width(),
bdakin@apple.com572c9f32014-03-20 23:19:04 +00001116 height() - m_horizontalScrollbar->height(),
1117 width() - m_horizontalScrollbar->width(),
1118 m_horizontalScrollbar->height()));
andersca@apple.com7d8fe982009-08-20 00:04:48 +00001119 }
1120
bdakin@apple.com572c9f32014-03-20 23:19:04 +00001121 if (m_verticalScrollbar && heightTrackedByScrollbar - m_verticalScrollbar->height() > 0) {
mmaxfield@apple.com4195a702016-04-27 01:25:26 +00001122 cornerRect.unite(IntRect(shouldPlaceBlockDirectionScrollbarOnLeft() ? 0 : width() - m_verticalScrollbar->width(),
bdakin@apple.com572c9f32014-03-20 23:19:04 +00001123 m_verticalScrollbar->height() + topContentInset(),
1124 m_verticalScrollbar->width(),
1125 heightTrackedByScrollbar - m_verticalScrollbar->height()));
andersca@apple.com7d8fe982009-08-20 00:04:48 +00001126 }
bdakin@apple.com572c9f32014-03-20 23:19:04 +00001127
andersca@apple.com7d8fe982009-08-20 00:04:48 +00001128 return cornerRect;
1129}
1130
jamesr@google.come53ce642011-04-14 06:51:50 +00001131bool ScrollView::isScrollCornerVisible() const
1132{
1133 return !scrollCornerRect().isEmpty();
1134}
1135
simon.fraser@apple.com448c42e2015-02-25 05:35:38 +00001136void ScrollView::scrollbarStyleChanged(ScrollbarStyle newStyle, bool forceUpdate)
bdakin@apple.comcbaf03e2011-06-15 00:09:01 +00001137{
simon.fraser@apple.com448c42e2015-02-25 05:35:38 +00001138 ScrollableArea::scrollbarStyleChanged(newStyle, forceUpdate);
bdakin@apple.com83c96f42011-11-28 23:06:56 +00001139 if (!forceUpdate)
1140 return;
1141
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +00001142 updateScrollbars(scrollPosition());
andersca@apple.com55b3a2a2012-01-27 02:01:47 +00001143 positionScrollbarLayers();
bdakin@apple.comcbaf03e2011-06-15 00:09:01 +00001144}
1145
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001146void ScrollView::paintScrollCorner(GraphicsContext& context, const IntRect& cornerRect)
andersca@apple.com7d8fe982009-08-20 00:04:48 +00001147{
timothy@apple.comf8942ab2018-06-23 01:21:13 +00001148 ScrollbarTheme::theme().paintScrollCorner(context, cornerRect);
andersca@apple.com7d8fe982009-08-20 00:04:48 +00001149}
1150
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001151void ScrollView::paintScrollbar(GraphicsContext& context, Scrollbar& bar, const IntRect& rect)
morrita@google.comc6c4fca2012-03-02 02:39:38 +00001152{
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001153 bar.paint(context, rect);
morrita@google.comc6c4fca2012-03-02 02:39:38 +00001154}
1155
eae@chromium.org92a579f2011-11-08 02:11:06 +00001156void ScrollView::invalidateScrollCornerRect(const IntRect& rect)
jamesr@google.come53ce642011-04-14 06:51:50 +00001157{
1158 invalidateRect(rect);
1159}
1160
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001161void ScrollView::paintScrollbars(GraphicsContext& context, const IntRect& rect)
kenneth@webkit.orgcd732702009-10-19 20:25:25 +00001162{
abucur@adobe.com46b0fd52014-01-30 10:22:36 +00001163 if (m_horizontalScrollbar && !layerForHorizontalScrollbar())
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001164 paintScrollbar(context, *m_horizontalScrollbar.get(), rect);
abucur@adobe.com46b0fd52014-01-30 10:22:36 +00001165 if (m_verticalScrollbar && !layerForVerticalScrollbar())
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001166 paintScrollbar(context, *m_verticalScrollbar.get(), rect);
kenneth@webkit.orgcd732702009-10-19 20:25:25 +00001167
jamesr@google.come53ce642011-04-14 06:51:50 +00001168 if (layerForScrollCorner())
1169 return;
abucur@adobe.com46b0fd52014-01-30 10:22:36 +00001170
kenneth@webkit.orgcd732702009-10-19 20:25:25 +00001171 paintScrollCorner(context, scrollCornerRect());
1172}
1173
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001174void ScrollView::paintPanScrollIcon(GraphicsContext& context)
kenneth@webkit.orgcd732702009-10-19 20:25:25 +00001175{
cdumez@apple.combb4fe7b2017-05-11 23:40:14 +00001176 static Image& panScrollIcon = Image::loadPlatformResource("panIcon").leakRef();
commit-queue@webkit.org1748b122012-03-10 03:53:50 +00001177 IntPoint iconGCPoint = m_panScrollIconPoint;
1178 if (parent())
1179 iconGCPoint = parent()->windowToContents(iconGCPoint);
cdumez@apple.combb4fe7b2017-05-11 23:40:14 +00001180 context.drawImage(panScrollIcon, iconGCPoint);
kenneth@webkit.orgcd732702009-10-19 20:25:25 +00001181}
1182
dino@apple.com79c37e32017-05-09 21:35:55 +00001183void ScrollView::paint(GraphicsContext& context, const IntRect& rect, SecurityOriginPaintPolicy securityOriginPaintPolicy)
hyatt@apple.com3b82dce2008-10-01 17:51:02 +00001184{
1185 if (platformWidget()) {
1186 Widget::paint(context, rect);
1187 return;
1188 }
1189
commit-queue@webkit.org55712e82018-07-17 00:17:45 +00001190 if (context.paintingDisabled() && !context.performingPaintInvalidation())
hyatt@apple.com3b82dce2008-10-01 17:51:02 +00001191 return;
1192
bdakin@apple.com9e05cff2011-03-16 02:21:59 +00001193 notifyPageThatContentAreaWillPaint();
bdakin@apple.com98933a52011-04-14 22:09:04 +00001194
eae@chromium.org92a579f2011-11-08 02:11:06 +00001195 IntRect documentDirtyRect = rect;
mikhail.pozdnyakov@intel.com5b0415c62013-02-07 16:46:49 +00001196 if (!paintsEntireContents()) {
mmaxfield@apple.com4280b492016-03-22 22:15:45 +00001197 IntRect visibleAreaWithoutScrollbars(locationOfContents(), visibleContentRect(LegacyIOSDocumentVisibleRect).size());
mikhail.pozdnyakov@intel.com5b0415c62013-02-07 16:46:49 +00001198 documentDirtyRect.intersect(visibleAreaWithoutScrollbars);
1199 }
mitz@apple.come4c40cc2011-04-22 18:13:24 +00001200
1201 if (!documentDirtyRect.isEmpty()) {
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001202 GraphicsContextStateSaver stateSaver(context);
hyatt@apple.com3b82dce2008-10-01 17:51:02 +00001203
mmaxfield@apple.com4280b492016-03-22 22:15:45 +00001204 IntPoint locationOfContents = this->locationOfContents();
1205 context.translate(locationOfContents.x(), locationOfContents.y());
1206 documentDirtyRect.moveBy(-locationOfContents);
hyatt@apple.com3b82dce2008-10-01 17:51:02 +00001207
simon.fraser@apple.com09cdc292011-04-21 15:55:57 +00001208 if (!paintsEntireContents()) {
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001209 context.translate(-scrollX(), -scrollY());
leviw@chromium.org35e01312011-06-03 02:41:09 +00001210 documentDirtyRect.moveBy(scrollPosition());
hyatt@apple.com3b82dce2008-10-01 17:51:02 +00001211
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001212 context.clip(visibleContentRect(LegacyIOSDocumentVisibleRect));
simon.fraser@apple.com09cdc292011-04-21 15:55:57 +00001213 }
1214
dino@apple.com79c37e32017-05-09 21:35:55 +00001215 paintContents(context, documentDirtyRect, securityOriginPaintPolicy);
andreas.kling@nokia.com9b08b642010-11-17 23:37:04 +00001216 }
hyatt@apple.com3b82dce2008-10-01 17:51:02 +00001217
abucur@adobe.com46b0fd52014-01-30 10:22:36 +00001218#if ENABLE(RUBBER_BANDING)
commit-queue@webkit.org0a4465d2011-09-15 04:06:49 +00001219 if (!layerForOverhangAreas())
1220 calculateAndPaintOverhangAreas(context, rect);
1221#else
1222 calculateAndPaintOverhangAreas(context, rect);
1223#endif
weinig@apple.comfe3ba1a2011-01-27 21:23:06 +00001224
hyatt@apple.com3b82dce2008-10-01 17:51:02 +00001225 // Now paint the scrollbars.
1226 if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar)) {
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001227 GraphicsContextStateSaver stateSaver(context);
eae@chromium.org92a579f2011-11-08 02:11:06 +00001228 IntRect scrollViewDirtyRect = rect;
benjamin@webkit.org25bc57c2014-03-10 21:25:24 +00001229 IntRect visibleAreaWithScrollbars(location(), unobscuredContentRectIncludingScrollbars().size());
aelias@chromium.orga49e9d22013-02-06 23:47:17 +00001230 scrollViewDirtyRect.intersect(visibleAreaWithScrollbars);
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001231 context.translate(x(), y());
leviw@chromium.org35e01312011-06-03 02:41:09 +00001232 scrollViewDirtyRect.moveBy(-location());
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001233 context.clip(IntRect(IntPoint(), visibleAreaWithScrollbars.size()));
hyatt@apple.com3b82dce2008-10-01 17:51:02 +00001234
kenneth@webkit.orgcd732702009-10-19 20:25:25 +00001235 paintScrollbars(context, scrollViewDirtyRect);
hyatt@apple.com3b82dce2008-10-01 17:51:02 +00001236 }
1237
1238 // Paint the panScroll Icon
kenneth@webkit.orgcd732702009-10-19 20:25:25 +00001239 if (m_drawPanScrollIcon)
1240 paintPanScrollIcon(context);
hyatt@apple.com3b82dce2008-10-01 17:51:02 +00001241}
1242
eae@chromium.org92a579f2011-11-08 02:11:06 +00001243void ScrollView::calculateOverhangAreasForPainting(IntRect& horizontalOverhangRect, IntRect& verticalOverhangRect)
weinig@apple.comfe3ba1a2011-01-27 21:23:06 +00001244{
simon.fraser@apple.com870034d2015-12-16 23:41:05 +00001245 IntSize scrollbarSpace = scrollbarIntrusion();
weinig@apple.com645f83d2011-02-03 03:45:32 +00001246
simon.fraser@apple.comefc492b2015-12-30 20:15:27 +00001247 // FIXME: use maximumScrollOffset().
1248 ScrollOffset scrollOffset = scrollOffsetFromPosition(scrollPosition());
1249 if (scrollOffset.y() < 0) {
weinig@apple.comfe3ba1a2011-01-27 21:23:06 +00001250 horizontalOverhangRect = frameRect();
simon.fraser@apple.comefc492b2015-12-30 20:15:27 +00001251 horizontalOverhangRect.setHeight(-scrollOffset.y());
simon.fraser@apple.com870034d2015-12-16 23:41:05 +00001252 horizontalOverhangRect.setWidth(horizontalOverhangRect.width() - scrollbarSpace.width());
simon.fraser@apple.comefc492b2015-12-30 20:15:27 +00001253 } else if (totalContentsSize().height() && scrollOffset.y() > totalContentsSize().height() - visibleHeight()) {
1254 int height = scrollOffset.y() - (totalContentsSize().height() - visibleHeight());
weinig@apple.comfe3ba1a2011-01-27 21:23:06 +00001255 horizontalOverhangRect = frameRect();
simon.fraser@apple.com870034d2015-12-16 23:41:05 +00001256 horizontalOverhangRect.setY(frameRect().maxY() - height - scrollbarSpace.height());
weinig@apple.comfe3ba1a2011-01-27 21:23:06 +00001257 horizontalOverhangRect.setHeight(height);
simon.fraser@apple.com870034d2015-12-16 23:41:05 +00001258 horizontalOverhangRect.setWidth(horizontalOverhangRect.width() - scrollbarSpace.width());
weinig@apple.comfe3ba1a2011-01-27 21:23:06 +00001259 }
1260
simon.fraser@apple.comefc492b2015-12-30 20:15:27 +00001261 if (scrollOffset.x() < 0) {
1262 verticalOverhangRect.setWidth(-scrollOffset.x());
simon.fraser@apple.com870034d2015-12-16 23:41:05 +00001263 verticalOverhangRect.setHeight(frameRect().height() - horizontalOverhangRect.height() - scrollbarSpace.height());
weinig@apple.com8c019242011-03-10 21:43:37 +00001264 verticalOverhangRect.setX(frameRect().x());
weinig@apple.comfe3ba1a2011-01-27 21:23:06 +00001265 if (horizontalOverhangRect.y() == frameRect().y())
1266 verticalOverhangRect.setY(frameRect().y() + horizontalOverhangRect.height());
1267 else
1268 verticalOverhangRect.setY(frameRect().y());
simon.fraser@apple.comefc492b2015-12-30 20:15:27 +00001269 } else if (contentsWidth() && scrollOffset.x() > contentsWidth() - visibleWidth()) {
1270 int width = scrollOffset.x() - (contentsWidth() - visibleWidth());
weinig@apple.comfe3ba1a2011-01-27 21:23:06 +00001271 verticalOverhangRect.setWidth(width);
simon.fraser@apple.com870034d2015-12-16 23:41:05 +00001272 verticalOverhangRect.setHeight(frameRect().height() - horizontalOverhangRect.height() - scrollbarSpace.height());
1273 verticalOverhangRect.setX(frameRect().maxX() - width - scrollbarSpace.width());
weinig@apple.comfe3ba1a2011-01-27 21:23:06 +00001274 if (horizontalOverhangRect.y() == frameRect().y())
1275 verticalOverhangRect.setY(frameRect().y() + horizontalOverhangRect.height());
1276 else
1277 verticalOverhangRect.setY(frameRect().y());
1278 }
1279}
1280
commit-queue@webkit.orgc1e94362012-02-22 20:18:30 +00001281void ScrollView::updateOverhangAreas()
1282{
commit-queue@webkit.org6121dfd2013-06-28 11:14:18 +00001283 HostWindow* window = hostWindow();
1284 if (!window)
commit-queue@webkit.orgc1e94362012-02-22 20:18:30 +00001285 return;
1286
1287 IntRect horizontalOverhangRect;
1288 IntRect verticalOverhangRect;
1289 calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect);
commit-queue@webkit.orgc1e94362012-02-22 20:18:30 +00001290 if (!horizontalOverhangRect.isEmpty())
commit-queue@webkit.org4149b932014-02-24 19:05:21 +00001291 window->invalidateContentsAndRootView(horizontalOverhangRect);
commit-queue@webkit.orgc1e94362012-02-22 20:18:30 +00001292 if (!verticalOverhangRect.isEmpty())
commit-queue@webkit.org4149b932014-02-24 19:05:21 +00001293 window->invalidateContentsAndRootView(verticalOverhangRect);
commit-queue@webkit.orgc1e94362012-02-22 20:18:30 +00001294}
1295
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001296void ScrollView::paintOverhangAreas(GraphicsContext& context, const IntRect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect& dirtyRect)
weinig@apple.comfe3ba1a2011-01-27 21:23:06 +00001297{
akling@apple.com53dfd8e2015-09-03 02:58:14 +00001298 ScrollbarTheme::theme().paintOverhangAreas(*this, context, horizontalOverhangRect, verticalOverhangRect, dirtyRect);
weinig@apple.comfe3ba1a2011-01-27 21:23:06 +00001299}
1300
mmaxfield@apple.coma93d7ef2015-08-29 06:15:28 +00001301void ScrollView::calculateAndPaintOverhangAreas(GraphicsContext& context, const IntRect& dirtyRect)
commit-queue@webkit.org0a4465d2011-09-15 04:06:49 +00001302{
eae@chromium.org92a579f2011-11-08 02:11:06 +00001303 IntRect horizontalOverhangRect;
1304 IntRect verticalOverhangRect;
commit-queue@webkit.org0a4465d2011-09-15 04:06:49 +00001305 calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect);
1306
1307 if (dirtyRect.intersects(horizontalOverhangRect) || dirtyRect.intersects(verticalOverhangRect))
1308 paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect, dirtyRect);
1309}
1310
bweinstein@apple.com9f624e52009-07-23 18:05:21 +00001311bool ScrollView::isPointInScrollbarCorner(const IntPoint& windowPoint)
1312{
1313 if (!scrollbarCornerPresent())
1314 return false;
1315
eae@chromium.org92a579f2011-11-08 02:11:06 +00001316 IntPoint viewPoint = convertFromContainingWindow(windowPoint);
bweinstein@apple.com9f624e52009-07-23 18:05:21 +00001317
1318 if (m_horizontalScrollbar) {
eae@chromium.org92a579f2011-11-08 02:11:06 +00001319 int horizontalScrollbarYMin = m_horizontalScrollbar->frameRect().y();
1320 int horizontalScrollbarYMax = m_horizontalScrollbar->frameRect().y() + m_horizontalScrollbar->frameRect().height();
1321 int horizontalScrollbarXMin = m_horizontalScrollbar->frameRect().x() + m_horizontalScrollbar->frameRect().width();
bweinstein@apple.com9f624e52009-07-23 18:05:21 +00001322
1323 return viewPoint.y() > horizontalScrollbarYMin && viewPoint.y() < horizontalScrollbarYMax && viewPoint.x() > horizontalScrollbarXMin;
1324 }
1325
eae@chromium.org92a579f2011-11-08 02:11:06 +00001326 int verticalScrollbarXMin = m_verticalScrollbar->frameRect().x();
1327 int verticalScrollbarXMax = m_verticalScrollbar->frameRect().x() + m_verticalScrollbar->frameRect().width();
1328 int verticalScrollbarYMin = m_verticalScrollbar->frameRect().y() + m_verticalScrollbar->frameRect().height();
bweinstein@apple.com9f624e52009-07-23 18:05:21 +00001329
1330 return viewPoint.x() > verticalScrollbarXMin && viewPoint.x() < verticalScrollbarXMax && viewPoint.y() > verticalScrollbarYMin;
1331}
1332
hyatt@apple.come2a30fd2008-10-13 21:23:21 +00001333bool ScrollView::scrollbarCornerPresent() const
1334{
andersca@apple.com98f7e262011-09-22 17:09:22 +00001335 return (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0)
1336 || (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0);
hyatt@apple.come2a30fd2008-10-13 21:23:21 +00001337}
1338
mmaxfield@apple.com221502e2016-03-30 16:50:14 +00001339IntRect ScrollView::convertFromScrollbarToContainingView(const Scrollbar& scrollbar, const IntRect& localRect) const
hyatt@apple.com6dc5ec32009-07-02 20:18:53 +00001340{
1341 // Scrollbars won't be transformed within us
eae@chromium.org92a579f2011-11-08 02:11:06 +00001342 IntRect newRect = localRect;
mmaxfield@apple.com221502e2016-03-30 16:50:14 +00001343 newRect.moveBy(scrollbar.location());
hyatt@apple.com6dc5ec32009-07-02 20:18:53 +00001344 return newRect;
1345}
1346
mmaxfield@apple.com221502e2016-03-30 16:50:14 +00001347IntRect ScrollView::convertFromContainingViewToScrollbar(const Scrollbar& scrollbar, const IntRect& parentRect) const
hyatt@apple.com6dc5ec32009-07-02 20:18:53 +00001348{
eae@chromium.org92a579f2011-11-08 02:11:06 +00001349 IntRect newRect = parentRect;
hyatt@apple.com6dc5ec32009-07-02 20:18:53 +00001350 // Scrollbars won't be transformed within us
mmaxfield@apple.com221502e2016-03-30 16:50:14 +00001351 newRect.moveBy(-scrollbar.location());
hyatt@apple.com6dc5ec32009-07-02 20:18:53 +00001352 return newRect;
1353}
1354
1355// FIXME: test these on windows
mmaxfield@apple.com221502e2016-03-30 16:50:14 +00001356IntPoint ScrollView::convertFromScrollbarToContainingView(const Scrollbar& scrollbar, const IntPoint& localPoint) const
hyatt@apple.com6dc5ec32009-07-02 20:18:53 +00001357{
1358 // Scrollbars won't be transformed within us
eae@chromium.org92a579f2011-11-08 02:11:06 +00001359 IntPoint newPoint = localPoint;
mmaxfield@apple.com221502e2016-03-30 16:50:14 +00001360 newPoint.moveBy(scrollbar.location());
hyatt@apple.com6dc5ec32009-07-02 20:18:53 +00001361 return newPoint;
1362}
1363
mmaxfield@apple.com221502e2016-03-30 16:50:14 +00001364IntPoint ScrollView::convertFromContainingViewToScrollbar(const Scrollbar& scrollbar, const IntPoint& parentPoint) const
hyatt@apple.com6dc5ec32009-07-02 20:18:53 +00001365{
eae@chromium.org92a579f2011-11-08 02:11:06 +00001366 IntPoint newPoint = parentPoint;
hyatt@apple.com6dc5ec32009-07-02 20:18:53 +00001367 // Scrollbars won't be transformed within us
mmaxfield@apple.com221502e2016-03-30 16:50:14 +00001368 newPoint.moveBy(-scrollbar.location());
hyatt@apple.com6dc5ec32009-07-02 20:18:53 +00001369 return newPoint;
1370}
1371
hyatt@apple.come72b16e2008-10-01 20:58:19 +00001372void ScrollView::setParentVisible(bool visible)
1373{
1374 if (isParentVisible() == visible)
1375 return;
1376
1377 Widget::setParentVisible(visible);
1378
hyatt@apple.com587b30b2008-12-04 20:07:41 +00001379 if (!isSelfVisible())
hyatt@apple.come72b16e2008-10-01 20:58:19 +00001380 return;
1381
darin@apple.com6c71ce22017-01-14 03:35:54 +00001382 for (auto& child : m_children)
1383 child->setParentVisible(visible);
hyatt@apple.come72b16e2008-10-01 20:58:19 +00001384}
1385
1386void ScrollView::show()
1387{
1388 if (!isSelfVisible()) {
1389 setSelfVisible(true);
1390 if (isParentVisible()) {
darin@apple.com6c71ce22017-01-14 03:35:54 +00001391 for (auto& child : m_children)
1392 child->setParentVisible(true);
hyatt@apple.come72b16e2008-10-01 20:58:19 +00001393 }
1394 }
1395
1396 Widget::show();
1397}
1398
1399void ScrollView::hide()
1400{
1401 if (isSelfVisible()) {
1402 if (isParentVisible()) {
darin@apple.com6c71ce22017-01-14 03:35:54 +00001403 for (auto& child : m_children)
1404 child->setParentVisible(false);
hyatt@apple.come72b16e2008-10-01 20:58:19 +00001405 }
1406 setSelfVisible(false);
1407 }
1408
1409 Widget::hide();
1410}
1411
hyatt@apple.com08ef1ea2008-10-01 21:11:07 +00001412bool ScrollView::isOffscreen() const
1413{
1414 if (platformWidget())
1415 return platformIsOffscreen();
1416
1417 if (!isVisible())
1418 return true;
1419
1420 // FIXME: Add a HostWindow::isOffscreen method here. Since only Mac implements this method
1421 // currently, we can add the method when the other platforms decide to implement this concept.
1422 return false;
1423}
1424
hyatt@apple.com98682b32008-10-02 20:17:08 +00001425
eae@chromium.org92a579f2011-11-08 02:11:06 +00001426void ScrollView::addPanScrollIcon(const IntPoint& iconPosition)
hyatt@apple.com98682b32008-10-02 20:17:08 +00001427{
commit-queue@webkit.org6121dfd2013-06-28 11:14:18 +00001428 HostWindow* window = hostWindow();
1429 if (!window)
alice.liu@apple.com3c49db42009-06-21 05:42:39 +00001430 return;
hyatt@apple.com98682b32008-10-02 20:17:08 +00001431 m_drawPanScrollIcon = true;
1432 m_panScrollIconPoint = IntPoint(iconPosition.x() - panIconSizeLength / 2 , iconPosition.y() - panIconSizeLength / 2) ;
commit-queue@webkit.org4149b932014-02-24 19:05:21 +00001433 window->invalidateContentsAndRootView(IntRect(m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)));
hyatt@apple.com98682b32008-10-02 20:17:08 +00001434}
1435
1436void ScrollView::removePanScrollIcon()
1437{
commit-queue@webkit.org6121dfd2013-06-28 11:14:18 +00001438 HostWindow* window = hostWindow();
1439 if (!window)
alice.liu@apple.com3c49db42009-06-21 05:42:39 +00001440 return;
hyatt@apple.com98682b32008-10-02 20:17:08 +00001441 m_drawPanScrollIcon = false;
commit-queue@webkit.org4149b932014-02-24 19:05:21 +00001442 window->invalidateContentsAndRootView(IntRect(m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)));
hyatt@apple.com98682b32008-10-02 20:17:08 +00001443}
1444
hyatt@apple.comcaa25f02011-02-01 18:44:10 +00001445void ScrollView::setScrollOrigin(const IntPoint& origin, bool updatePositionAtAll, bool updatePositionSynchronously)
xji@chromium.org506e6f62010-11-30 01:11:08 +00001446{
xji@chromium.org85d87542011-11-01 22:06:46 +00001447 if (scrollOrigin() == origin)
hyatt@apple.coma26422b2010-12-01 21:31:50 +00001448 return;
xji@chromium.org506e6f62010-11-30 01:11:08 +00001449
xji@chromium.org85d87542011-11-01 22:06:46 +00001450 ScrollableArea::setScrollOrigin(origin);
xji@chromium.org506e6f62010-11-30 01:11:08 +00001451
hyatt@apple.coma26422b2010-12-01 21:31:50 +00001452 if (platformWidget()) {
hyatt@apple.comcaa25f02011-02-01 18:44:10 +00001453 platformSetScrollOrigin(origin, updatePositionAtAll, updatePositionSynchronously);
hyatt@apple.coma26422b2010-12-01 21:31:50 +00001454 return;
1455 }
1456
1457 // Update if the scroll origin changes, since our position will be different if the content size did not change.
hyatt@apple.comcaa25f02011-02-01 18:44:10 +00001458 if (updatePositionAtAll && updatePositionSynchronously)
simon.fraser@apple.comdb0e0672015-12-30 00:29:36 +00001459 updateScrollbars(scrollPosition());
xji@chromium.org506e6f62010-11-30 01:11:08 +00001460}
1461
akling@apple.com86ab9812014-05-03 22:16:53 +00001462void ScrollView::styleDidChange()
1463{
1464 if (m_horizontalScrollbar)
1465 m_horizontalScrollbar->styleChanged();
1466
1467 if (m_verticalScrollbar)
1468 m_verticalScrollbar->styleChanged();
1469}
1470
mmaxfield@apple.com4280b492016-03-22 22:15:45 +00001471IntPoint ScrollView::locationOfContents() const
1472{
1473 IntPoint result = location();
mmaxfield@apple.com4195a702016-04-27 01:25:26 +00001474 if (shouldPlaceBlockDirectionScrollbarOnLeft() && m_verticalScrollbar)
mmaxfield@apple.com4280b492016-03-22 22:15:45 +00001475 result.move(m_verticalScrollbar->occupiedWidth(), 0);
1476 return result;
1477}
1478
mitz@apple.com1a8d7d32014-02-07 23:37:54 +00001479#if !PLATFORM(COCOA)
darin@apple.com95761192009-05-17 17:47:13 +00001480
hyatt@apple.com8de3eb72008-10-03 18:29:28 +00001481void ScrollView::platformAddChild(Widget*)
1482{
1483}
1484
1485void ScrollView::platformRemoveChild(Widget*)
1486{
1487}
darin@apple.com95761192009-05-17 17:47:13 +00001488
hyatt@apple.com8de3eb72008-10-03 18:29:28 +00001489#endif
1490
mitz@apple.com1a8d7d32014-02-07 23:37:54 +00001491#if !PLATFORM(COCOA)
darin@apple.com95761192009-05-17 17:47:13 +00001492
weinig@apple.com58518942009-12-13 04:45:31 +00001493void ScrollView::platformSetScrollbarsSuppressed(bool)
hyatt@apple.come6f04e52008-09-28 01:07:05 +00001494{
1495}
darin@apple.com95761192009-05-17 17:47:13 +00001496
commit-queue@webkit.orgd22205d2012-09-14 08:42:44 +00001497void ScrollView::platformSetScrollOrigin(const IntPoint&, bool, bool)
xji@chromium.org506e6f62010-11-30 01:11:08 +00001498{
1499}
1500
commit-queue@webkit.orgb31092d2011-07-21 01:32:17 +00001501void ScrollView::platformSetScrollbarOverlayStyle(ScrollbarOverlayStyle)
1502{
1503}
1504
hyatt@apple.com64a3be22008-09-25 20:49:17 +00001505#endif
1506
mitz@apple.com1a8d7d32014-02-07 23:37:54 +00001507#if !PLATFORM(COCOA)
darin@apple.com95761192009-05-17 17:47:13 +00001508
hyatt@apple.com01adde82008-09-26 20:49:34 +00001509void ScrollView::platformSetScrollbarModes()
1510{
1511}
1512
1513void ScrollView::platformScrollbarModes(ScrollbarMode& horizontal, ScrollbarMode& vertical) const
1514{
darin@apple.com95761192009-05-17 17:47:13 +00001515 horizontal = ScrollbarAuto;
1516 vertical = ScrollbarAuto;
hyatt@apple.com01adde82008-09-26 20:49:34 +00001517}
1518
cwzwarich@webkit.orgd96b94e2008-12-11 21:56:07 +00001519void ScrollView::platformSetCanBlitOnScroll(bool)
1520{
1521}
1522
1523bool ScrollView::platformCanBlitOnScroll() const
1524{
1525 return false;
1526}
1527
hyatt@apple.com9a6f73c2008-09-25 22:34:43 +00001528IntRect ScrollView::platformVisibleContentRect(bool) const
hyatt@apple.com79be62c2008-09-25 22:25:22 +00001529{
hyatt@apple.com282364d2008-09-25 22:52:03 +00001530 return IntRect();
hyatt@apple.com79be62c2008-09-25 22:25:22 +00001531}
hyatt@apple.comc01fb232008-09-26 04:28:25 +00001532
bdakin@apple.com044c2c12014-07-31 22:32:40 +00001533float ScrollView::platformTopContentInset() const
1534{
1535 return 0;
1536}
1537
1538void ScrollView::platformSetTopContentInset(float)
1539{
1540}
1541
simon.fraser@apple.com23bb5042013-08-08 02:00:07 +00001542IntSize ScrollView::platformVisibleContentSize(bool) const
1543{
1544 return IntSize();
1545}
1546
bdakin@apple.com35d64202014-08-01 22:39:52 +00001547IntRect ScrollView::platformVisibleContentRectIncludingObscuredArea(bool) const
1548{
1549 return IntRect();
1550}
1551
1552IntSize ScrollView::platformVisibleContentSizeIncludingObscuredArea(bool) const
1553{
1554 return IntSize();
1555}
1556
hyatt@apple.com70ef2a32008-09-26 07:15:03 +00001557void ScrollView::platformSetContentsSize()
1558{
1559}
mitz@apple.comad171f12008-09-29 20:52:19 +00001560
eae@chromium.org92a579f2011-11-08 02:11:06 +00001561IntRect ScrollView::platformContentsToScreen(const IntRect& rect) const
hyatt@apple.comfe9c1302008-10-01 20:34:07 +00001562{
1563 return rect;
1564}
1565
eae@chromium.org92a579f2011-11-08 02:11:06 +00001566IntPoint ScrollView::platformScreenToContents(const IntPoint& point) const
hyatt@apple.comfe9c1302008-10-01 20:34:07 +00001567{
1568 return point;
1569}
1570
mitz@apple.comad171f12008-09-29 20:52:19 +00001571void ScrollView::platformSetScrollPosition(const IntPoint&)
1572{
1573}
mitz@apple.com2449a052008-09-29 20:57:33 +00001574
mitz@apple.com9a3e3c82008-09-29 21:04:54 +00001575bool ScrollView::platformScroll(ScrollDirection, ScrollGranularity)
mitz@apple.com2449a052008-09-29 20:57:33 +00001576{
mitz@apple.com9a3e3c82008-09-29 21:04:54 +00001577 return true;
mitz@apple.com2449a052008-09-29 20:57:33 +00001578}
hyatt@apple.com70936b52008-09-30 20:09:42 +00001579
commit-queue@webkit.org4149b932014-02-24 19:05:21 +00001580void ScrollView::platformRepaintContentRectangle(const IntRect&)
hyatt@apple.com70936b52008-09-30 20:09:42 +00001581{
1582}
hyatt@apple.com08ef1ea2008-10-01 21:11:07 +00001583
1584bool ScrollView::platformIsOffscreen() const
1585{
1586 return false;
1587}
darin@apple.com95761192009-05-17 17:47:13 +00001588
hyatt@apple.com79be62c2008-09-25 22:25:22 +00001589#endif
1590
hyatt@apple.comf1ffabf2008-10-02 18:23:32 +00001591}