2 Copyright (C) 1997 Martin Jones (mjones@kde.org)
3 (C) 1998 Waldo Bastian (bastian@kde.org)
4 (C) 1998, 1999 Torben Weis (weis@kde.org)
5 (C) 1999 Lars Knoll (knoll@kde.org)
6 (C) 1999 Antti Koivisto (koivisto@kde.org)
7 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
19 You should have received a copy of the GNU Library General Public License
20 along with this library; see the file COPYING.LIB. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA.
28 #include "AdjustViewSizeOrNot.h"
30 #include "PaintPhase.h"
31 #include "ScrollView.h"
32 #include <wtf/Forward.h>
33 #include <wtf/OwnPtr.h>
34 #include <wtf/text/WTFString.h>
42 class FrameActionScheduler;
47 class RenderEmbeddedObject;
50 class RenderScrollbarPart;
52 typedef unsigned long long DOMTimeStamp;
54 class FrameView : public ScrollView {
56 friend class RenderView;
58 static PassRefPtr<FrameView> create(Frame*);
59 static PassRefPtr<FrameView> create(Frame*, const IntSize& initialSize);
63 virtual HostWindow* hostWindow() const;
65 virtual void invalidateRect(const LayoutRect&);
66 virtual void setFrameRect(const LayoutRect&);
67 #if ENABLE(REQUEST_ANIMATION_FRAME)
68 void scheduleAnimation();
71 Frame* frame() const { return m_frame.get(); }
74 LayoutUnit marginWidth() const { return m_margins.width(); } // -1 means default
75 LayoutUnit marginHeight() const { return m_margins.height(); } // -1 means default
76 void setMarginWidth(LayoutUnit);
77 void setMarginHeight(LayoutUnit);
79 virtual void setCanHaveScrollbars(bool);
80 void updateCanHaveScrollbars();
82 virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
84 virtual bool avoidScrollbarCreation() const;
85 virtual void didAddHorizontalScrollbar(Scrollbar*);
86 virtual void willRemoveHorizontalScrollbar(Scrollbar*);
88 virtual void setContentsSize(const LayoutSize&);
90 void layout(bool allowSubtree = true);
91 bool didFirstLayout() const;
92 void layoutTimerFired(Timer<FrameView>*);
93 void scheduleRelayout();
94 void scheduleRelayoutOfSubtree(RenderObject*);
95 void unscheduleRelayout();
96 bool layoutPending() const;
97 bool isInLayout() const { return m_inLayout; }
99 RenderObject* layoutRoot(bool onlyDuringLayout = false) const;
100 int layoutCount() const { return m_layoutCount; }
102 bool needsLayout() const;
103 void setNeedsLayout();
105 bool needsFullRepaint() const { return m_doFullRepaint; }
107 #if ENABLE(REQUEST_ANIMATION_FRAME)
108 void serviceScriptedAnimations(DOMTimeStamp);
111 #if USE(ACCELERATED_COMPOSITING)
112 void updateCompositingLayers();
113 bool syncCompositingStateForThisFrame(Frame* rootFrameForSync);
115 void clearBackingStores();
116 void restoreBackingStores();
118 // Called when changes to the GraphicsLayer hierarchy have to be synchronized with
119 // content rendered via the normal painting path.
120 void setNeedsOneShotDrawingSynchronization();
123 bool hasCompositedContent() const;
124 bool hasCompositedContentIncludingDescendants() const;
125 bool hasCompositingAncestor() const;
126 void enterCompositingMode();
127 bool isEnclosedInCompositingLayer() const;
129 // Only used with accelerated compositing, but outside the #ifdef to make linkage easier.
130 // Returns true if the sync was completed.
131 bool syncCompositingStateIncludingSubframes();
133 // Returns true when a paint with the PaintBehaviorFlattenCompositingLayers flag set gives
134 // a faithful representation of the content.
135 bool isSoftwareRenderable() const;
137 void didMoveOnscreen();
138 void willMoveOffscreen();
140 void resetScrollbars();
141 void resetScrollbarsAndClearContentsSize();
142 void detachCustomScrollbars();
143 virtual void recalculateScrollbarOverlayStyle();
147 bool isTransparent() const;
148 void setTransparent(bool isTransparent);
150 Color baseBackgroundColor() const;
151 void setBaseBackgroundColor(const Color&);
152 void updateBackgroundRecursively(const Color&, bool);
154 bool shouldUpdateWhileOffscreen() const;
155 void setShouldUpdateWhileOffscreen(bool);
156 bool shouldUpdate(bool = false) const;
158 void adjustViewSize();
160 virtual LayoutRect windowClipRect(bool clipToContents = true) const;
161 LayoutRect windowClipRectForLayer(const RenderLayer*, bool clipToLayerContents) const;
163 virtual LayoutRect windowResizerRect() const;
165 void setScrollPosition(const LayoutPoint&);
166 void scrollPositionChangedViaPlatformWidget();
167 virtual void repaintFixedElementsAfterScrolling();
168 virtual bool shouldRubberBandInDirection(ScrollDirection) const;
170 String mediaType() const;
171 void setMediaType(const String&);
172 void adjustMediaTypeForPrinting(bool printing);
174 void setCannotBlitToWindow();
175 void setIsOverlapped(bool);
176 bool isOverlapped() const { return m_isOverlapped; }
177 bool isOverlappedIncludingAncestors() const;
178 void setContentIsOpaque(bool);
180 void addSlowRepaintObject();
181 void removeSlowRepaintObject();
183 void addFixedObject();
184 void removeFixedObject();
186 // Functions for querying the current scrolled position, negating the effects of overhang
187 // and adjusting for page scale.
188 LayoutUnit scrollXForFixedPosition() const;
189 LayoutUnit scrollYForFixedPosition() const;
190 LayoutSize scrollOffsetForFixedPosition() const;
192 void beginDeferredRepaints();
193 void endDeferredRepaints();
194 void checkStopDelayingDeferredRepaints();
195 void resetDeferredRepaintDelay();
197 #if ENABLE(DASHBOARD_SUPPORT)
198 void updateDashboardRegions();
200 void updateControlTints();
202 void restoreScrollbar();
204 void scheduleEvent(PassRefPtr<Event>, PassRefPtr<Node>);
205 void pauseScheduledEvents();
206 void resumeScheduledEvents();
207 void postLayoutTimerFired(Timer<FrameView>*);
209 bool wasScrolledByUser() const;
210 void setWasScrolledByUser(bool);
212 void addWidgetToUpdate(RenderEmbeddedObject*);
213 void removeWidgetToUpdate(RenderEmbeddedObject*);
215 virtual void paintContents(GraphicsContext*, const LayoutRect& damageRect);
216 void setPaintBehavior(PaintBehavior);
217 PaintBehavior paintBehavior() const;
218 bool isPainting() const;
219 bool hasEverPainted() const { return m_lastPaintTime; }
220 void setNodeToDraw(Node*);
222 virtual void paintOverhangAreas(GraphicsContext*, const LayoutRect& horizontalOverhangArea, const LayoutRect& verticalOverhangArea, const LayoutRect& dirtyRect);
223 virtual void paintScrollCorner(GraphicsContext*, const LayoutRect& cornerRect);
225 Color documentBackgroundColor() const;
227 static double currentPaintTimeStamp() { return sCurrentPaintTimeStamp; } // returns 0 if not painting
229 void updateLayoutAndStyleIfNeededRecursive();
230 void flushDeferredRepaints();
232 void incrementVisuallyNonEmptyCharacterCount(unsigned);
233 void incrementVisuallyNonEmptyPixelCount(const IntSize&);
234 void setIsVisuallyNonEmpty() { m_isVisuallyNonEmpty = true; }
235 bool isVisuallyNonEmpty() const { return m_isVisuallyNonEmpty; }
237 void forceLayout(bool allowSubtree = false);
238 void forceLayoutForPagination(const FloatSize& pageSize, float maximumShrinkFactor, AdjustViewSizeOrNot);
240 // FIXME: This method is retained because of embedded WebViews in AppKit. When a WebView is embedded inside
241 // some enclosing view with auto-pagination, no call happens to resize the view. The new pagination model
242 // needs the view to resize as a result of the breaks, but that means that the enclosing view has to potentially
243 // resize around that view. Auto-pagination uses the bounds of the actual view that's being printed to determine
244 // the edges of the print operation, so the resize is necessary if the enclosing view's bounds depend on the
245 // web document's bounds.
247 // This is already a problem if the view needs to be a different size because of printer fonts or because of print stylesheets.
248 // Mail/Dictionary work around this problem by using the _layoutForPrinting SPI
249 // to at least get print stylesheets and printer fonts into play, but since WebKit doesn't know about the page offset or
250 // page size, it can't actually paginate correctly during _layoutForPrinting.
252 // We can eventually move Mail to a newer SPI that would let them opt in to the layout-time pagination model,
253 // but that doesn't solve the general problem of how other AppKit views could opt in to the better model.
255 // NO OTHER PLATFORM BESIDES MAC SHOULD USE THIS METHOD.
256 void adjustPageHeightDeprecated(float* newBottom, float oldTop, float oldBottom, float bottomLimit);
258 bool scrollToFragment(const KURL&);
259 bool scrollToAnchor(const String&);
260 void maintainScrollPositionAtAnchor(Node*);
262 // Methods to convert points and rects between the coordinate space of the renderer, and this view.
263 virtual LayoutRect convertFromRenderer(const RenderObject*, const LayoutRect&) const;
264 virtual LayoutRect convertToRenderer(const RenderObject*, const LayoutRect&) const;
265 virtual LayoutPoint convertFromRenderer(const RenderObject*, const LayoutPoint&) const;
266 virtual LayoutPoint convertToRenderer(const RenderObject*, const LayoutPoint&) const;
268 bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
270 void calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode);
273 static void setRepaintThrottlingDeferredRepaintDelay(double p);
274 // Negative value would mean that first few repaints happen without a delay
275 static void setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p);
276 // The delay grows on each repaint to this maximum value
277 static void setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p);
278 // On each repaint the delay increses by this amount
279 static void setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p);
281 virtual LayoutPoint currentMousePosition() const;
283 // FIXME: Remove this method once plugin loading is decoupled from layout.
284 void flushAnyPendingPostLayoutTasks();
286 virtual bool shouldSuspendScrollAnimations() const;
288 void setAnimatorsAreActive();
290 RenderBox* embeddedContentBox() const;
292 void clearOwningRendererForCustomScrollbars(RenderBox*);
295 virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const LayoutRect& rectToScroll, const LayoutRect& clipRect);
296 virtual void scrollContentsSlowPath(const LayoutRect& updateRect);
298 virtual bool isVerticalDocument() const;
299 virtual bool isFlippedDocument() const;
307 virtual bool isFrameView() const;
309 friend class RenderWidget;
310 bool useSlowRepaints(bool considerOverlap = true) const;
311 bool useSlowRepaintsIfNotOverlapped() const;
312 void updateCanBlitOnScrollRecursively();
313 bool contentsInCompositedLayer() const;
315 bool hasFixedObjects() const { return m_fixedObjectCount > 0; }
317 void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode);
319 void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow);
321 void forceLayoutParentViewIfNeeded();
322 void performPostLayoutTasks();
324 virtual void repaintContentRectangle(const LayoutRect&, bool immediate);
325 virtual void contentsResized();
326 virtual void visibleContentsResized();
328 // Override ScrollView methods to do point conversion via renderers, in order to
329 // take transforms into account.
330 virtual LayoutRect convertToContainingView(const LayoutRect&) const;
331 virtual LayoutRect convertFromContainingView(const LayoutRect&) const;
332 virtual LayoutPoint convertToContainingView(const LayoutPoint&) const;
333 virtual LayoutPoint convertFromContainingView(const LayoutPoint&) const;
335 // ScrollableArea interface
336 virtual void invalidateScrollbarRect(Scrollbar*, const LayoutRect&);
337 virtual bool isActive() const;
338 virtual void getTickmarks(Vector<LayoutRect>&) const;
339 virtual void scrollTo(const LayoutSize&);
340 virtual void didStartRubberBand(const IntSize&) const;
341 virtual void didCompleteRubberBand(const IntSize&) const;
342 virtual void didStartAnimatedScroll() const;
343 virtual void didCompleteAnimatedScroll() const;
344 virtual void setVisibleScrollerThumbRect(const LayoutRect&);
345 virtual bool isOnActivePage() const;
346 virtual ScrollableArea* enclosingScrollableArea() const;
348 #if USE(ACCELERATED_COMPOSITING)
349 virtual GraphicsLayer* layerForHorizontalScrollbar() const;
350 virtual GraphicsLayer* layerForVerticalScrollbar() const;
351 virtual GraphicsLayer* layerForScrollCorner() const;
352 #if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
353 virtual GraphicsLayer* layerForOverhangAreas() const;
357 virtual void notifyPageThatContentAreaWillPaint() const;
358 virtual void disconnectFromPage() { m_page = 0; }
360 virtual bool scrollAnimatorEnabled() const;
362 void deferredRepaintTimerFired(Timer<FrameView>*);
363 void doDeferredRepaints();
364 void updateDeferredRepaintDelay();
365 double adjustedDeferredRepaintDelay() const;
367 bool updateWidgets();
368 void updateWidget(RenderEmbeddedObject*);
369 void scrollToAnchor();
370 void scrollPositionChanged();
372 bool hasCustomScrollbars() const;
374 virtual void updateScrollCorner();
376 FrameView* parentFrameView() const;
378 virtual AXObjectCache* axObjectCache() const;
379 void notifyWidgetsInAllFrames(WidgetNotification);
381 static double sCurrentPaintTimeStamp; // used for detecting decoded resource thrash in the cache
384 LayoutSize m_margins;
386 typedef HashSet<RenderEmbeddedObject*> RenderEmbeddedObjectSet;
387 OwnPtr<RenderEmbeddedObjectSet> m_widgetUpdateSet;
388 RefPtr<Frame> m_frame;
390 bool m_doFullRepaint;
392 bool m_canHaveScrollbars;
393 bool m_cannotBlitToWindow;
395 bool m_contentIsOpaque;
396 unsigned m_slowRepaintObjectCount;
397 unsigned m_fixedObjectCount;
402 Timer<FrameView> m_layoutTimer;
403 bool m_delayedLayout;
404 RenderObject* m_layoutRoot;
406 bool m_layoutSchedulingEnabled;
409 bool m_inLayoutParentView;
411 bool m_hasPendingPostLayoutTasks;
412 bool m_inSynchronousPostLayout;
414 unsigned m_nestedLayoutCount;
415 Timer<FrameView> m_postLayoutTasksTimer;
416 bool m_firstLayoutCallbackPending;
419 bool m_isTransparent;
420 Color m_baseBackgroundColor;
421 LayoutSize m_lastLayoutSize;
422 float m_lastZoomFactor;
425 String m_mediaTypeWhenNotPrinting;
427 OwnPtr<FrameActionScheduler> m_actionScheduler;
429 bool m_overflowStatusDirty;
430 bool m_horizontalOverflow;
431 bool m_verticalOverflow;
432 RenderObject* m_viewportRenderer;
434 bool m_wasScrolledByUser;
435 bool m_inProgrammaticScroll;
437 unsigned m_deferringRepaints;
438 unsigned m_repaintCount;
439 Vector<LayoutRect> m_repaintRects;
440 Timer<FrameView> m_deferredRepaintTimer;
441 double m_deferredRepaintDelay;
442 double m_lastPaintTime;
444 bool m_shouldUpdateWhileOffscreen;
446 unsigned m_deferSetNeedsLayouts;
447 bool m_setNeedsLayoutWasDeferred;
449 RefPtr<Node> m_nodeToDraw;
450 PaintBehavior m_paintBehavior;
453 unsigned m_visuallyNonEmptyCharacterCount;
454 unsigned m_visuallyNonEmptyPixelCount;
455 bool m_isVisuallyNonEmpty;
456 bool m_firstVisuallyNonEmptyLayoutCallbackPending;
458 RefPtr<Node> m_maintainScrollPositionAnchor;
460 // Renderer to hold our custom scroll corner.
461 RenderScrollbarPart* m_scrollCorner;
465 static double s_deferredRepaintDelay;
466 static double s_initialDeferredRepaintDelayDuringLoading;
467 static double s_maxDeferredRepaintDelayDuringLoading;
468 static double s_deferredRepaintDelayIncrementDuringLoading;
471 inline void FrameView::incrementVisuallyNonEmptyCharacterCount(unsigned count)
473 if (m_isVisuallyNonEmpty)
475 m_visuallyNonEmptyCharacterCount += count;
476 // Use a threshold value to prevent very small amounts of visible content from triggering didFirstVisuallyNonEmptyLayout.
477 // The first few hundred characters rarely contain the interesting content of the page.
478 static const unsigned visualCharacterThreshold = 200;
479 if (m_visuallyNonEmptyCharacterCount > visualCharacterThreshold)
480 setIsVisuallyNonEmpty();
483 inline void FrameView::incrementVisuallyNonEmptyPixelCount(const IntSize& size)
485 if (m_isVisuallyNonEmpty)
487 m_visuallyNonEmptyPixelCount += size.width() * size.height();
488 // Use a threshold value to prevent very small amounts of visible content from triggering didFirstVisuallyNonEmptyLayout
489 static const unsigned visualPixelThreshold = 32 * 32;
490 if (m_visuallyNonEmptyPixelCount > visualPixelThreshold)
491 setIsVisuallyNonEmpty();
494 } // namespace WebCore
496 #endif // FrameView_h