[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9

simon.fraser at apple.com simon.fraser at apple.com
Thu Feb 4 21:23:37 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit 84fc0c6aca3414c2fd6829def76719c9ddc8430f
Author: simon.fraser at apple.com <simon.fraser at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Jan 21 20:19:10 2010 +0000

    2010-01-20  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Dave Hyatt.
    
            Hit testing on composited plugins is broken
            https://bugs.webkit.org/show_bug.cgi?id=33927
            <rdar://problem/7559069>
    
            RenderWidget::paint()'s strategy of moving widgets at paint time, using tx and ty, was flawed
            because tx,ty are not always root-relative, especially when painting into compositing layers.
            This would move widgets to the wrong location, which caused hit testing issues.
    
            Widgets are usually positioned by layout. The one time this was not true was scrolling fixed-position
            elements, so we now reposition widgets after scrolling too.
    
            There was a related problem, which was that widgets expect the graphics context to be set up for
            root-relative painting. To fix this, adjust the CTM and the paintRect when the widget's frameRect
            is in a different coordinate system to the painting offset.
    
            Test: plugins/mouse-events-fixedpos.html
    
            * page/FrameView.cpp:
            (WebCore::FrameView::scrollPositionChanged): Update widget positions, to handle widgets in fixed position
            elements, but only if we're not already inside of layout.
    
            * platform/graphics/GraphicsContext.h:
            (WebCore::GraphicsContext::translate): Add a translate() convenience method that takes a FloatSize.
    
            * platform/graphics/IntSize.h:
            (WebCore::IntSize::isZero): Add a convenience method for testing for a zero size.
    
            * platform/mac/WidgetMac.mm:
            (WebCore::Widget::paint): Adjust a comment.
    
            * rendering/RenderWidget.cpp:
            (WebCore::RenderWidget::paint): Detect when the widget's frame is in a different coordinate system
            to painting, and adjust the CTM and paintRect in that case.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53637 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 85cf0b6..034590b 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,16 @@
+2010-01-20  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        Hit testing on composited plugins is broken
+        https://bugs.webkit.org/show_bug.cgi?id=33927
+        <rdar://problem/7559069>
+
+        Testcase for hit testing on a fixed-position plugin after scrolling.
+        
+        * plugins/mouse-events-fixedpos-expected.txt: Added.
+        * plugins/mouse-events-fixedpos.html: Added.
+
 2010-01-21  Diego Gonzalez  <diego.gonzalez at openbossa.org>
 
         Reviewed by Kenneth Rohde Christiansen.
diff --git a/LayoutTests/plugins/mouse-events-fixedpos-expected.txt b/LayoutTests/plugins/mouse-events-fixedpos-expected.txt
new file mode 100644
index 0000000..6eeff92
--- /dev/null
+++ b/LayoutTests/plugins/mouse-events-fixedpos-expected.txt
@@ -0,0 +1,7 @@
+CONSOLE MESSAGE: line 0: PLUGIN: getFocusEvent
+CONSOLE MESSAGE: line 0: PLUGIN: mouseDown at (50, 50)
+CONSOLE MESSAGE: line 0: PLUGIN: mouseUp at (50, 50)
+CONSOLE MESSAGE: line 0: PLUGIN: mouseDown at (60, 60)
+CONSOLE MESSAGE: line 0: PLUGIN: mouseUp at (70, 60)
+
+Tests for widget positions being correctly updated after scrolling. rdar://problem/7559069
diff --git a/LayoutTests/plugins/mouse-events-fixedpos.html b/LayoutTests/plugins/mouse-events-fixedpos.html
new file mode 100644
index 0000000..22c9c11
--- /dev/null
+++ b/LayoutTests/plugins/mouse-events-fixedpos.html
@@ -0,0 +1,58 @@
+<html>
+<style type="text/css" media="screen">
+  body {
+    height: 1000px;
+  }
+
+  .fixed {
+    position: fixed;
+    left: 20px;
+    top: 20px;
+  }
+
+  p {
+    margin-top: 200px;
+  }
+
+  embed {
+    margin: 20px;
+  }
+</style>
+<script>
+
+  function runTest()
+  {
+    window.scrollBy(50, 50);
+
+    if (!window.layoutTestController) {
+        document.body.appendChild(document.createTextNode("This test does not work in manual mode."));
+        return;
+    }
+
+    layoutTestController.dumpAsText();
+
+    plg.eventLoggingEnabled = true;
+
+    eventSender.mouseMoveTo(70,70);
+    eventSender.mouseMoveTo(90,90);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+    eventSender.mouseMoveTo(100,100);
+    eventSender.mouseDown();
+    eventSender.mouseMoveTo(110,100);
+    eventSender.mouseUp();
+    eventSender.mouseMoveTo(20,20);
+
+    plg.eventLoggingEnabled = false; // stop logging so our output doesn't bleed into the next test
+  }
+  
+  window.addEventListener('load', runTest, false);
+</script>
+<body>
+  <div class="fixed">
+    <embed name="plg" type="application/x-webkit-test-netscape" width=100 height=100></embed>
+  </div>
+
+<p>Tests for widget positions being correctly updated after scrolling. <a href="rdar://problem/7559069">rdar://problem/7559069</a></p>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 1f559a9..d8dad58 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,41 @@
+2010-01-20  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        Hit testing on composited plugins is broken
+        https://bugs.webkit.org/show_bug.cgi?id=33927
+        <rdar://problem/7559069>
+
+        RenderWidget::paint()'s strategy of moving widgets at paint time, using tx and ty, was flawed
+        because tx,ty are not always root-relative, especially when painting into compositing layers.
+        This would move widgets to the wrong location, which caused hit testing issues.
+        
+        Widgets are usually positioned by layout. The one time this was not true was scrolling fixed-position
+        elements, so we now reposition widgets after scrolling too.
+        
+        There was a related problem, which was that widgets expect the graphics context to be set up for
+        root-relative painting. To fix this, adjust the CTM and the paintRect when the widget's frameRect
+        is in a different coordinate system to the painting offset.
+        
+        Test: plugins/mouse-events-fixedpos.html
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::scrollPositionChanged): Update widget positions, to handle widgets in fixed position
+        elements, but only if we're not already inside of layout.
+
+        * platform/graphics/GraphicsContext.h:
+        (WebCore::GraphicsContext::translate): Add a translate() convenience method that takes a FloatSize.
+
+        * platform/graphics/IntSize.h:
+        (WebCore::IntSize::isZero): Add a convenience method for testing for a zero size.
+
+        * platform/mac/WidgetMac.mm:
+        (WebCore::Widget::paint): Adjust a comment.
+
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::paint): Detect when the widget's frame is in a different coordinate system
+        to painting, and adjust the CTM and paintRect in that case.
+
 2010-01-21  Andrei Popescu  <andreip at google.com>
 
         Reviewed by David Levin.
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 86e13a7..21666ae 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -950,6 +950,13 @@ void FrameView::scrollPositionChanged()
     if (layer)
         layer->updateLayerPositions(RenderLayer::UpdateCompositingLayers);
 #endif
