summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Scott <phanna@android.com>2010-12-09 18:12:20 -0500
committerPatrick Scott <phanna@android.com>2010-12-13 08:23:29 -0500
commitfe812d40b53dc52d5c929e39b5e293af8b6cb4e4 (patch)
tree81002048cd73d5fa21b7cac3b047c2f1b1755b64
parent83ddee4501f0c2f48d1073e0185a2fb0a732c929 (diff)
downloadexternal_webkit-fe812d40b53dc52d5c929e39b5e293af8b6cb4e4.zip
external_webkit-fe812d40b53dc52d5c929e39b5e293af8b6cb4e4.tar.gz
external_webkit-fe812d40b53dc52d5c929e39b5e293af8b6cb4e4.tar.bz2
Fix hit testing inside layers.
* Prevent asking for a sync in GraphicsLayerAndroid if some property has not changed. * Remove scrolling logic from LayerAndroid and create a subclass for scrollable layers. * Report the scrolling limits to the layer in order to scroll iframes (not turned on) and to avoid computing them each time the layer is scrolled. * Change the foreground rect calculations to better match the non-overflow case. * During hit testing, intersect the hitTestClip with the foreground and background to prevent false positives in the layer. * Prepare for iframe scrolling by adding code to trigger compositing for iframes. This currently works great except for navigation so it disabled for now. Bug: 3258631 Change-Id: I0da2d8dbe25376c6aa4f485c9350048c82c6f563
-rw-r--r--WebCore/Android.mk1
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp69
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.h4
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp45
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.h18
-rw-r--r--WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp37
-rw-r--r--WebCore/platform/graphics/android/ScrollableLayerAndroid.h65
-rw-r--r--WebCore/rendering/RenderLayer.cpp19
-rw-r--r--WebCore/rendering/RenderLayer.h16
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp5
-rw-r--r--WebKit/android/nav/WebView.cpp15
11 files changed, 201 insertions, 93 deletions
diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index fda5318..af6353e 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -614,6 +614,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/PathAndroid.cpp \
platform/graphics/android/PatternAndroid.cpp \
platform/graphics/android/PlatformGraphicsContext.cpp \
+ platform/graphics/android/ScrollableLayerAndroid.cpp \
platform/graphics/android/SharedBufferStream.cpp \
platform/graphics/android/ShaderProgram.cpp \
platform/graphics/android/SharedTexture.cpp \
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index fe7b132..0fdbc21 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -32,6 +32,7 @@
#include "RenderView.h"
#include "RotateTransformOperation.h"
#include "ScaleTransformOperation.h"
+#include "ScrollableLayerAndroid.h"
#include "SkCanvas.h"
#include "TransformationMatrix.h"
#include "TranslateTransformOperation.h"
@@ -263,6 +264,8 @@ void GraphicsLayerAndroid::updateFixedPosition()
void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
{
+ if (point == m_currentPosition)
+ return;
m_currentPosition = point;
m_needsDisplay = true;
#ifdef LAYER_DEBUG_2
@@ -276,6 +279,8 @@ void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point)
{
+ if (point == m_anchorPoint)
+ return;
GraphicsLayer::setAnchorPoint(point);
m_contentLayer->setAnchorPoint(point.x(), point.y());
askForSync();
@@ -283,14 +288,13 @@ void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point)
void GraphicsLayerAndroid::setSize(const FloatSize& size)
{
- if ((size.width() != m_size.width())
- || (size.height() != m_size.height())) {
- MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height());
- GraphicsLayer::setSize(size);
- m_contentLayer->setSize(size.width(), size.height());
- updateFixedPosition();
- askForSync();
- }
+ if (size == m_size)
+ return;
+ MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height());
+ GraphicsLayer::setSize(size);
+ m_contentLayer->setSize(size.width(), size.height());
+ updateFixedPosition();
+ askForSync();
}
void GraphicsLayerAndroid::setTransform(const TransformationMatrix& t)
@@ -329,7 +333,7 @@ void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t)
void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer)
{
if (layer == m_maskLayer)
- return;
+ return;
GraphicsLayer::setMaskLayer(layer);
m_needsSyncMask = true;
@@ -338,6 +342,8 @@ void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer)
void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds)
{
+ if (masksToBounds == m_masksToBounds)
+ return;
GraphicsLayer::setMasksToBounds(masksToBounds);
m_needsSyncMask = true;
askForSync();
@@ -345,20 +351,30 @@ void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds)
void GraphicsLayerAndroid::setDrawsContent(bool drawsContent)
{
+ if (drawsContent == m_drawsContent)
+ return;
GraphicsLayer::setDrawsContent(drawsContent);
if (m_contentLayer->isRootLayer())
return;
if (m_drawsContent) {
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
RenderLayer* layer = renderLayerFromClient(m_client);
- if (layer && layer->hasOverflowScroll() && !m_foregroundLayer) {
- m_foregroundLayer = new LayerAndroid(false);
- m_foregroundLayer->setContentScrollable(true);
- m_foregroundClipLayer = new LayerAndroid(false);
- m_foregroundClipLayer->setMasksToBounds(true);
-
- m_foregroundClipLayer->addChild(m_foregroundLayer);
- m_contentLayer->addChild(m_foregroundClipLayer);
+ if (layer) {
+ if (layer->hasOverflowScroll() && !m_foregroundLayer) {
+ m_foregroundLayer = new ScrollableLayerAndroid();
+ m_foregroundClipLayer = new LayerAndroid(false);
+ m_foregroundClipLayer->setMasksToBounds(true);
+
+ m_foregroundClipLayer->addChild(m_foregroundLayer);
+ m_contentLayer->addChild(m_foregroundClipLayer);
+ } else if (false /* FIXME: disable until navigation is fixed */ &&
+ layer->isRootLayer() &&
+ layer->renderer()->frame()->ownerRenderer()) {
+ // Replace the content layer with a scrollable layer.
+ LayerAndroid* layer = new ScrollableLayerAndroid(*m_contentLayer);
+ m_contentLayer->unref();
+ m_contentLayer = layer;
+ }
}
#endif
@@ -370,6 +386,8 @@ void GraphicsLayerAndroid::setDrawsContent(bool drawsContent)
void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
{
+ if (color == m_backgroundColor)
+ return;
LOG("(%x) setBackgroundColor", this);
GraphicsLayer::setBackgroundColor(color);
SkColor c = SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue());
@@ -387,6 +405,8 @@ void GraphicsLayerAndroid::clearBackgroundColor()
void GraphicsLayerAndroid::setContentsOpaque(bool opaque)
{
+ if (opaque == m_contentsOpaque)
+ return;
LOG("(%x) setContentsOpaque (%d)", this, opaque);
GraphicsLayer::setContentsOpaque(opaque);
m_haveContents = true;
@@ -449,6 +469,7 @@ bool GraphicsLayerAndroid::repaint()
// with SkPicture, we request the entire layer's content.
IntRect layerBounds(0, 0, m_size.width(), m_size.height());
+ RenderLayer* layer = renderLayerFromClient(m_client);
if (m_foregroundLayer) {
PaintingPhase phase(this);
// Paint the background into a separate context.
@@ -456,7 +477,6 @@ bool GraphicsLayerAndroid::repaint()
if (!paintContext(m_contentLayer->recordContext(), layerBounds))
return false;
- RenderLayer* layer = renderLayerFromClient(m_client);
// Construct the foreground layer and draw.
RenderBox* box = layer->renderBox();
int outline = box->view()->maximalOutlineSize();
@@ -485,11 +505,20 @@ bool GraphicsLayerAndroid::repaint()
// Need to offset the foreground layer by the clip layer in order
// for the contents to be in the correct position.
m_foregroundLayer->setPosition(-x, -y);
+ // Set the scrollable bounds of the layer.
+ m_foregroundLayer->setScrollLimits(-x, -y, m_size.width(), m_size.height());
} else {
// If there is no contents clip, we can draw everything into one
// picture.
if (!paintContext(m_contentLayer->recordContext(), layerBounds))
return false;
+ // Check for a scrollable iframe and report the scrolling
+ // limits based on the view size.
+ if (m_contentLayer->contentIsScrollable()) {
+ FrameView* view = layer->renderer()->frame()->view();
+ static_cast<ScrollableLayerAndroid*>(m_contentLayer)->setScrollLimits(
+ m_position.x(), m_position.y(), view->layoutWidth(), view->layoutHeight());
+ }
}
TLOG("(%x) repaint() on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!",
@@ -579,7 +608,7 @@ bool GraphicsLayerAndroid::addAnimation(const KeyframeValueList& valueList,
double beginTime)
{
if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() != 2)
- return false;
+ return false;
bool createdAnimations = false;
if (valueList.property() == AnimatedPropertyWebkitTransform) {
@@ -882,6 +911,8 @@ void GraphicsLayerAndroid::setDebugBorder(const Color& color, float borderWidth)
void GraphicsLayerAndroid::setZPosition(float position)
{
+ if (position == m_zPosition)
+ return;
LOG("(%x) setZPosition: %.2f", this, position);
GraphicsLayer::setZPosition(position);
askForSync();
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index 098ad37..ea8c5c9 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -32,6 +32,8 @@ class Image;
namespace WebCore {
+class ScrollableLayerAndroid;
+
class GraphicsLayerAndroid : public GraphicsLayer {
public:
@@ -149,7 +151,7 @@ private:
Vector<FloatRect> m_invalidatedRects;
LayerAndroid* m_contentLayer;
- LayerAndroid* m_foregroundLayer;
+ ScrollableLayerAndroid* m_foregroundLayer;
LayerAndroid* m_foregroundClipLayer;
};
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp
index ca9a0e3..f02136a 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -51,7 +51,6 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(),
m_haveClip(false),
m_doRotation(false),
m_isFixed(false),
- m_contentScrollable(false),
m_recordingPicture(0),
m_contentsImage(0),
m_extra(0),
@@ -68,7 +67,6 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(),
LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
m_isRootLayer(layer.m_isRootLayer),
m_haveClip(layer.m_haveClip),
- m_contentScrollable(layer.m_contentScrollable),
m_extra(0), // deliberately not copied
m_uniqueId(layer.m_uniqueId)
{
@@ -96,7 +94,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
SkSafeRef(m_recordingPicture);
for (int i = 0; i < layer.countChildren(); i++)
- addChild(new LayerAndroid(*layer.getChild(i)))->unref();
+ addChild(layer.getChild(i)->copy())->unref();
KeyframesMap::const_iterator end = layer.m_animations.end();
for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it)
@@ -110,7 +108,6 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(),
m_haveClip(false),
m_doRotation(false),
m_isFixed(false),
- m_contentScrollable(false),
m_recordingPicture(picture),
m_contentsImage(0),
m_extra(0),
@@ -476,46 +473,6 @@ SkPicture* LayerAndroid::recordContext()
return 0;
}
-bool LayerAndroid::scrollTo(int x, int y) {
- SkIRect scrollBounds;
- getScrollRect(&scrollBounds);
- if (scrollBounds.fRight == 0 && scrollBounds.fBottom == 0)
- return false;
-
- SkScalar newX = SkScalarPin(x, 0, scrollBounds.fRight);
- SkScalar newY = SkScalarPin(y, 0, scrollBounds.fBottom);
- // Check for no change.
- if (newX == scrollBounds.fLeft && newY == scrollBounds.fTop)
- return false;
-
- SkScalar diffX = newX - scrollBounds.fLeft;
- SkScalar diffY = newY - scrollBounds.fTop;
- const SkPoint& pos = getPosition();
- setPosition(pos.fX - diffX, pos.fY - diffY);
- return true;
-}
-
-void LayerAndroid::getScrollRect(SkIRect* out) const {
- if (!contentIsScrollable())
- return;
-
- // Scrollable layers have a mask layer and then the actual main layer.
- if (getParent() == 0 || getParent()->getParent() == 0)
- return;
- LayerAndroid* realLayer = static_cast<LayerAndroid*>(getParent()->getParent());
-
- SkRect scrollBounds;
- realLayer->bounds(&scrollBounds);
-
- const SkPoint& maskLayerPosition = getParent()->getPosition();
- const SkPoint& pos = getPosition();
- // Our original position is the offset of the mask layer's position.
- out->fLeft = maskLayerPosition.fX - pos.fX;
- out->fTop = maskLayerPosition.fY - pos.fY;
- out->fRight = getSize().width() - scrollBounds.width();
- out->fBottom = getSize().height() - scrollBounds.height();
-}
-
bool LayerAndroid::prepareContext(bool force)
{
if (masksToBounds())
diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h
index 30f5555..510014b 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/WebCore/platform/graphics/android/LayerAndroid.h
@@ -131,15 +131,6 @@ public:
SkPicture* recordContext();
- // Returns true if the content position has changed.
- bool scrollTo(int dx, int dy);
- // Fills the rect with the current scroll offset and the maximum scroll.
- // fLeft = scrollX
- // fTop = scrollY
- // fRight = maxX
- // fBottom = maxY
- void getScrollRect(SkIRect* out) const;
-
void addAnimation(PassRefPtr<AndroidAnimation> anim);
void removeAnimation(const String& name);
bool evaluateAnimations() const;
@@ -193,12 +184,8 @@ public:
void bounds(SkRect* ) const;
- bool contentIsScrollable() const { return m_contentScrollable; }
-
- // Set when building the layer hierarchy for scrollable elements.
- void setContentScrollable(bool scrollable) {
- m_contentScrollable = scrollable;
- }
+ virtual bool contentIsScrollable() const { return false; }
+ virtual LayerAndroid* copy() const { return new LayerAndroid(*this); }
protected:
virtual void onDraw(SkCanvas*, SkScalar opacity);
@@ -219,7 +206,6 @@ private:
bool m_doRotation;
bool m_isFixed;
bool m_backgroundColorSet;
- bool m_contentScrollable;
SkLength m_fixedLeft;
SkLength m_fixedTop;
diff --git a/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp b/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
new file mode 100644
index 0000000..7b40b8d
--- /dev/null
+++ b/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
@@ -0,0 +1,37 @@
+#include "config.h"
+#include "ScrollableLayerAndroid.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+namespace WebCore {
+
+bool ScrollableLayerAndroid::scrollTo(int x, int y) {
+ SkIRect scrollBounds;
+ getScrollRect(&scrollBounds);
+ if (scrollBounds.fRight == 0 && scrollBounds.fBottom == 0)
+ return false;
+
+ SkScalar newX = SkScalarPin(x, 0, scrollBounds.fRight);
+ SkScalar newY = SkScalarPin(y, 0, scrollBounds.fBottom);
+ // Check for no change.
+ if (newX == scrollBounds.fLeft && newY == scrollBounds.fTop)
+ return false;
+
+ SkScalar diffX = newX - scrollBounds.fLeft;
+ SkScalar diffY = newY - scrollBounds.fTop;
+ const SkPoint& pos = getPosition();
+ setPosition(pos.fX - diffX, pos.fY - diffY);
+ return true;
+}
+
+void ScrollableLayerAndroid::getScrollRect(SkIRect* out) const {
+ const SkPoint& pos = getPosition();
+ out->fLeft = m_scrollLimits.fLeft - pos.fX;
+ out->fTop = m_scrollLimits.fTop - pos.fY;
+ out->fRight = getSize().width() - m_scrollLimits.width();
+ out->fBottom = getSize().height() - m_scrollLimits.height();
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/android/ScrollableLayerAndroid.h b/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
new file mode 100644
index 0000000..d63625a
--- /dev/null
+++ b/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ScrollableLayerAndroid_h
+#define ScrollableLayerAndroid_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerAndroid.h"
+
+namespace WebCore {
+
+class ScrollableLayerAndroid : public LayerAndroid {
+
+public:
+ ScrollableLayerAndroid()
+ : LayerAndroid(false) {}
+ ScrollableLayerAndroid(const ScrollableLayerAndroid& layer)
+ : LayerAndroid(layer)
+ , m_scrollLimits(layer.m_scrollLimits) {}
+ ScrollableLayerAndroid(const LayerAndroid& layer)
+ : LayerAndroid(layer) {
+ m_scrollLimits.setEmpty();
+ }
+ virtual ~ScrollableLayerAndroid() {};
+
+ virtual bool contentIsScrollable() const { return true; }
+
+ virtual LayerAndroid* copy() const { return new ScrollableLayerAndroid(*this); }
+
+ // Returns true if the content position has changed.
+ bool scrollTo(int dx, int dy);
+ // Fills the rect with the current scroll offset and the maximum scroll.
+ // fLeft = scrollX
+ // fTop = scrollY
+ // fRight = maxX
+ // fBottom = maxY
+ void getScrollRect(SkIRect* out) const;
+
+ void setScrollLimits(float x, float y, float width, float height) {
+ m_scrollLimits.set(x, y, width, height);
+ }
+
+private:
+ SkRect m_scrollLimits;
+};
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // LayerAndroid_h
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 4221816..9d894af 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -2945,6 +2945,14 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
candidateLayer = hitLayer;
}
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ if (hasOverflowParent()) {
+ ClipRects clipRects;
+ calculateClipRects(rootLayer, clipRects, useTemporaryClipRects);
+ fgRect.intersect(clipRects.hitTestClip());
+ bgRect.intersect(clipRects.hitTestClip());
+ }
+#endif
// Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
if (fgRect.intersects(hitTestArea) && isSelfPaintingLayer()) {
// Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
@@ -3223,12 +3231,12 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& cl
if (renderer()->hasOverflowClip()) {
IntRect newOverflowClip = toRenderBox(renderer())->overflowClipRect(x, y);
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ clipRects.setHitTestClip(intersection(newOverflowClip, clipRects.hitTestClip()));
if (hasOverflowScroll()) {
RenderBox* box = toRenderBox(renderer());
newOverflowClip =
- IntRect(x, y,
- box->borderLeft() + box->borderRight() + m_scrollWidth,
- box->borderTop() + box->borderBottom() + m_scrollHeight);
+ IntRect(x + box->borderLeft(), y + box->borderTop(),
+ m_scrollWidth, m_scrollHeight);
}
#endif
clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect()));
@@ -3298,9 +3306,8 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa
// Use the entire foreground rectangle to record the contents.
RenderBox* box = toRenderBox(renderer());
foregroundRect =
- IntRect(x, y,
- box->borderLeft() + box->borderRight() + m_scrollWidth,
- box->borderTop() + box->borderBottom() + m_scrollHeight);
+ IntRect(x + box->borderLeft(), y + box->borderTop(),
+ m_scrollWidth, m_scrollHeight);
} else
#endif
if (renderer()->hasOverflowClip())
diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h
index 6b60fe1..be3ddc6 100644
--- a/WebCore/rendering/RenderLayer.h
+++ b/WebCore/rendering/RenderLayer.h
@@ -79,6 +79,9 @@ public:
: m_overflowClipRect(r)
, m_fixedClipRect(r)
, m_posClipRect(r)
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ , m_hitTestClip(r)
+#endif
, m_refCnt(0)
, m_fixed(false)
{
@@ -88,6 +91,9 @@ public:
: m_overflowClipRect(other.overflowClipRect())
, m_fixedClipRect(other.fixedClipRect())
, m_posClipRect(other.posClipRect())
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ , m_hitTestClip(other.hitTestClip())
+#endif
, m_refCnt(0)
, m_fixed(other.fixed())
{
@@ -98,6 +104,9 @@ public:
m_overflowClipRect = r;
m_fixedClipRect = r;
m_posClipRect = r;
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ m_hitTestClip = r;
+#endif
m_fixed = false;
}
@@ -109,6 +118,10 @@ public:
const IntRect& posClipRect() const { return m_posClipRect; }
void setPosClipRect(const IntRect& r) { m_posClipRect = r; }
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ const IntRect& hitTestClip() const { return m_hitTestClip; }
+ void setHitTestClip(const IntRect& r) { m_hitTestClip = r; }
+#endif
bool fixed() const { return m_fixed; }
void setFixed(bool fixed) { m_fixed = fixed; }
@@ -149,6 +162,9 @@ private:
IntRect m_overflowClipRect;
IntRect m_fixedClipRect;
IntRect m_posClipRect;
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ IntRect m_hitTestClip;
+#endif
unsigned m_refCnt : 31;
bool m_fixed : 1;
};
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index cf75a2a..ce80e5a 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1176,6 +1176,11 @@ bool RenderLayerCompositor::requiresCompositingForMobileSites(const RenderLayer*
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
if (layer->hasOverflowScroll())
return true;
+ HTMLFrameOwnerElement* ownerElement = enclosingIFrameElement();
+ RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0;
+ // FIXME: Disabled for now until navigation is fixed.
+ if (false && layer->isRootLayer() && renderer && renderer->isRenderIFrame())
+ return true;
#endif
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
// First, check if we are in an iframe, and if so bail out
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index c5ed5e5..9063f38 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -44,6 +44,7 @@
#include "Node.h"
#include "PlatformGraphicsContext.h"
#include "PlatformString.h"
+#include "ScrollableLayerAndroid.h"
#include "SelectText.h"
#include "SkCanvas.h"
#include "SkDumpCanvas.h"
@@ -983,12 +984,12 @@ bool motionUp(int x, int y, int slop)
}
#if USE(ACCELERATED_COMPOSITING)
-static const LayerAndroid* findScrollableLayer(const LayerAndroid* parent, int x, int y) {
+static const ScrollableLayerAndroid* findScrollableLayer(const LayerAndroid* parent, int x, int y) {
SkRect bounds;
parent->bounds(&bounds);
// Check the parent bounds first; this will clip to within a masking layer's
// bounds.
- if (!bounds.contains(x, y))
+ if (parent->masksToBounds() && !bounds.contains(x, y))
return 0;
// Move the hit test local to parent.
x -= bounds.fLeft;
@@ -996,12 +997,12 @@ static const LayerAndroid* findScrollableLayer(const LayerAndroid* parent, int x
int count = parent->countChildren();
for (int i = 0; i < count; i++) {
const LayerAndroid* child = parent->getChild(i);
- const LayerAndroid* result = findScrollableLayer(child, x, y);
+ const ScrollableLayerAndroid* result = findScrollableLayer(child, x, y);
if (result)
return result;
}
if (parent->contentIsScrollable())
- return parent;
+ return static_cast<const ScrollableLayerAndroid*>(parent);
return 0;
}
#endif
@@ -1012,7 +1013,7 @@ int scrollableLayer(int x, int y, SkIRect* layerRect)
const LayerAndroid* layerRoot = compositeRoot();
if (!layerRoot)
return 0;
- const LayerAndroid* result = findScrollableLayer(layerRoot, x, y);
+ const ScrollableLayerAndroid* result = findScrollableLayer(layerRoot, x, y);
if (result) {
result->getScrollRect(layerRect);
return result->uniqueId();
@@ -2242,9 +2243,9 @@ static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint x,
if (!root)
return false;
LayerAndroid* layer = root->findById(layerId);
- if (!layer)
+ if (!layer || !layer->contentIsScrollable())
return false;
- return layer->scrollTo(x, y);
+ return static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y);
#endif
return false;
}