From ed578c7d36371bb3f80576541888fb80a210e487 Mon Sep 17 00:00:00 2001 From: "commit-queue@webkit.org" Date: Thu, 2 Feb 2012 15:09:48 +0000 Subject: [PATCH] Source/WebCore: Update active and hover state on touch release. https://bugs.webkit.org/show_bug.cgi?id=77620 Patch by Allan Sandfeld Jensen on 2012-02-02 Reviewed by Kenneth Rohde Christiansen. * rendering/HitTestRequest.h: (WebCore::HitTestRequest::move): (WebCore::HitTestRequest::release): (WebCore::HitTestRequest::touchEvent): (WebCore::HitTestRequest::mouseEvent): (WebCore::HitTestRequest::touchMove): (WebCore::HitTestRequest::touchRelease): Rename the enum values in HitTestRequest to be mouse/touch agnostic, and add value for recognizing touch events. * rendering/RenderFrameSet.cpp: (WebCore::RenderFrameSet::nodeAtPoint): Update for HitTestRequest rename. * rendering/RenderLayer.cpp: (WebCore::RenderLayer::hitTest): ditto (WebCore::RenderLayer::updateHoverActiveState): Reset hoverstate on touch release. * page/EventHandler.cpp: (WebCore::EventHandler::updateSelectionForMouseDrag): Update for HitTestRequest rename. (WebCore::EventHandler::handleMouseMoveEvent): ditto (WebCore::EventHandler::handleMouseReleaseEvent): ditto (WebCore::EventHandler::hoverTimerFired): ditto (WebCore::EventHandler::dragSourceEndedAt): ditto (WebCore::EventHandler::handleTouchEvent): Hittest touch release to reset active and hover states and add touch enum to all touch hittests. Source/WebKit/chromium: Update enum name for HitTestRequest::RequestType https://bugs.webkit.org/show_bug.cgi?id=77620 Patch by Allan Sandfeld Jensen on 2012-02-02 Reviewed by Kenneth Rohde Christiansen. * src/WebFrameImpl.cpp: (WebKit::WebFrameImpl::visiblePositionForWindowPoint): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@106554 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebCore/ChangeLog | 30 +++++++++++++++++++++++++++++ Source/WebCore/page/EventHandler.cpp | 22 ++++++++++++--------- Source/WebCore/rendering/HitTestRequest.h | 18 ++++++++++++----- Source/WebCore/rendering/RenderFrameSet.cpp | 2 +- Source/WebCore/rendering/RenderLayer.cpp | 26 ++++++++++++++++++------- Source/WebKit/chromium/ChangeLog | 10 ++++++++++ Source/WebKit/chromium/src/WebFrameImpl.cpp | 2 +- 7 files changed, 87 insertions(+), 23 deletions(-) diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index c341d20..e596795 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,33 @@ +2012-02-02 Allan Sandfeld Jensen + + Update active and hover state on touch release. + https://bugs.webkit.org/show_bug.cgi?id=77620 + + Reviewed by Kenneth Rohde Christiansen. + + * rendering/HitTestRequest.h: + (WebCore::HitTestRequest::move): + (WebCore::HitTestRequest::release): + (WebCore::HitTestRequest::touchEvent): + (WebCore::HitTestRequest::mouseEvent): + (WebCore::HitTestRequest::touchMove): + (WebCore::HitTestRequest::touchRelease): + Rename the enum values in HitTestRequest to be mouse/touch + agnostic, and add value for recognizing touch events. + * rendering/RenderFrameSet.cpp: + (WebCore::RenderFrameSet::nodeAtPoint): Update for HitTestRequest rename. + * rendering/RenderLayer.cpp: + (WebCore::RenderLayer::hitTest): ditto + (WebCore::RenderLayer::updateHoverActiveState): Reset hoverstate on touch release. + * page/EventHandler.cpp: + (WebCore::EventHandler::updateSelectionForMouseDrag): Update for HitTestRequest rename. + (WebCore::EventHandler::handleMouseMoveEvent): ditto + (WebCore::EventHandler::handleMouseReleaseEvent): ditto + (WebCore::EventHandler::hoverTimerFired): ditto + (WebCore::EventHandler::dragSourceEndedAt): ditto + (WebCore::EventHandler::handleTouchEvent): Hittest touch release to reset + active and hover states and add touch enum to all touch hittests. + 2012-02-02 Pavel Feldman Web Inspector: enable editing of selected rows on single click in elements panel. diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp index 4ab1833..a2f322e 100644 --- a/Source/WebCore/page/EventHandler.cpp +++ b/Source/WebCore/page/EventHandler.cpp @@ -646,7 +646,7 @@ void EventHandler::updateSelectionForMouseDrag() HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | - HitTestRequest::MouseMove); + HitTestRequest::Move); HitTestResult result(view->windowToContents(m_currentMousePosition)); layer->hitTest(request, result); updateSelectionForMouseDrag(result); @@ -1620,7 +1620,7 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi if (m_lastScrollbarUnderMouse && m_mousePressed) return m_lastScrollbarUnderMouse->mouseMoved(mouseEvent); - HitTestRequest::HitTestRequestType hitType = HitTestRequest::MouseMove; + HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move; if (m_mousePressed) hitType |= HitTestRequest::Active; @@ -1727,7 +1727,7 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent) return m_lastScrollbarUnderMouse->mouseUp(mouseEvent); } - HitTestRequest request(HitTestRequest::MouseUp); + HitTestRequest request(HitTestRequest::Release); MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent); Frame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev); if (m_eventHandlerWillResetCapturingMouseEventsNode) @@ -2456,7 +2456,7 @@ void EventHandler::hoverTimerFired(Timer*) if (RenderView* renderer = m_frame->contentRenderer()) { if (FrameView* view = m_frame->view()) { - HitTestRequest request(HitTestRequest::MouseMove); + HitTestRequest request(HitTestRequest::Move); HitTestResult result(view->windowToContents(m_currentMousePosition)); renderer->layer()->hitTest(request, result); m_frame->document()->updateStyleIfNeeded(); @@ -2773,7 +2773,7 @@ void EventHandler::freeClipboard() void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation) { // Send a hit test request so that RenderLayer gets a chance to update the :hover and :active pseudoclasses. - HitTestRequest request(HitTestRequest::MouseUp); + HitTestRequest request(HitTestRequest::Release); prepareMouseEvent(request, event); if (dragState().m_dragSrc && dragState().shouldDispatchEvents()) { @@ -3232,7 +3232,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) PlatformTouchPoint::State pointState = point.state(); LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos()); - HitTestRequest::HitTestRequestType hitType = HitTestRequest::Active | HitTestRequest::ReadOnly; + HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent; // The HitTestRequest types used for mouse events map quite adequately // to touch events. Note that in addition to meaning that the hit test // should affect the active state of the current node if necessary, @@ -3240,16 +3240,17 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) // with the mouse (or finger in this case) being pressed. switch (pointState) { case PlatformTouchPoint::TouchPressed: - hitType = HitTestRequest::Active; + hitType |= HitTestRequest::Active; break; case PlatformTouchPoint::TouchMoved: - hitType = HitTestRequest::Active | HitTestRequest::MouseMove | HitTestRequest::ReadOnly; + hitType |= HitTestRequest::Active | HitTestRequest::Move | HitTestRequest::ReadOnly; break; case PlatformTouchPoint::TouchReleased: case PlatformTouchPoint::TouchCancelled: - hitType = HitTestRequest::MouseUp; + hitType |= HitTestRequest::Release; break; default: + ASSERT_NOT_REACHED(); break; } @@ -3274,10 +3275,13 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) m_originatingTouchPointTargets.set(touchPointTargetKey, node); touchTarget = node; } else if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) { + // We only perform a hittest on release or cancel to unset :active or :hover state. + hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false, false, DontHitTestScrollbars, hitType); // The target should be the original target for this touch, so get it from the hashmap. As it's a release or cancel // we also remove it from the map. touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey); } else + // No hittest is performed on move, since the target is not allowed to change anyway. touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey); if (!touchTarget.get()) diff --git a/Source/WebCore/rendering/HitTestRequest.h b/Source/WebCore/rendering/HitTestRequest.h index 1d0441d..e6a5231 100644 --- a/Source/WebCore/rendering/HitTestRequest.h +++ b/Source/WebCore/rendering/HitTestRequest.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Apple Computer, Inc. * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ + * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -29,10 +30,11 @@ public: enum RequestType { ReadOnly = 1 << 1, Active = 1 << 2, - MouseMove = 1 << 3, - MouseUp = 1 << 4, + Move = 1 << 3, + Release = 1 << 4, IgnoreClipping = 1 << 5, - SVGClipContent = 1 << 6 + SVGClipContent = 1 << 6, + TouchEvent = 1 << 7 }; typedef unsigned HitTestRequestType; @@ -44,10 +46,16 @@ public: bool readOnly() const { return m_requestType & ReadOnly; } bool active() const { return m_requestType & Active; } - bool mouseMove() const { return m_requestType & MouseMove; } - bool mouseUp() const { return m_requestType & MouseUp; } + bool move() const { return m_requestType & Move; } + bool release() const { return m_requestType & Release; } bool ignoreClipping() const { return m_requestType & IgnoreClipping; } bool svgClipContent() const { return m_requestType & SVGClipContent; } + bool touchEvent() const { return m_requestType & TouchEvent; } + bool mouseEvent() const { return !touchEvent(); } + + // Convenience functions + bool touchMove() const { return move() && touchEvent(); } + bool touchRelease() const { return release() && touchEvent(); } HitTestRequestType type() const { return m_requestType; } diff --git a/Source/WebCore/rendering/RenderFrameSet.cpp b/Source/WebCore/rendering/RenderFrameSet.cpp index 074f3ed..6b6d239 100644 --- a/Source/WebCore/rendering/RenderFrameSet.cpp +++ b/Source/WebCore/rendering/RenderFrameSet.cpp @@ -167,7 +167,7 @@ bool RenderFrameSet::nodeAtPoint(const HitTestRequest& request, HitTestResult& r || m_isResizing; if (inside && frameSet()->noResize() - && !request.readOnly() && !result.innerNode()) { + && !request.readOnly() && !result.innerNode() && !request.touchMove()) { result.setInnerNode(node()); result.setInnerNonSharedNode(node()); } diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp index 21aa3d3..d06b30d 100644 --- a/Source/WebCore/rendering/RenderLayer.cpp +++ b/Source/WebCore/rendering/RenderLayer.cpp @@ -3104,7 +3104,7 @@ bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result) // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down, // return ourselves. We do this so mouse events continue getting delivered after a drag has // exited the WebView, and so hit testing over a scrollbar hits the content document. - if ((request.active() || request.mouseUp()) && renderer()->isRenderView()) { + if ((request.active() || request.release()) && renderer()->isRenderView()) { renderer()->updateHitTestResult(result, result.point()); insideLayer = this; } @@ -4013,13 +4013,12 @@ void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestR doc->setActiveNode(0); } else { Node* newActiveNode = result.innerNode(); - if (!activeNode && newActiveNode && request.active()) { + if (!activeNode && newActiveNode && request.active() && !request.touchMove()) { // We are setting the :active chain and freezing it. If future moves happen, they // will need to reference this chain. for (RenderObject* curr = newActiveNode->renderer(); curr; curr = curr->parent()) { - if (curr->node() && !curr->isText()) { + if (curr->node() && !curr->isText()) curr->node()->setInActiveChain(); - } } doc->setActiveNode(newActiveNode); } @@ -4031,11 +4030,24 @@ void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestR // If the mouse is down and if this is a mouse move event, we want to restrict changes in // :hover/:active to only apply to elements that are in the :active chain that we froze // at the time the mouse went down. - bool mustBeInActiveChain = request.active() && request.mouseMove(); + bool mustBeInActiveChain = request.active() && request.move(); - // Check to see if the hovered node has changed. If not, then we don't need to - // do anything. RefPtr oldHoverNode = doc->hoverNode(); + // Clear the :hover chain when the touch gesture is over. + if (request.touchRelease()) { + if (oldHoverNode) { + for (RenderObject* curr = oldHoverNode->renderer(); curr; curr = curr->parent()) { + if (curr->node() && !curr->isText()) + curr->node()->setHovered(false); + } + doc->setHoverNode(0); + } + // A touch release can not set new hover or active target. + return; + } + + // Check to see if the hovered node has changed. + // If it hasn't, we do not need to do anything. Node* newHoverNode = result.innerNode(); if (newHoverNode && !newHoverNode->renderer()) newHoverNode = result.innerNonSharedNode(); diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog index 323c429..c47d6ae 100644 --- a/Source/WebKit/chromium/ChangeLog +++ b/Source/WebKit/chromium/ChangeLog @@ -1,3 +1,13 @@ +2012-02-02 Allan Sandfeld Jensen + + Update enum name for HitTestRequest::RequestType + https://bugs.webkit.org/show_bug.cgi?id=77620 + + Reviewed by Kenneth Rohde Christiansen. + + * src/WebFrameImpl.cpp: + (WebKit::WebFrameImpl::visiblePositionForWindowPoint): + 2012-02-02 Kinuko Yasuda Cleanup: Move chrome-specific filesystem type handling code (for FileSystem API) under chromium directory (re-landing r105395) diff --git a/Source/WebKit/chromium/src/WebFrameImpl.cpp b/Source/WebKit/chromium/src/WebFrameImpl.cpp index 9163e2e..2524cf4 100644 --- a/Source/WebKit/chromium/src/WebFrameImpl.cpp +++ b/Source/WebKit/chromium/src/WebFrameImpl.cpp @@ -1384,7 +1384,7 @@ void WebFrameImpl::selectRange(const WebPoint& start, const WebPoint& end) VisiblePosition WebFrameImpl::visiblePositionForWindowPoint(const WebPoint& point) { - HitTestRequest::HitTestRequestType hitType = HitTestRequest::MouseMove; + HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move; hitType |= HitTestRequest::ReadOnly; hitType |= HitTestRequest::Active; HitTestRequest request(hitType); -- 2.7.4