[Qt][WK2] Fixed elements position is wrong after zooming.
authoryael.aharon@nokia.com <yael.aharon@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Apr 2012 14:05:42 +0000 (14:05 +0000)
committeryael.aharon@nokia.com <yael.aharon@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Apr 2012 14:05:42 +0000 (14:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=83981

Reviewed by Kenneth Rohde Christiansen.

.:

* ManualTests/remove-add-fixed-position.html: Added.

Source/WebCore:

When setFixedVisibleContentRect is called we mark all fixed elements in the frame for layout.
In order to find these elements, RenderView maintains a list of fixed elements.
They are added and removed at the same time that they are added and removed from their parent RenderBlock.
The idea is taken from the iOS5.1 branch, at opensource.apple.com.
Added a manual test that allows removing and adding fixed elements at will.

* page/FrameView.cpp:
(WebCore::FrameView::setFixedVisibleContentRect):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::insertPositionedObject):
(WebCore::RenderBlock::removePositionedObject):
* rendering/RenderView.cpp:
(WebCore::RenderView::setFixedPositionedObjectsNeedLayout):
(WebCore):
(WebCore::RenderView::insertFixedPositionedObject):
(WebCore::RenderView::removeFixedPositionedObject):
* rendering/RenderView.h:
(RenderView):

Source/WebKit2:

Turn on the flag setFixedElementsLayoutRelativeToFrame. This causes fixed elements position to be calculated based on
visibleWidth and visibleHeight. When zoom level grows, the visibleWidth and visibleHeight become smaller.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::setResizesToContentsUsingLayoutSize):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@114249 268f45cc-cd09-0410-ab3c-d52691b4dbfc

ChangeLog
ManualTests/remove-add-fixed-position.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/FrameView.cpp
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderView.cpp
Source/WebCore/rendering/RenderView.h
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebPage/WebPage.cpp

index 1d02f3c..4db92b7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-04-16  Yael Aharon  <yael.aharon@nokia.com>
+
+        [Qt][WK2] Fixed elements position is wrong after zooming.
+        https://bugs.webkit.org/show_bug.cgi?id=83981
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        * ManualTests/remove-add-fixed-position.html: Added.
+
 2012-04-13  Jason Liu  <jason.liu@torchmobile.com.cn>
 
         [BlackBerry] Sign in cookie for ESPN.com does not retain login account (for fantasy sports).
diff --git a/ManualTests/remove-add-fixed-position.html b/ManualTests/remove-add-fixed-position.html
new file mode 100644 (file)
index 0000000..983f13d
--- /dev/null
@@ -0,0 +1,93 @@
+<html><head>
+<meta name="viewport" content="width=device-width">
+<style>
+.d1 {position:fixed; top:5; right:5; z-index:2; overflow:hidden;}
+.o {background:green; height:40px; width:200px;}
+.t { width:2000px; height:198px; background-color: lightgray; border: 1px solid blue;}
+body { margin: 0px; }
+</style>
+<script>
+
+var fixed;
+
+function remove_child()
+{
+  fixed = document.getElementById("d1");
+  fixed.parentElement.removeChild(fixed);
+}
+
+function add_child()
+{
+  document.body.appendChild(fixed);
+}
+
+</script>
+</head>
+<body>
+<div class="d1" id="d1"><div class="o">This is a test</div></div>
+<div class="t">
+000
+</div>
+<div class="t">
+200<br>
+<button onclick="remove_child();">remove fixed</button>
+</div>
+<div class="t">
+400<br>
+<button onclick="add_child();">add fixed</button>
+</div>
+<div class="t">
+600<br>
+</div>
+<div class="t">
+800
+</div>
+<div class="t">
+1000
+</div>
+<div class="t">
+1200
+</div>
+<div class="t">
+1400
+</div>
+<div class="t">
+1600
+</div>
+<div class="t">
+1800
+</div>
+<div class="t">
+2000
+</div>
+<div class="t">
+2200
+</div>
+<div class="t">
+2400
+</div>
+<div class="t">
+2600
+</div>
+<div class="t">
+2800
+</div>
+<div class="t">
+3000
+</div>
+<div class="t">
+3200
+</div>
+<div class="t">
+3400
+</div>
+<div class="t">
+3600
+</div>
+<div class="t">
+3800
+</div>
+<div class="t">
+4000
+</div>
+</body></html>
index 3b32c0c..7d97b98 100644 (file)
@@ -1,3 +1,29 @@
+2012-04-16  Yael Aharon  <yael.aharon@nokia.com>
+
+        [Qt][WK2] Fixed elements position is wrong after zooming.
+        https://bugs.webkit.org/show_bug.cgi?id=83981
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        When setFixedVisibleContentRect is called we mark all fixed elements in the frame for layout.
+        In order to find these elements, RenderView maintains a list of fixed elements.
+        They are added and removed at the same time that they are added and removed from their parent RenderBlock.
+        The idea is taken from the iOS5.1 branch, at opensource.apple.com.
+        Added a manual test that allows removing and adding fixed elements at will.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::setFixedVisibleContentRect):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::insertPositionedObject):
+        (WebCore::RenderBlock::removePositionedObject):
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::setFixedPositionedObjectsNeedLayout):
+        (WebCore):
+        (WebCore::RenderView::insertFixedPositionedObject):
+        (WebCore::RenderView::removeFixedPositionedObject):
+        * rendering/RenderView.h:
+        (RenderView):
+
 2012-04-13  Pavel Feldman  <pfeldman@chromium.org>
 
         Web Inspector: extract ContentProvider into its own file, make NetworkRequest, Resoruce and others implement it.
