diff options
-rw-r--r-- | WebCore/page/EventHandler.cpp | 14 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.h | 4 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/android_graphics.cpp | 2 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/android_graphics.h | 1 | ||||
-rw-r--r-- | WebCore/rendering/RenderBox.cpp | 8 | ||||
-rw-r--r-- | WebCore/rendering/RenderLayer.cpp | 26 | ||||
-rw-r--r-- | WebCore/rendering/RenderLayerCompositor.cpp | 15 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 58 | ||||
-rw-r--r-- | WebKit/android/nav/CacheBuilder.cpp | 17 | ||||
-rw-r--r-- | WebKit/android/nav/CachedFrame.cpp | 32 | ||||
-rw-r--r-- | WebKit/android/nav/CachedFrame.h | 2 | ||||
-rw-r--r-- | WebKit/android/nav/CachedLayer.cpp | 75 | ||||
-rw-r--r-- | WebKit/android/nav/CachedLayer.h | 7 | ||||
-rw-r--r-- | WebKit/android/nav/CachedRoot.cpp | 4 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 9 |
15 files changed, 212 insertions, 62 deletions
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp index 89e9424..e2fab6e 100644 --- a/WebCore/page/EventHandler.cpp +++ b/WebCore/page/EventHandler.cpp @@ -1257,7 +1257,14 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) } m_mouseDownWasInSubframe = false; +#if ENABLE(COMPOSITED_FIXED_ELEMENTS) + // Add IgnoreClipping because fixed position elements are moved only on the + // UI thread. Nodes in fixed position elements are clipped out by the view + // without IgnoreClipping. + HitTestRequest request(HitTestRequest::Active | HitTestRequest::IgnoreClipping); +#else HitTestRequest request(HitTestRequest::Active); +#endif // Save the document point we generate in case the window coordinate is invalidated by what happens // when we dispatch the event. IntPoint documentPoint = documentPointForWindowPoint(m_frame, mouseEvent.pos()); @@ -1575,7 +1582,14 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent) return m_lastScrollbarUnderMouse->mouseUp(); } +#if ENABLE(COMPOSITED_FIXED_ELEMENTS) + // Add IgnoreClipping because fixed position elements are moved only on the + // UI thread. Nodes in fixed position elements are clipped out by the view + // without IgnoreClipping. + HitTestRequest request(HitTestRequest::MouseUp | HitTestRequest::IgnoreClipping); +#else HitTestRequest request(HitTestRequest::MouseUp); +#endif MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent); Frame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev); if (m_eventHandlerWillResetCapturingMouseEventsNode) diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index b74a8c8..712d699 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -135,6 +135,10 @@ public: void setForegroundClip(const SkRect& clip) { m_foregroundClip = clip; } + + // Return the foreground clip offset by the position of the layer. + SkRect foregroundClip() const { return m_foregroundClip; } + bool contentIsScrollable() const; // Returns true if the content position has changed. diff --git a/WebCore/platform/graphics/android/android_graphics.cpp b/WebCore/platform/graphics/android/android_graphics.cpp index fafd3df..a5dafda 100644 --- a/WebCore/platform/graphics/android/android_graphics.cpp +++ b/WebCore/platform/graphics/android/android_graphics.cpp @@ -140,7 +140,9 @@ bool CursorRing::setup() m_rings.clear(); m_rings.append(m_bounds); } + m_absBounds = m_node->bounds(m_frame); m_bounds.inflate(SkScalarCeil(CURSOR_RING_OUTER_DIAMETER)); + m_absBounds.inflate(SkScalarCeil(CURSOR_RING_OUTER_DIAMETER)); if (!m_node->hasCursorRing() || (m_node->isPlugin() && m_node->isFocus())) return false; m_flavor = NORMAL_FLAVOR; diff --git a/WebCore/platform/graphics/android/android_graphics.h b/WebCore/platform/graphics/android/android_graphics.h index dbf1978..46c60e8 100644 --- a/WebCore/platform/graphics/android/android_graphics.h +++ b/WebCore/platform/graphics/android/android_graphics.h @@ -71,6 +71,7 @@ private: WebViewCore* m_viewImpl; // copy for convenience WTF::Vector<IntRect> m_rings; IntRect m_bounds; + IntRect m_absBounds; const CachedRoot* m_root; const CachedFrame* m_frame; const CachedNode* m_node; diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp index 8d18440..2deeffc 100644 --- a/WebCore/rendering/RenderBox.cpp +++ b/WebCore/rendering/RenderBox.cpp @@ -73,10 +73,6 @@ bool RenderBox::s_hadOverflowClip = false; RenderBox::RenderBox(Node* node) : RenderBoxModelObject(node) -#ifdef ANDROID_LAYOUT - , m_visibleWidth(0) - , m_isVisibleWidthChangedBeforeLayout(false) -#endif , m_marginLeft(0) , m_marginRight(0) , m_marginTop(0) @@ -84,6 +80,10 @@ RenderBox::RenderBox(Node* node) , m_minPrefWidth(-1) , m_maxPrefWidth(-1) , m_inlineBoxWrapper(0) +#ifdef ANDROID_LAYOUT + , m_visibleWidth(0) + , m_isVisibleWidthChangedBeforeLayout(false) +#endif { setIsBox(); } diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp index f0c6333..368a1a7 100644 --- a/WebCore/rendering/RenderLayer.cpp +++ b/WebCore/rendering/RenderLayer.cpp @@ -3238,16 +3238,18 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa if (renderer()->hasOverflowClip() || renderer()->hasClip()) { // This layer establishes a clip of some kind. #if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (renderer()->hasOverflowClip()) { + if (renderer()->hasOverflowClip() && + !m_scrollDimensionsDirty && + (m_scrollWidth > renderBox()->clientWidth() || + m_scrollHeight > renderBox()->clientHeight())) { RenderBox* box = toRenderBox(renderer()); layerBounds = backgroundRect = foregroundRect = outlineRect = IntRect(x, y, box->borderLeft() + box->borderRight() + m_scrollWidth, box->borderTop() + box->borderBottom() + m_scrollHeight); - } -#else + } else +#endif if (renderer()->hasOverflowClip()) foregroundRect.intersect(toRenderBox(renderer())->overflowClipRect(x, y)); -#endif if (renderer()->hasClip()) { // Clip applies to *us* as well, so go ahead and update the damageRect. IntRect newPosClip = toRenderBox(renderer())->clipRect(x, y); @@ -3757,24 +3759,10 @@ bool RenderLayer::shouldBeNormalFlowOnly() const && !isTransparent(); } -#if ENABLE(ANDROID_OVERFLOW_SCROLL) -static bool hasOverflowScroll(const RenderLayer* layer) -{ - RenderBox* box = layer->renderBox(); - if (!box || !box->node() || !box->node()->hasTagName(HTMLNames::divTag)) - return false; - EOverflow x = box->style()->overflowX(); - EOverflow y = box->style()->overflowY(); - return (x == OAUTO || x == OSCROLL || y == OAUTO || y == OSCROLL) && - (box->scrollWidth() > box->clientWidth() || - box->scrollHeight() > box->clientHeight()); -} -#endif - bool RenderLayer::isSelfPaintingLayer() const { #if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (hasOverflowScroll(this)) + if (renderer()->hasOverflowClip()) return true; #endif return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow() || renderer()->isVideo() || renderer()->isEmbeddedObject() || renderer()->isRenderIFrame(); diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp index 46278a2..f6e1442 100644 --- a/WebCore/rendering/RenderLayerCompositor.cpp +++ b/WebCore/rendering/RenderLayerCompositor.cpp @@ -1155,19 +1155,6 @@ bool RenderLayerCompositor::requiresCompositingForMobileSites(const RenderLayer* } #endif -#if ENABLE(ANDROID_OVERFLOW_SCROLL) -static bool requiresCompositingForOverflowScroll(const RenderLayer* layer) { - RenderBox* box = layer->renderBox(); - if (!box || !box->node()->hasTagName(HTMLNames::divTag)) - return false; - EOverflow x = box->style()->overflowX(); - EOverflow y = box->style()->overflowY(); - return (x == OAUTO || x == OSCROLL || y == OAUTO || y == OSCROLL) && - (box->scrollWidth() > box->clientWidth() || - box->scrollHeight() > box->clientHeight()); -} -#endif - // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons. // Use needsToBeComposited() to determine if a RL actually needs a compositing layer. // static @@ -1183,7 +1170,7 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) c #if PLATFORM(ANDROID) || requiresCompositingForMobileSites(layer) #if ENABLE(ANDROID_OVERFLOW_SCROLL) - || requiresCompositingForOverflowScroll(layer) + || renderer->hasOverflowClip() #endif #endif || requiresCompositingForVideo(renderer) diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index 3da678e..9d2a430 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -2357,6 +2357,59 @@ void WebViewCore::touchUp(int touchGeneration, handleMouseClick(frame, node); } +// Return the RenderLayer for the given RenderObject only if the layer is +// composited and it contains a scrollable content layer. +static WebCore::RenderLayer* getLayerFromRenderer(WebCore::RenderObject* renderer) +{ + if (!renderer) + return 0; + WebCore::RenderLayer* layer = renderer->enclosingSelfPaintingLayer(); + if (!layer || !layer->backing()) + return 0; + GraphicsLayerAndroid* graphicsLayer = + static_cast<GraphicsLayerAndroid*>(layer->backing()->graphicsLayer()); + if (!graphicsLayer) + return 0; + LayerAndroid* aLayer = graphicsLayer->contentLayer(); + if (!aLayer || !aLayer->contentIsScrollable()) + return 0; + return layer; +} + +// Scroll the RenderLayer associated with a scrollable div element. This is +// done so that the node is visible when it is clicked. +static void scrollLayer(WebCore::RenderObject* renderer, WebCore::IntPoint* pos) +{ + WebCore::RenderLayer* layer = getLayerFromRenderer(renderer); + if (!layer) + return; + WebCore::IntRect absBounds = renderer->absoluteBoundingBoxRect(); + WebCore::IntRect layerBounds = layer->absoluteBoundingBox(); + + // Move the node's bounds into the layer's coordinates. + absBounds.move(-layerBounds.x(), -layerBounds.y()); + + // Scroll the layer to the node's position. The false parameters tell the + // layer not to invalidate. + layer->scrollToOffset(absBounds.x(), absBounds.y(), false, false); + + // Update the mouse position to the layer offset. + pos->move(-layer->scrollXOffset(), -layer->scrollYOffset()); +} + +static void restoreScrolledLayer(WebCore::RenderObject* renderer, + WebCore::IntPoint* pos) +{ + WebCore::RenderLayer* layer = getLayerFromRenderer(renderer); + if (!layer) + return; + // Move the mouse position back to it's original position. + pos->move(layer->scrollXOffset(), layer->scrollYOffset()); + + // Scroll the layer back to 0,0. + layer->scrollToOffset(0, 0, false, false); +} + // Common code for both clicking with the trackball and touchUp bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr) { @@ -2373,6 +2426,7 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node DBG_NAV_LOG("area"); return true; } + WebCore::RenderObject* renderer = nodePtr->renderer(); if (renderer && (renderer->isMenuList() || renderer->isListBox())) { WebCore::HTMLSelectElement* select = static_cast<WebCore::HTMLSelectElement*>(nodePtr); @@ -2415,6 +2469,8 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node } if (!valid || !framePtr) framePtr = m_mainFrame; + if (nodePtr && valid) + scrollLayer(nodePtr->renderer(), &m_mousePos); webFrame->setUserInitiatedClick(true); WebCore::PlatformMouseEvent mouseDown(m_mousePos, m_mousePos, WebCore::LeftButton, WebCore::MouseEventPressed, 1, false, false, false, false, @@ -2451,6 +2507,8 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node requestKeyboard(true); } } + if (nodePtr && valid) + restoreScrolledLayer(nodePtr->renderer(), &m_mousePos); return handled; } diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp index 5fddc48..b4a91bc 100644 --- a/WebKit/android/nav/CacheBuilder.cpp +++ b/WebKit/android/nav/CacheBuilder.cpp @@ -979,7 +979,6 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, cachedRoot->setFocusBounds(focused->getRect()); int globalOffsetX, globalOffsetY; GetGlobalOffset(frame, &globalOffsetX, &globalOffsetY); - IntPoint bodyPos = IntPoint(0, 0); while (walk.mMore || (node = node->traverseNextNode()) != NULL) { #if DUMP_NAV_CACHE nodeIndex++; @@ -1062,7 +1061,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, #if USE(ACCELERATED_COMPOSITING) if (nodeRenderer->hasLayer()) { TrackLayer(layerTracker, nodeRenderer, lastChild, - globalOffsetX - bodyPos.x(), globalOffsetY - bodyPos.y()); + globalOffsetX, globalOffsetY); size_t size = tracker.size(); const LayerAndroid* layer = layerTracker.last().mLayer; if (layer) { @@ -1129,10 +1128,15 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, originalAbsBounds = absBounds; absBounds.move(globalOffsetX, globalOffsetY); hasClip = nodeRenderer->hasOverflowClip(); +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + if (nodeRenderer->hasLayer()) { + const LayerAndroid* layer = layerTracker.last().mLayer; + if (layer && layer->contentIsScrollable()) + hasClip = false; + } +#endif - if (node->hasTagName(HTMLNames::bodyTag)) - bodyPos = originalAbsBounds.location(); - else if (node->hasTagName(HTMLNames::canvasTag)) + if (node->hasTagName(HTMLNames::canvasTag)) mPictureSetDisabled = true; if (checkForPluginViewThatWantsFocus(nodeRenderer)) { bounds = absBounds; @@ -1323,7 +1327,8 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, LayerAndroid* layer = layerTracker.last().mLayer; if (layer) { const IntRect& layerClip = layerTracker.last().mBounds; - if (!layerClip.isEmpty() && !cachedNode.clip(layerClip)) { + if (!layer->contentIsScrollable() && !layerClip.isEmpty() && + !cachedNode.clip(layerClip)) { DBG_NAV_LOGD("skipped on layer clip %d", cacheIndex); continue; // skip this node if outside of the clip } diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp index ff13508..3bf16fc 100644 --- a/WebKit/android/nav/CachedFrame.cpp +++ b/WebKit/android/nav/CachedFrame.cpp @@ -48,6 +48,19 @@ WebCore::IntRect CachedFrame::adjustBounds(const CachedNode* node, #endif } +// This is for nodes inside a layer. It takes an IntRect that has been +// adjusted by the layer's position and removes the adjustment made by the +// layer. +WebCore::IntRect CachedFrame::unadjustBounds(const CachedNode* node, + const WebCore::IntRect& rect) const +{ +#if USE(ACCELERATED_COMPOSITING) + if (node->isInLayer()) + return layer(node)->unadjustBounds(mRoot->rootLayer(), rect); +#endif + return rect; +} + bool CachedFrame::CheckBetween(Direction direction, const WebCore::IntRect& bestRect, const WebCore::IntRect& prior, WebCore::IntRect* result) { @@ -394,8 +407,10 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect, if (*directHit == NULL) { *directHit = test; *directHitFramePtr = this; - *x = center.x(); - *y = center.y(); + IntRect r(center, IntSize(0, 0)); + r = unadjustBounds(test, r); + *x = r.x(); + *y = r.y(); } else { // We have hit another one before const CachedNode* d = *directHit; @@ -436,6 +451,7 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect, *inside = testInside; result = test; *framePtr = this; + both = unadjustBounds(test, both); *x = both.x() + (both.width() >> 1); *y = both.y() + (both.height() >> 1); } @@ -500,6 +516,7 @@ const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect, if (cursorRect.intersects(rect)) { WebCore::IntRect intersection(cursorRect); intersection.intersect(rect); + intersection = unadjustBounds(test, intersection); *x = intersection.x() + (intersection.width() >> 1); *y = intersection.y() + (intersection.height() >> 1); *framePtr = this; @@ -696,12 +713,17 @@ int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, testData.mNode->setCondition(CachedNode::DISABLED); return REJECT_TEST; } - if (mRoot->scrolledBounds().intersects(test->bounds(this)) == false) { + WebCore::IntRect bounds = test->bounds(this); + if (bounds.isEmpty()) { + testData.mNode->setCondition(CachedNode::NAVABLE); + return REJECT_TEST; + } + if (mRoot->scrolledBounds().intersects(bounds) == false) { testData.mNode->setCondition(CachedNode::NAVABLE); return REJECT_TEST; } if (mRoot->rootLayer() && !test->isInLayer() - && !mRoot->baseUncovered().intersects(test->bounds(this))) { + && !mRoot->baseUncovered().intersects(bounds)) { testData.mNode->setCondition(CachedNode::UNDER_LAYER); return REJECT_TEST; } @@ -901,7 +923,7 @@ WebCore::IntRect CachedFrame::localBounds(const CachedNode* node, DBG_NAV_LOGD("node=%p [%d] rect=(%d,%d,w=%d,h=%d)", node, node->index(), rect.x(), rect.y(), rect.width(), rect.height()); #if USE(ACCELERATED_COMPOSITING) - return layer(node)->localBounds(rect); + return layer(node)->localBounds(mRoot->rootLayer(), rect); #else return rect; #endif diff --git a/WebKit/android/nav/CachedFrame.h b/WebKit/android/nav/CachedFrame.h index 9334707..caba482 100644 --- a/WebKit/android/nav/CachedFrame.h +++ b/WebKit/android/nav/CachedFrame.h @@ -78,6 +78,8 @@ public: void addFrame(CachedFrame& child) { mCachedFrames.append(child); } WebCore::IntRect adjustBounds(const CachedNode* , const WebCore::IntRect& ) const; + WebCore::IntRect unadjustBounds(const CachedNode*, + const WebCore::IntRect& ) const; bool checkRings(const CachedNode* node, const WTF::Vector<WebCore::IntRect>& rings, const WebCore::IntRect& bounds) const; diff --git a/WebKit/android/nav/CachedLayer.cpp b/WebKit/android/nav/CachedLayer.cpp index 2f6e20a..9c7d59b 100644 --- a/WebKit/android/nav/CachedLayer.cpp +++ b/WebKit/android/nav/CachedLayer.cpp @@ -46,23 +46,67 @@ IntRect CachedLayer::adjustBounds(const LayerAndroid* root, return bounds; } FloatRect temp = bounds; + // First, remove the original offset from the bounds. + temp.move(-mOffset.x(), -mOffset.y()); + + // Next, add in the new position of the layer (could be different due to a + // fixed position layer). const FloatPoint& position = aLayer->getPosition(); temp.move(position.x(), position.y()); + + // Add in any layer translation. const FloatPoint& translation = aLayer->translation(); temp.move(translation.x(), translation.y()); + + // Move the bounds by the layer's internal scroll position. + const SkPoint& scroll = aLayer->scrollPosition(); + temp.move(SkScalarToFloat(-scroll.fX), SkScalarToFloat(-scroll.fY)); + IntRect result = enclosingIntRect(temp); + + // Finally, clip the result to the foreground (this includes the object's + // border which does not scroll). + IntRect clip(aLayer->foregroundClip()); + clip.move(position.x(), position.y()); + result.intersect(clip); + DBG_NAV_LOGD("root=%p aLayer=%p [%d]" - " bounds=(%d,%d,w=%d,h=%d) pos=(%g,%g) trans=(%g,%g)" - " result=(%d,%d,w=%d,h=%d) offset=(%d,%d)", + " bounds=(%d,%d,w=%d,h=%d) trans=(%g,%g)" + " offset=(%d,%d) clip=(%d,%d,w=%d,h=%d)" + " result=(%d,%d,w=%d,h=%d)", root, aLayer, aLayer->uniqueId(), bounds.x(), bounds.y(), bounds.width(), bounds.height(), - position.x(), position.y(), translation.x(), translation.y(), - result.x(), result.y(), result.width(), result.height(), - mOffset.x(), mOffset.y()); - result.move(-mOffset.x(), -mOffset.y()); + translation.x(), translation.y(), mOffset.x(), mOffset.y(), + clip.x(), clip.y(), clip.width(), clip.height(), + result.x(), result.y(), result.width(), result.height()); return result; } +IntRect CachedLayer::unadjustBounds(const LayerAndroid* root, + const IntRect& bounds) const +{ + const LayerAndroid* aLayer = layer(root); + if (!aLayer) + return bounds; + + IntRect temp = bounds; + // Remove the new position (i.e. fixed position elements). + const FloatPoint& position = aLayer->getPosition(); + temp.move(-position.x(), -position.y()); + + // Remove any layer translation. + const FloatPoint& translation = aLayer->translation(); + temp.move(-translation.x(), -translation.y()); + + // Move the bounds by the internal scroll position. + const SkPoint& scroll = aLayer->scrollPosition(); + temp.move(SkScalarRound(scroll.fX), SkScalarRound(scroll.fY)); + + // Move it back to the original offset. + temp.move(mOffset.x(), mOffset.y()); + return temp; +} + const LayerAndroid* CachedLayer::layer(const LayerAndroid* root) const { if (!root || mLayer) @@ -71,11 +115,26 @@ const LayerAndroid* CachedLayer::layer(const LayerAndroid* root) const } // return bounds relative to enclosing layer as recorded when walking the dom -IntRect CachedLayer::localBounds(const IntRect& bounds) const +IntRect CachedLayer::localBounds(const LayerAndroid* root, + const IntRect& bounds) const { IntRect temp = bounds; + // Remove the original offset from the bounds. temp.move(-mOffset.x(), -mOffset.y()); - return temp; + + const LayerAndroid* aLayer = layer(root); + if (aLayer) { + // Move the bounds by the scroll position of the layer. + const SkPoint& scroll = aLayer->scrollPosition(); + temp.move(SkScalarToFloat(-scroll.fX), SkScalarToFloat(-scroll.fY)); + + // Clip by the layer's foreground bounds. Since the bounds have + // already be moved local to the layer, no need to move the foreground + // clip. + temp.intersect(IntRect(aLayer->foregroundClip())); + } + + return enclosingIntRect(temp); } SkPicture* CachedLayer::picture(const LayerAndroid* root) const diff --git a/WebKit/android/nav/CachedLayer.h b/WebKit/android/nav/CachedLayer.h index c802407..8bfe922 100644 --- a/WebKit/android/nav/CachedLayer.h +++ b/WebKit/android/nav/CachedLayer.h @@ -47,10 +47,13 @@ public: } // FIXME: adjustBounds should be renamed globalBounds or toGlobal IntRect adjustBounds(const LayerAndroid* root, const IntRect& bounds) const; + // Moves the bounds by the layer's scroll position. Assumes the incoming + // bounds have been adjusted by adjustBounds. + IntRect unadjustBounds(const LayerAndroid* root, + const IntRect& bounds) const; int cachedNodeIndex() const { return mCachedNodeIndex; } - const IntPoint& getOffset() const { return mOffset; } const LayerAndroid* layer(const LayerAndroid* root) const; - IntRect localBounds(const IntRect& bounds) const; + IntRect localBounds(const LayerAndroid* root, const IntRect& bounds) const; SkPicture* picture(const LayerAndroid* root) const; void reset() { mLayer = 0; } void setCachedNodeIndex(int index) { mCachedNodeIndex = index; } diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp index 2d37a2a..6016d28 100644 --- a/WebKit/android/nav/CachedRoot.cpp +++ b/WebKit/android/nav/CachedRoot.cpp @@ -999,7 +999,9 @@ void CachedRoot::innerMove(const CachedNode* node, BestData* bestData, if (bestData->mNode != NULL) { mHistory->addToVisited(bestData->mNode, direction); mHistory->mNavBounds = bestData->bounds(); - mHistory->mMouseBounds = bestData->mouseBounds(); + mHistory->mMouseBounds = + cursorFrame->unadjustBounds(bestData->mNode, + bestData->mouseBounds()); } else if (scroll->x() != 0 || scroll->y() != 0) { WebCore::IntRect newBounds = mHistory->mNavBounds; int offsetX = scroll->x(); diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index aad3501..9108fdb 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -385,7 +385,7 @@ void drawCursorPostamble() if (time < m_ringAnimationEnd) { // views assume that inval bounds coordinates are non-negative WebCore::IntRect invalBounds(0, 0, INT_MAX, INT_MAX); - invalBounds.intersect(m_ring.m_bounds); + invalBounds.intersect(m_ring.m_absBounds); postInvalidateDelayed(m_ringAnimationEnd - time, invalBounds); } else { if (m_ring.m_followedLink) @@ -829,7 +829,8 @@ void selectBestAt(const WebCore::IntRect& rect) root->setCursor(0, 0); } else { DBG_NAV_LOGD("CachedNode:%p (%d)", node, node->index()); - root->rootHistory()->setMouseBounds(node->bounds(frame)); + WebCore::IntRect bounds = node->bounds(frame); + root->rootHistory()->setMouseBounds(frame->unadjustBounds(node, bounds)); m_viewImpl->updateCursorBounds(root, frame, node); root->setCursor(const_cast<CachedFrame*>(frame), const_cast<CachedNode*>(node)); @@ -897,6 +898,8 @@ bool motionUp(int x, int y, int slop) } DBG_NAV_LOGD("CachedNode:%p (%d) x=%d y=%d rx=%d ry=%d", result, result->index(), x, y, rx, ry); + // No need to call unadjustBounds below. rx and ry are already adjusted to + // the absolute position of the node. WebCore::IntRect navBounds = WebCore::IntRect(rx, ry, 1, 1); setNavBounds(navBounds); root->rootHistory()->setMouseBounds(navBounds); @@ -1965,7 +1968,7 @@ static bool nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj) if (!next) return false; const WebCore::IntRect& bounds = next->bounds(frame); - root->rootHistory()->setMouseBounds(bounds); + root->rootHistory()->setMouseBounds(frame->unadjustBounds(next, bounds)); view->getWebViewCore()->updateCursorBounds(root, frame, next); root->setCursor(const_cast<CachedFrame*>(frame), const_cast<CachedNode*>(next)); |