Mark positioned elements as needing a relayout when checking for hit test.
This is necessary when using composited fixed layers, as the layers position
may have moved UI-side, while the webkit's related position of those layers
may not have been updated yet.
Fix Bug:2457215
Change-Id: If4f0e9c3d1a4786b29dcc7c2dc3510ba090b6a36
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index fa4a180..3571a49 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -115,6 +115,7 @@
m_needsNotifyClient(false),
m_haveContents(false),
m_haveImage(false),
+ m_hasFixedLayers(false),
m_translateX(0),
m_translateY(0),
m_currentTranslateX(0),
@@ -253,6 +254,13 @@
offsetFromRenderer().width(),
offsetFromRenderer().height(),
w, h);
+
+ GraphicsLayerAndroid* rootGraphicsLayer = this;
+
+ while (rootGraphicsLayer->parent())
+ rootGraphicsLayer = static_cast<GraphicsLayerAndroid*>(rootGraphicsLayer->parent());
+
+ rootGraphicsLayer->setHasFixedLayers(true);
}
}
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index 25f70b4..d0347a7 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -121,6 +121,9 @@
void sendImmediateRepaint();
LayerAndroid* contentLayer() { return m_contentLayer; }
+ bool hasFixedLayers() const { return m_hasFixedLayers; }
+ void setHasFixedLayers(bool val) { m_hasFixedLayers = val; }
+
static int instancesCount();
private:
@@ -139,6 +142,8 @@
bool m_haveContents;
bool m_haveImage;
+ bool m_hasFixedLayers;
+
float m_translateX;
float m_translateY;
float m_currentTranslateX;
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 00ac725..554a835 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -1632,6 +1632,9 @@
x, y, m_scrollOffsetX, m_scrollOffsetY);
if (!frame || CacheBuilder::validNode(m_mainFrame, frame, NULL) == false)
frame = m_mainFrame;
+#if USE(ACCELERATED_COMPOSITING) && ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ markPositionedObjectsForLayout();
+#endif
// mouse event expects the position in the window coordinate
m_mousePos = WebCore::IntPoint(x - m_scrollOffsetX, y - m_scrollOffsetY);
// validNode will still return true if the node is null, as long as we have
@@ -1979,6 +1982,9 @@
bool WebViewCore::key(const PlatformKeyboardEvent& event)
{
+#if USE(ACCELERATED_COMPOSITING) && ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ markPositionedObjectsForLayout();
+#endif
WebCore::EventHandler* eventHandler = m_mainFrame->eventHandler();
WebCore::Node* focusNode = currentFocus();
if (focusNode)
@@ -1990,6 +1996,9 @@
// For when the user clicks the trackball
void WebViewCore::click(WebCore::Frame* frame, WebCore::Node* node) {
+#if USE(ACCELERATED_COMPOSITING) && ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ markPositionedObjectsForLayout();
+#endif
if (!node) {
WebCore::IntPoint pt = m_mousePos;
pt.move(m_scrollOffsetX, m_scrollOffsetY);
@@ -2012,6 +2021,7 @@
}
#if USE(ACCELERATED_COMPOSITING)
+
GraphicsLayerAndroid* WebViewCore::graphicsRootLayer() const
{
RenderView* contentRenderer = m_mainFrame->contentRenderer();
@@ -2020,7 +2030,24 @@
return static_cast<GraphicsLayerAndroid*>(
contentRenderer->compositor()->rootPlatformLayer());
}
-#endif
+
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+
+// If we have composited fixed elements, we need to mark
+// fixed elements' as needing a relayout, as they could have
+// visually moved on the UI side, without that movement being
+// reflected in webkit.
+void WebViewCore::markPositionedObjectsForLayout()
+{
+ GraphicsLayerAndroid* graphicsLayer = graphicsRootLayer();
+ if (graphicsLayer && graphicsLayer->hasFixedLayers() &&
+ m_mainFrame->contentRenderer())
+ m_mainFrame->contentRenderer()->markPositionedObjectsForLayout();
+}
+
+#endif // ENABLE(COMPOSITED_FIXED_ELEMENTS)
+
+#endif // USE(ACCELERATED_COMPOSITING)
bool WebViewCore::handleTouchEvent(int action, int x, int y, int metaState)
{
@@ -2032,6 +2059,10 @@
rootLayer->pauseDisplay(true);
#endif
+#if USE(ACCELERATED_COMPOSITING) && ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ markPositionedObjectsForLayout();
+#endif
+
#if ENABLE(TOUCH_EVENTS) // Android
WebCore::TouchEventType type = WebCore::TouchStart;
WebCore::PlatformTouchPoint::State touchState = WebCore::PlatformTouchPoint::TouchPressed;
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 8c885e6..336ddca 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -139,6 +139,9 @@
GraphicsLayerAndroid* graphicsRootLayer() const;
void immediateRepaint();
void setUIRootLayer(const LayerAndroid* layer);
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ void markPositionedObjectsForLayout();
+#endif
#endif
/** Invalidate the view/screen, NOT the content/DOM, but expressed in