Source/WebCore: Update active and hover state on touch release.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Feb 2012 15:09:48 +0000 (15:09 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Feb 2012 15:09:48 +0000 (15:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=77620

Patch by Allan Sandfeld Jensen <allan.jensen@nokia.com> 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 <allan.jensen@nokia.com> 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
Source/WebCore/page/EventHandler.cpp
Source/WebCore/rendering/HitTestRequest.h
Source/WebCore/rendering/RenderFrameSet.cpp
Source/WebCore/rendering/RenderLayer.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/WebFrameImpl.cpp

index c341d20..e596795 100644 (file)
@@ -1,3 +1,33 @@
+2012-02-02  Allan Sandfeld Jensen  <allan.jensen@nokia.com>
+
+        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  <pfeldman@google.com>
 
         Web Inspector: enable editing of selected rows on single click in elements panel.
index 4ab1833..a2f322e 100644 (file)
@@ -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<EventHandler>*)
 
     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())
index 1d0441d..e6a5231 100644 (file)
@@ -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; }
 
index 074f3ed..6b6d239 100644 (file)
@@ -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());
     }
index 21aa3d3..d06b30d 100644 (file)
@@ -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<Node> 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();
index 323c429..c47d6ae 100644 (file)
@@ -1,3 +1,13 @@
+2012-02-02  Allan Sandfeld Jensen  <allan.jensen@nokia.com>
+
+        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  <kinuko@chromium.org>
 
         Cleanup: Move chrome-specific filesystem type handling code (for FileSystem API) under chromium directory (re-landing r105395)
index 9163e2e..2524cf4 100644 (file)
@@ -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);