+
+    // Update widget positions to take care of widgets inside fixed position elements,
+    // but only if we're not inside of layout.
+    if (!m_nestedLayoutCount) {
+        if (RenderView* root = m_frame->contentRenderer())
+            root->updateWidgetPositions();
+    }
 }
 
 HostWindow* FrameView::hostWindow() const
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index 88e41e6..9d7bac3 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -291,6 +291,7 @@ namespace WebCore {
 
         void scale(const FloatSize&);
         void rotate(float angleInRadians);
+        void translate(const FloatSize& size) { translate(size.width(), size.height()); }
         void translate(float x, float y);
         IntPoint origin();
 
diff --git a/WebCore/platform/graphics/IntSize.h b/WebCore/platform/graphics/IntSize.h
index b242784..13d9e22 100644
--- a/WebCore/platform/graphics/IntSize.h
+++ b/WebCore/platform/graphics/IntSize.h
@@ -69,7 +69,8 @@ public:
     void setHeight(int height) { m_height = height; }
 
     bool isEmpty() const { return m_width <= 0 || m_height <= 0; }
-
+    bool isZero() const { return !m_width && !m_height; }
+    
     void expand(int width, int height)
     {
         m_width += width;
diff --git a/WebCore/platform/mac/WidgetMac.mm b/WebCore/platform/mac/WidgetMac.mm
index 3fd30aa..e473053 100644
--- a/WebCore/platform/mac/WidgetMac.mm
+++ b/WebCore/platform/mac/WidgetMac.mm
@@ -197,7 +197,7 @@ void Widget::paint(GraphicsContext* p, const IntRect& r)
         END_BLOCK_OBJC_EXCEPTIONS;
     } else {
         // This is the case of drawing into a bitmap context other than a window backing store. It gets hit beneath
-        // -cacheDisplayInRect:toBitmapImageRep:.
+        // -cacheDisplayInRect:toBitmapImageRep:, and when painting into compositing layers.
 
         // Transparent subframes are in fact implemented with scroll views that return YES from -drawsBackground (whenever the WebView
         // itself is in drawsBackground mode). In the normal drawing code path, the scroll views are never asked to draw the background,
diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp
index af199e2..4763309 100644
--- a/WebCore/rendering/RenderWidget.cpp
+++ b/WebCore/rendering/RenderWidget.cpp
@@ -252,18 +252,27 @@ void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty)
     }
 
     if (m_widget) {
-        // Move the widget if necessary.  We normally move and resize widgets during layout, but sometimes
-        // widgets can move without layout occurring (most notably when you scroll a document that
-        // contains fixed positioned elements).
-        m_widget->move(tx + borderLeft() + paddingLeft(), ty + borderTop() + paddingTop());
-
         // Tell the widget to paint now.  This is the only time the widget is allowed
         // to paint itself.  That way it will composite properly with z-indexed layers.
         if (m_substituteImage)
             paintInfo.context->drawImage(m_substituteImage.get(), style()->colorSpace(), m_widget->frameRect());
-        else
-            m_widget->paint(paintInfo.context, paintInfo.rect);
+        else {
+            IntPoint widgetLocation = m_widget->frameRect().location();
+            IntPoint paintLocation(tx + borderLeft() + paddingLeft(), ty + borderTop() + paddingTop());
+            IntRect paintRect = paintInfo.rect;
+
+            IntSize paintOffset = paintLocation - widgetLocation;
+            // When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer,
+            // not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing.
+            if (!paintOffset.isZero()) {
+                paintInfo.context->translate(paintOffset);
+                paintRect.move(-paintOffset);
+            }
+            m_widget->paint(paintInfo.context, paintRect);
 
+            if (!paintOffset.isZero())
+                paintInfo.context->translate(-paintOffset);
+        }
         if (m_widget->isFrameView() && paintInfo.overlapTestRequests && !static_cast<FrameView*>(m_widget.get())->useSlowRepaintsIfNotOverlapped()) {
             ASSERT(!paintInfo.overlapTestRequests->contains(this));
             paintInfo.overlapTestRequests->set(this, m_widget->frameRect());

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list