summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/3rdparty/webkit/VERSION2
-rw-r--r--src/3rdparty/webkit/WebCore/page/FrameView.cpp30
-rw-r--r--src/3rdparty/webkit/WebCore/page/FrameView.h6
-rw-r--r--src/3rdparty/webkit/WebCore/platform/ScrollView.cpp7
-rw-r--r--src/3rdparty/webkit/WebCore/platform/ScrollView.h5
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderLayer.cpp24
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderLayer.h2
-rw-r--r--src/3rdparty/webkit/WebKit/qt/tests/qwebview/tst_qwebview.cpp26
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