| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/input/GestureManager.h" | 5 #include "core/input/GestureManager.h" |
| 6 | 6 |
| 7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
| 8 #include "core/editing/SelectionController.h" | 8 #include "core/editing/SelectionController.h" |
| 9 #include "core/events/GestureEvent.h" | 9 #include "core/events/GestureEvent.h" |
| 10 #include "core/frame/FrameHost.h" | 10 #include "core/frame/FrameHost.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 } | 46 } |
| 47 | 47 |
| 48 HitTestRequest::HitTestRequestType GestureManager::getHitTypeForGestureType( | 48 HitTestRequest::HitTestRequestType GestureManager::getHitTypeForGestureType( |
| 49 PlatformEvent::EventType type) { | 49 PlatformEvent::EventType type) { |
| 50 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent; | 50 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent; |
| 51 switch (type) { | 51 switch (type) { |
| 52 case PlatformEvent::GestureShowPress: | 52 case PlatformEvent::GestureShowPress: |
| 53 case PlatformEvent::GestureTapUnconfirmed: | 53 case PlatformEvent::GestureTapUnconfirmed: |
| 54 return hitType | HitTestRequest::Active; | 54 return hitType | HitTestRequest::Active; |
| 55 case PlatformEvent::GestureTapDownCancel: | 55 case PlatformEvent::GestureTapDownCancel: |
| 56 // A TapDownCancel received when no element is active shouldn't really be
changing hover state. | 56 // A TapDownCancel received when no element is active shouldn't really be |
| 57 // changing hover state. |
| 57 if (!m_frame->document()->activeHoverElement()) | 58 if (!m_frame->document()->activeHoverElement()) |
| 58 hitType |= HitTestRequest::ReadOnly; | 59 hitType |= HitTestRequest::ReadOnly; |
| 59 return hitType | HitTestRequest::Release; | 60 return hitType | HitTestRequest::Release; |
| 60 case PlatformEvent::GestureTap: | 61 case PlatformEvent::GestureTap: |
| 61 return hitType | HitTestRequest::Release; | 62 return hitType | HitTestRequest::Release; |
| 62 case PlatformEvent::GestureTapDown: | 63 case PlatformEvent::GestureTapDown: |
| 63 case PlatformEvent::GestureLongPress: | 64 case PlatformEvent::GestureLongPress: |
| 64 case PlatformEvent::GestureLongTap: | 65 case PlatformEvent::GestureLongTap: |
| 65 case PlatformEvent::GestureTwoFingerTap: | 66 case PlatformEvent::GestureTwoFingerTap: |
| 66 // FIXME: Shouldn't LongTap and TwoFingerTap clear the Active state? | 67 // FIXME: Shouldn't LongTap and TwoFingerTap clear the Active state? |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); | 136 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); |
| 136 HitTestRequest::HitTestRequestType hitType = | 137 HitTestRequest::HitTestRequestType hitType = |
| 137 getHitTypeForGestureType(gestureEvent.type()); | 138 getHitTypeForGestureType(gestureEvent.type()); |
| 138 uint64_t preDispatchDomTreeVersion = m_frame->document()->domTreeVersion(); | 139 uint64_t preDispatchDomTreeVersion = m_frame->document()->domTreeVersion(); |
| 139 uint64_t preDispatchStyleVersion = m_frame->document()->styleVersion(); | 140 uint64_t preDispatchStyleVersion = m_frame->document()->styleVersion(); |
| 140 | 141 |
| 141 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); | 142 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); |
| 142 | 143 |
| 143 HitTestResult currentHitTest = targetedEvent.hitTestResult(); | 144 HitTestResult currentHitTest = targetedEvent.hitTestResult(); |
| 144 | 145 |
| 145 // We use the adjusted position so the application isn't surprised to see a ev
ent with | 146 // We use the adjusted position so the application isn't surprised to see a |
| 146 // co-ordinates outside the target's bounds. | 147 // event with co-ordinates outside the target's bounds. |
| 147 IntPoint adjustedPoint = | 148 IntPoint adjustedPoint = |
| 148 frameView->rootFrameToContents(gestureEvent.position()); | 149 frameView->rootFrameToContents(gestureEvent.position()); |
| 149 | 150 |
| 150 const unsigned modifiers = gestureEvent.getModifiers(); | 151 const unsigned modifiers = gestureEvent.getModifiers(); |
| 151 | 152 |
| 152 if (!m_suppressMouseEventsFromGestures) { | 153 if (!m_suppressMouseEventsFromGestures) { |
| 153 PlatformMouseEvent fakeMouseMove( | 154 PlatformMouseEvent fakeMouseMove( |
| 154 gestureEvent.position(), gestureEvent.globalPosition(), | 155 gestureEvent.position(), gestureEvent.globalPosition(), |
| 155 WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, | 156 WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, |
| 156 /* clickCount */ 0, static_cast<PlatformEvent::Modifiers>(modifiers), | 157 /* clickCount */ 0, static_cast<PlatformEvent::Modifiers>(modifiers), |
| 157 PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), | 158 PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), |
| 158 WebPointerProperties::PointerType::Mouse); | 159 WebPointerProperties::PointerType::Mouse); |
| 159 m_mouseEventManager->setMousePositionAndDispatchMouseEvent( | 160 m_mouseEventManager->setMousePositionAndDispatchMouseEvent( |
| 160 currentHitTest.innerNode(), EventTypeNames::mousemove, fakeMouseMove); | 161 currentHitTest.innerNode(), EventTypeNames::mousemove, fakeMouseMove); |
| 161 } | 162 } |
| 162 | 163 |
| 163 // Do a new hit-test in case the mousemove event changed the DOM. | 164 // Do a new hit-test in case the mousemove event changed the DOM. |
| 164 // Note that if the original hit test wasn't over an element (eg. was over a s
crollbar) we | 165 // Note that if the original hit test wasn't over an element (eg. was over a |
| 165 // don't want to re-hit-test because it may be in the wrong frame (and there's
no way the page | 166 // scrollbar) we don't want to re-hit-test because it may be in the wrong |
| 166 // could have seen the event anyway). | 167 // frame (and there's no way the page could have seen the event anyway). Also |
| 167 // Also note that the position of the frame may have changed, so we need to re
compute the content | 168 // note that the position of the frame may have changed, so we need to |
| 168 // co-ordinates (updating layout/style as hitTestResultAtPoint normally would)
. | 169 // recompute the content co-ordinates (updating layout/style as |
| 169 // FIXME: Use a hit-test cache to avoid unnecessary hit tests. http://crbug.co
m/398920 | 170 // hitTestResultAtPoint normally would). |
| 171 // FIXME: Use a hit-test cache to avoid unnecessary hit tests. |
| 172 // http://crbug.com/398920 |
| 170 if (currentHitTest.innerNode()) { | 173 if (currentHitTest.innerNode()) { |
| 171 LocalFrame* mainFrame = m_frame->localFrameRoot(); | 174 LocalFrame* mainFrame = m_frame->localFrameRoot(); |
| 172 if (mainFrame && mainFrame->view()) | 175 if (mainFrame && mainFrame->view()) |
| 173 mainFrame->view()->updateLifecycleToCompositingCleanPlusScrolling(); | 176 mainFrame->view()->updateLifecycleToCompositingCleanPlusScrolling(); |
| 174 adjustedPoint = frameView->rootFrameToContents(gestureEvent.position()); | 177 adjustedPoint = frameView->rootFrameToContents(gestureEvent.position()); |
| 175 currentHitTest = EventHandlingUtil::hitTestResultInFrame( | 178 currentHitTest = EventHandlingUtil::hitTestResultInFrame( |
| 176 m_frame, adjustedPoint, hitType); | 179 m_frame, adjustedPoint, hitType); |
| 177 } | 180 } |
| 178 | 181 |
| 179 // Capture data for showUnhandledTapUIIfNeeded. | 182 // Capture data for showUnhandledTapUIIfNeeded. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 MouseEventWithHitTestResults(fakeMouseDown, currentHitTest)); | 218 MouseEventWithHitTestResults(fakeMouseDown, currentHitTest)); |
| 216 } | 219 } |
| 217 | 220 |
| 218 if (currentHitTest.innerNode()) { | 221 if (currentHitTest.innerNode()) { |
| 219 DCHECK(gestureEvent.type() == PlatformEvent::GestureTap); | 222 DCHECK(gestureEvent.type() == PlatformEvent::GestureTap); |
| 220 HitTestResult result = currentHitTest; | 223 HitTestResult result = currentHitTest; |
| 221 result.setToShadowHostIfInUserAgentShadowRoot(); | 224 result.setToShadowHostIfInUserAgentShadowRoot(); |
| 222 m_frame->chromeClient().onMouseDown(result.innerNode()); | 225 m_frame->chromeClient().onMouseDown(result.innerNode()); |
| 223 } | 226 } |
| 224 | 227 |
| 225 // FIXME: Use a hit-test cache to avoid unnecessary hit tests. http://crbug.co
m/398920 | 228 // FIXME: Use a hit-test cache to avoid unnecessary hit tests. |
| 229 // http://crbug.com/398920 |
| 226 if (currentHitTest.innerNode()) { | 230 if (currentHitTest.innerNode()) { |
| 227 LocalFrame* mainFrame = m_frame->localFrameRoot(); | 231 LocalFrame* mainFrame = m_frame->localFrameRoot(); |
| 228 if (mainFrame && mainFrame->view()) | 232 if (mainFrame && mainFrame->view()) |
| 229 mainFrame->view()->updateAllLifecyclePhases(); | 233 mainFrame->view()->updateAllLifecyclePhases(); |
| 230 adjustedPoint = frameView->rootFrameToContents(gestureEvent.position()); | 234 adjustedPoint = frameView->rootFrameToContents(gestureEvent.position()); |
| 231 currentHitTest = EventHandlingUtil::hitTestResultInFrame( | 235 currentHitTest = EventHandlingUtil::hitTestResultInFrame( |
| 232 m_frame, adjustedPoint, hitType); | 236 m_frame, adjustedPoint, hitType); |
| 233 } | 237 } |
| 234 | 238 |
| 235 PlatformMouseEvent fakeMouseUp( | 239 PlatformMouseEvent fakeMouseUp( |
| 236 gestureEvent.position(), gestureEvent.globalPosition(), | 240 gestureEvent.position(), gestureEvent.globalPosition(), |
| 237 WebPointerProperties::Button::Left, PlatformEvent::MouseReleased, | 241 WebPointerProperties::Button::Left, PlatformEvent::MouseReleased, |
| 238 gestureEvent.tapCount(), static_cast<PlatformEvent::Modifiers>(modifiers), | 242 gestureEvent.tapCount(), static_cast<PlatformEvent::Modifiers>(modifiers), |
| 239 PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), | 243 PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), |
| 240 WebPointerProperties::PointerType::Mouse); | 244 WebPointerProperties::PointerType::Mouse); |
| 241 WebInputEventResult mouseUpEventResult = | 245 WebInputEventResult mouseUpEventResult = |
| 242 m_suppressMouseEventsFromGestures | 246 m_suppressMouseEventsFromGestures |
| 243 ? WebInputEventResult::HandledSuppressed | 247 ? WebInputEventResult::HandledSuppressed |
| 244 : m_mouseEventManager->setMousePositionAndDispatchMouseEvent( | 248 : m_mouseEventManager->setMousePositionAndDispatchMouseEvent( |
| 245 currentHitTest.innerNode(), EventTypeNames::mouseup, | 249 currentHitTest.innerNode(), EventTypeNames::mouseup, |
| 246 fakeMouseUp); | 250 fakeMouseUp); |
| 247 | 251 |
| 248 WebInputEventResult clickEventResult = WebInputEventResult::NotHandled; | 252 WebInputEventResult clickEventResult = WebInputEventResult::NotHandled; |
| 249 if (tappedNonTextNode) { | 253 if (tappedNonTextNode) { |
| 250 if (currentHitTest.innerNode()) { | 254 if (currentHitTest.innerNode()) { |
| 251 // Updates distribution because a mouseup (or mousedown) event listener ca
n make the | 255 // Updates distribution because a mouseup (or mousedown) event listener |
| 252 // tree dirty at dispatchMouseEvent() invocation above. | 256 // can make the tree dirty at dispatchMouseEvent() invocation above. |
| 253 // Unless distribution is updated, commonAncestor would hit DCHECK. | 257 // Unless distribution is updated, commonAncestor would hit DCHECK. Both |
| 254 // Both tappedNonTextNode and currentHitTest.innerNode()) don't need to be
updated | 258 // tappedNonTextNode and currentHitTest.innerNode()) don't need to be |
| 255 // because commonAncestor() will exit early if their documents are differe
nt. | 259 // updated because commonAncestor() will exit early if their documents are |
| 260 // different. |
| 256 tappedNonTextNode->updateDistribution(); | 261 tappedNonTextNode->updateDistribution(); |
| 257 Node* clickTargetNode = currentHitTest.innerNode()->commonAncestor( | 262 Node* clickTargetNode = currentHitTest.innerNode()->commonAncestor( |
| 258 *tappedNonTextNode, EventHandlingUtil::parentForClickEvent); | 263 *tappedNonTextNode, EventHandlingUtil::parentForClickEvent); |
| 259 clickEventResult = | 264 clickEventResult = |
| 260 m_mouseEventManager->setMousePositionAndDispatchMouseEvent( | 265 m_mouseEventManager->setMousePositionAndDispatchMouseEvent( |
| 261 clickTargetNode, EventTypeNames::click, fakeMouseUp); | 266 clickTargetNode, EventTypeNames::click, fakeMouseUp); |
| 262 } | 267 } |
| 263 m_mouseEventManager->setClickNode(nullptr); | 268 m_mouseEventManager->setClickNode(nullptr); |
| 264 } | 269 } |
| 265 | 270 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 284 m_frame->chromeClient().showUnhandledTapUIIfNeeded( | 289 m_frame->chromeClient().showUnhandledTapUIIfNeeded( |
| 285 tappedPositionInViewport, tappedNode, domTreeChanged || styleChanged); | 290 tappedPositionInViewport, tappedNode, domTreeChanged || styleChanged); |
| 286 } | 291 } |
| 287 return eventResult; | 292 return eventResult; |
| 288 } | 293 } |
| 289 | 294 |
| 290 WebInputEventResult GestureManager::handleGestureLongPress( | 295 WebInputEventResult GestureManager::handleGestureLongPress( |
| 291 const GestureEventWithHitTestResults& targetedEvent) { | 296 const GestureEventWithHitTestResults& targetedEvent) { |
| 292 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); | 297 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); |
| 293 | 298 |
| 294 // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests h
ere (re-using the | 299 // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests |
| 295 // supplied HitTestResult), but that will require some overhaul of the touch d
rag-and-drop code | 300 // here (re-using the supplied HitTestResult), but that will require some |
| 296 // and LongPress is such a special scenario that it's unlikely to matter much
in practice. | 301 // overhaul of the touch drag-and-drop code and LongPress is such a special |
| 302 // scenario that it's unlikely to matter much in practice. |
| 297 | 303 |
| 298 IntPoint hitTestPoint = | 304 IntPoint hitTestPoint = |
| 299 m_frame->view()->rootFrameToContents(gestureEvent.position()); | 305 m_frame->view()->rootFrameToContents(gestureEvent.position()); |
| 300 HitTestResult hitTestResult = | 306 HitTestResult hitTestResult = |
| 301 m_frame->eventHandler().hitTestResultAtPoint(hitTestPoint); | 307 m_frame->eventHandler().hitTestResultAtPoint(hitTestPoint); |
| 302 | 308 |
| 303 m_longTapShouldInvokeContextMenu = false; | 309 m_longTapShouldInvokeContextMenu = false; |
| 304 bool hitTestContainsLinks = hitTestResult.URLElement() || | 310 bool hitTestContainsLinks = hitTestResult.URLElement() || |
| 305 !hitTestResult.absoluteImageURL().isNull() || | 311 !hitTestResult.absoluteImageURL().isNull() || |
| 306 !hitTestResult.absoluteMediaURL().isNull(); | 312 !hitTestResult.absoluteMediaURL().isNull(); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 return nullptr; | 418 return nullptr; |
| 413 | 419 |
| 414 return &m_frame->page()->frameHost(); | 420 return &m_frame->page()->frameHost(); |
| 415 } | 421 } |
| 416 | 422 |
| 417 double GestureManager::getLastShowPressTimestamp() const { | 423 double GestureManager::getLastShowPressTimestamp() const { |
| 418 return m_lastShowPressTimestamp; | 424 return m_lastShowPressTimestamp; |
| 419 } | 425 } |
| 420 | 426 |
| 421 } // namespace blink | 427 } // namespace blink |
| OLD | NEW |