diff options
-rw-r--r-- | src/3rdparty/webkit/VERSION | 2 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebCore/page/FrameView.cpp | 30 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebCore/page/FrameView.h | 6 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebCore/platform/ScrollView.cpp | 7 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebCore/platform/ScrollView.h | 5 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp | 24 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebCore/rendering/RenderLayer.h | 2 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/tests/qwebview/tst_qwebview.cpp | 26 |
8 files changed, 84 insertions, 18 deletions
diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 1b8e789..354e21d 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - be1a105be93d7fcbe36d93d0827dc6e98b55de0c + fc13f9b396e1448cd71266f56ba7a93de5cf6ed9 diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/WebCore/page/FrameView.cpp index cc7d171..1ea166f 100644 --- a/src/3rdparty/webkit/WebCore/page/FrameView.cpp +++ b/src/3rdparty/webkit/WebCore/page/FrameView.cpp @@ -780,7 +780,7 @@ void FrameView::removeFixedObject() setCanBlitOnScroll(!useSlowRepaints()); } -void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) +bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) { const size_t fixedObjectThreshold = 5; @@ -790,7 +790,7 @@ void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect if (!positionedObjects || positionedObjects->isEmpty()) { hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); - return; + return true; } // Get the rects of the fixed objects visible in the rectToScroll @@ -801,9 +801,9 @@ void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect RenderBox* renderBox = *it; if (renderBox->style()->position() != FixedPosition) continue; - IntRect topLevelRect; - IntRect updateRect = renderBox->paintingRootRect(topLevelRect); - updateRect.move(-scrollX(), -scrollY()); + IntRect updateRect = renderBox->layer()->repaintRectIncludingDescendants(); + updateRect = contentsToWindow(updateRect); + updateRect.intersect(rectToScroll); if (!updateRect.isEmpty()) { if (subRectToUpdate.size() >= fixedObjectThreshold) { @@ -819,7 +819,7 @@ void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect // 1) scroll hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); - // 2) update the area of fixed objets that has been invalidated + // 2) update the area of fixed objects that has been invalidated size_t fixObjectsCount = subRectToUpdate.size(); for (size_t i = 0; i < fixObjectsCount; ++i) { IntRect updateRect = subRectToUpdate[i]; @@ -829,12 +829,11 @@ void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect updateRect.intersect(rectToScroll); hostWindow()->repaint(updateRect, true, false, true); } - } else { - // the number of fixed objects exceed the threshold, so we repaint everything. - IntRect updateRect = clipRect; - updateRect.intersect(rectToScroll); - hostWindow()->repaint(updateRect, true, false, true); + return true; } + + // the number of fixed objects exceed the threshold, we cannot use the fast path + return false; } void FrameView::setIsOverlapped(bool isOverlapped) @@ -964,6 +963,15 @@ void FrameView::scrollPositionChanged() { frame()->eventHandler()->sendScrollEvent(); + // For fixed position elements, update widget positions and compositing layers after scrolling, + // but only if we're not inside of layout. + if (!m_nestedLayoutCount && hasFixedObjects()) { + if (RenderView* root = m_frame->contentRenderer()) { + root->updateWidgetPositions(); + root->layer()->updateRepaintRectsAfterScroll(); + } + } + #if USE(ACCELERATED_COMPOSITING) // We need to update layer positions after scrolling to account for position:fixed layers. Document* document = m_frame->document(); diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.h b/src/3rdparty/webkit/WebCore/page/FrameView.h index ed1e6c6..6350a2a 100644 --- a/src/3rdparty/webkit/WebCore/page/FrameView.h +++ b/src/3rdparty/webkit/WebCore/page/FrameView.h @@ -131,7 +131,7 @@ public: virtual void scrollRectIntoViewRecursively(const IntRect&); virtual void setScrollPosition(const IntPoint&); - void scrollPositionChanged(); + virtual void scrollPositionChanged(); String mediaType() const; void setMediaType(const String&); @@ -200,7 +200,7 @@ public: void invalidateScrollCorner(); protected: - virtual void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); + virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); private: FrameView(Frame*); @@ -214,6 +214,8 @@ private: bool useSlowRepaints() const; bool useSlowRepaintsIfNotOverlapped() const; + bool hasFixedObjects() const { return m_fixedObjectCount > 0; } + void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode); void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow); diff --git a/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp b/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp index 9e15c43..518c454 100644 --- a/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp +++ b/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp @@ -259,6 +259,7 @@ void ScrollView::valueChanged(Scrollbar* scrollbar) if (scrollbarsSuppressed()) return; + scrollPositionChanged(); scrollContents(scrollDelta); } @@ -509,7 +510,8 @@ void ScrollView::scrollContents(const IntSize& scrollDelta) if (canBlitOnScroll()) { // The main frame can just blit the WebView window // FIXME: Find a way to blit subframes without blitting overlapping content - scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect); + if (!scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect)) + hostWindow()->repaint(updateRect, true, false, true); } else { // We need to go ahead and repaint the entire backing store. Do it now before moving the // windowed plugins. @@ -524,9 +526,10 @@ void ScrollView::scrollContents(const IntSize& scrollDelta) hostWindow()->paint(); } -void ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) +bool ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) { hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); + return true; } IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const diff --git a/src/3rdparty/webkit/WebCore/platform/ScrollView.h b/src/3rdparty/webkit/WebCore/platform/ScrollView.h index 7060d07..0e40334 100644 --- a/src/3rdparty/webkit/WebCore/platform/ScrollView.h +++ b/src/3rdparty/webkit/WebCore/platform/ScrollView.h @@ -246,7 +246,7 @@ protected: virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect); // Scroll the content by blitting the pixels - virtual void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); + virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); private: RefPtr<Scrollbar> m_horizontalScrollbar; @@ -281,6 +281,9 @@ private: // Called to update the scrollbars to accurately reflect the state of the view. void updateScrollbars(const IntSize& desiredOffset); + // Called when the scroll position within this view changes. FrameView overrides this to generate repaint invalidations. + virtual void scrollPositionChanged() {} + void platformInit(); void platformDestroy(); void platformAddChild(Widget*); diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp index fea61c9..6c73114 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp @@ -331,6 +331,14 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags) m_marquee->updateMarqueePosition(); } +IntRect RenderLayer::repaintRectIncludingDescendants() const +{ + IntRect repaintRect = m_repaintRect; + for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) + repaintRect.unite(child->repaintRectIncludingDescendants()); + return repaintRect; +} + void RenderLayer::computeRepaintRects() { RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint(); @@ -338,6 +346,22 @@ void RenderLayer::computeRepaintRects() m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer); } +void RenderLayer::updateRepaintRectsAfterScroll(bool fixed) +{ + if (fixed || renderer()->style()->position() == FixedPosition) { + computeRepaintRects(); + fixed = true; + } else if (renderer()->hasTransform()) { + // Transforms act as fixed position containers, so nothing inside a + // transformed element can be fixed relative to the viewport if the + // transformed element is not fixed itself or child of a fixed element. + return; + } + + for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) + child->updateRepaintRectsAfterScroll(fixed); +} + void RenderLayer::updateTransform() { // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set, diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h index a274638..ac51d9d 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderLayer.h @@ -384,7 +384,9 @@ public: // Return a cached repaint rect, computed relative to the layer renderer's containerForRepaint. IntRect repaintRect() const { return m_repaintRect; } + IntRect repaintRectIncludingDescendants() const; void computeRepaintRects(); + void updateRepaintRectsAfterScroll(bool fixed = false); void setNeedsFullRepaint(bool f = true) { m_needsFullRepaint = f; } int staticX() const { return m_staticX; } diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebview/tst_qwebview.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebview/tst_qwebview.cpp index d466ab5..5e8e8a9 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebview/tst_qwebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebview/tst_qwebview.cpp @@ -29,7 +29,31 @@ #include <qdiriterator.h> #include <qwebkitversion.h> #include <qwebframe.h> - +#include <qtimer.h> +#include <qsignalspy.h> + +/** + * Starts an event loop that runs until the given signal is received. + Optionally the event loop + * can return earlier on a timeout. + * + * \return \p true if the requested signal was received + * \p false on timeout + */ +static bool waitForSignal(QObject* obj, const char* signal, int timeout = 0) +{ + QEventLoop loop; + QObject::connect(obj, signal, &loop, SLOT(quit())); + QTimer timer; + QSignalSpy timeoutSpy(&timer, SIGNAL(timeout())); + if (timeout > 0) { + QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + timer.setSingleShot(true); + timer.start(timeout); + } + loop.exec(); + return timeoutSpy.isEmpty(); +} class tst_QWebView : public QObject { Q_OBJECT |