index 149c536..844de28 100644 (file)
@@ -1705,6 +1705,13 @@ void FrameView::delegatesScrollingDidChange()
 
 void FrameView::setFixedVisibleContentRect(const IntRect& visibleContentRect)
 {
+    if (visibleContentRect.size() != this->fixedVisibleContentRect().size()) {
+        // When the viewport size changes or the content is scaled, we need to
+        // reposition the fixed positioned elements.
+        if (RenderView* root = rootRenderer(this))
+            root->setFixedPositionedObjectsNeedLayout();
+    }
+
     IntSize offset = scrollOffset();
     ScrollView::setFixedVisibleContentRect(visibleContentRect);
     if (offset != scrollOffset()) {
index b30ba3d..ef9ad33 100755 (executable)
@@ -3418,12 +3418,18 @@ void RenderBlock::insertPositionedObject(RenderBox* o)
         m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
 
     m_positionedObjects->add(o);
+
+    if (o->style()->position() == FixedPosition && view())
+        view()->insertFixedPositionedObject(o);
 }
 
 void RenderBlock::removePositionedObject(RenderBox* o)
 {
     if (m_positionedObjects)
         m_positionedObjects->remove(o);
+
+    if (view())
+        view()->removeFixedPositionedObject(o);
 }
 
 void RenderBlock::removePositionedObjects(RenderBlock* o)
index 7cf2ead..8f76afb 100644 (file)
@@ -920,4 +920,35 @@ RenderBlock::IntervalArena* RenderView::intervalArena()
     return m_intervalArena.get();
 }
 
+void RenderView::setFixedPositionedObjectsNeedLayout()
+{
+    ASSERT(m_frameView);
+
+    PositionedObjectsListHashSet* positionedObjects = this->positionedObjects();
+    if (!positionedObjects)
+        return;
+
+    PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
+    for (PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
+        RenderBox* currBox = *it;
+        currBox->setNeedsLayout(true);
+    }
+}
+
+void RenderView::insertFixedPositionedObject(RenderBox* object)
+{
+    if (!m_positionedObjects)
+        m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
+
+    m_positionedObjects->add(object);
+}
+
+void RenderView::removeFixedPositionedObject(RenderBox* object)
+{
+    if (!m_positionedObjects)
+        return;
+
+    m_positionedObjects->remove(object);
+}
+
 } // namespace WebCore
index a0a3e55..e6baa09 100644 (file)
@@ -179,6 +179,11 @@ public:
     IntervalArena* intervalArena();
 
     IntSize viewportSize() const { return document()->viewportSize(); }
+
+    void setFixedPositionedObjectsNeedLayout();
+    void insertFixedPositionedObject(RenderBox*);
+    void removeFixedPositionedObject(RenderBox*);
+
 protected:
     virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&, bool* wasFixed = 0) const;
     virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
@@ -254,7 +259,10 @@ protected:
 
     typedef HashSet<RenderWidget*> RenderWidgetSet;
     RenderWidgetSet m_widgets;
-    
+
+    typedef HashSet<RenderBox*> RenderBoxSet;
+    OwnPtr<RenderBoxSet> m_fixedPositionedElements;
+
 private:
     unsigned m_pageLogicalHeight;
     bool m_pageLogicalHeightChanged;
index 1db8237..0131e84 100644 (file)
@@ -1,3 +1,16 @@
+2012-04-16  Yael Aharon  <yael.aharon@nokia.com>
+
+        [Qt][WK2] Fixed elements position is wrong after zooming.
+        https://bugs.webkit.org/show_bug.cgi?id=83981
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Turn on the flag setFixedElementsLayoutRelativeToFrame. This causes fixed elements position to be calculated based on
+        visibleWidth and visibleHeight. When zoom level grows, the visibleWidth and visibleHeight become smaller.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::setResizesToContentsUsingLayoutSize):
+
 2012-04-16  Kenneth Rohde Christiansen  <kenneth@webkit.org>
 
         [Qt] Clean up how the interaction engine is making use of ViewportAttributes
index 1ea91c7..6eaecc7 100644 (file)
@@ -836,6 +836,7 @@ void WebPage::setResizesToContentsUsingLayoutSize(const IntSize& targetLayoutSiz
     view->setFixedLayoutSize(targetLayoutSize);
 
     m_page->settings()->setAcceleratedCompositingForFixedPositionEnabled(true);
+    m_page->settings()->setFixedElementsLayoutRelativeToFrame(true);
 
     // Schedule a layout to use the new target size.
     if (!view->layoutPending()) {