| 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/PointerEventManager.h" | 5 #include "core/input/PointerEventManager.h" |
| 6 | 6 |
| 7 #include "core/dom/DocumentUserGestureToken.h" | 7 #include "core/dom/DocumentUserGestureToken.h" |
| 8 #include "core/dom/ElementTraversal.h" | 8 #include "core/dom/ElementTraversal.h" |
| 9 #include "core/dom/shadow/FlatTreeTraversal.h" | 9 #include "core/dom/shadow/FlatTreeTraversal.h" |
| 10 #include "core/events/MouseEvent.h" | 10 #include "core/events/MouseEvent.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "platform/PlatformTouchEvent.h" | 21 #include "platform/PlatformTouchEvent.h" |
| 22 | 22 |
| 23 namespace blink { | 23 namespace blink { |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 size_t toPointerTypeIndex(WebPointerProperties::PointerType t) { | 27 size_t toPointerTypeIndex(WebPointerProperties::PointerType t) { |
| 28 return static_cast<size_t>(t); | 28 return static_cast<size_t>(t); |
| 29 } | 29 } |
| 30 | 30 |
| 31 const AtomicString& pointerEventNameForTouchPointState( | |
| 32 PlatformTouchPoint::TouchState state) { | |
| 33 switch (state) { | |
| 34 case PlatformTouchPoint::TouchReleased: | |
| 35 return EventTypeNames::pointerup; | |
| 36 case PlatformTouchPoint::TouchCancelled: | |
| 37 return EventTypeNames::pointercancel; | |
| 38 case PlatformTouchPoint::TouchPressed: | |
| 39 return EventTypeNames::pointerdown; | |
| 40 case PlatformTouchPoint::TouchMoved: | |
| 41 return EventTypeNames::pointermove; | |
| 42 case PlatformTouchPoint::TouchStationary: | |
| 43 // Fall through to default | |
| 44 default: | |
| 45 NOTREACHED(); | |
| 46 return emptyAtom; | |
| 47 } | |
| 48 } | |
| 49 | |
| 50 bool isInDocument(EventTarget* n) { | 31 bool isInDocument(EventTarget* n) { |
| 51 return n && n->toNode() && n->toNode()->isConnected(); | 32 return n && n->toNode() && n->toNode()->isConnected(); |
| 52 } | 33 } |
| 53 | 34 |
| 35 Vector<PlatformTouchPoint> getCoalescedPoints( |
| 36 const Vector<PlatformTouchEvent>& coalescedEvents, |
| 37 int id) { |
| 38 Vector<PlatformTouchPoint> relatedPoints; |
| 39 for (const auto& touchEvent : coalescedEvents) { |
| 40 for (auto& point : touchEvent.touchPoints()) { |
| 41 // TODO(nzolghadr): Need to filter out stationary points |
| 42 if (point.id() == id) |
| 43 relatedPoints.append(point); |
| 44 } |
| 45 } |
| 46 return relatedPoints; |
| 47 } |
| 48 |
| 54 } // namespace | 49 } // namespace |
| 55 | 50 |
| 56 PointerEventManager::PointerEventManager(LocalFrame* frame, | 51 PointerEventManager::PointerEventManager(LocalFrame* frame, |
| 57 MouseEventManager* mouseEventManager) | 52 MouseEventManager* mouseEventManager) |
| 58 : m_frame(frame), | 53 : m_frame(frame), |
| 59 m_touchEventManager(new TouchEventManager(frame)), | 54 m_touchEventManager(new TouchEventManager(frame)), |
| 60 m_mouseEventManager(mouseEventManager) { | 55 m_mouseEventManager(mouseEventManager) { |
| 61 clear(); | 56 clear(); |
| 62 } | 57 } |
| 63 | 58 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 return target; | 178 return target; |
| 184 } | 179 } |
| 185 | 180 |
| 186 void PointerEventManager::sendMouseAndPointerBoundaryEvents( | 181 void PointerEventManager::sendMouseAndPointerBoundaryEvents( |
| 187 Node* enteredNode, | 182 Node* enteredNode, |
| 188 const PlatformMouseEvent& mouseEvent) { | 183 const PlatformMouseEvent& mouseEvent) { |
| 189 // Mouse event type does not matter as this pointerevent will only be used | 184 // Mouse event type does not matter as this pointerevent will only be used |
| 190 // to create boundary pointer events and its type will be overridden in | 185 // to create boundary pointer events and its type will be overridden in |
| 191 // |sendBoundaryEvents| function. | 186 // |sendBoundaryEvents| function. |
| 192 PointerEvent* dummyPointerEvent = m_pointerEventFactory.create( | 187 PointerEvent* dummyPointerEvent = m_pointerEventFactory.create( |
| 193 EventTypeNames::mousedown, mouseEvent, m_frame->document()->domWindow()); | 188 EventTypeNames::mousedown, mouseEvent, Vector<PlatformMouseEvent>(), |
| 189 m_frame->document()->domWindow()); |
| 194 | 190 |
| 195 // TODO(crbug/545647): This state should reset with pointercancel too. | 191 // TODO(crbug/545647): This state should reset with pointercancel too. |
| 196 // This function also gets called for compat mouse events of touch at this | 192 // This function also gets called for compat mouse events of touch at this |
| 197 // stage. So if the event is not frame boundary transition it is only a | 193 // stage. So if the event is not frame boundary transition it is only a |
| 198 // compatibility mouse event and we do not need to change pointer event | 194 // compatibility mouse event and we do not need to change pointer event |
| 199 // behavior regarding preventMouseEvent state in that case. | 195 // behavior regarding preventMouseEvent state in that case. |
| 200 if (dummyPointerEvent->buttons() == 0 && dummyPointerEvent->isPrimary()) { | 196 if (dummyPointerEvent->buttons() == 0 && dummyPointerEvent->isPrimary()) { |
| 201 m_preventMouseEventForPointerType[toPointerTypeIndex( | 197 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 202 mouseEvent.pointerProperties().pointerType)] = false; | 198 mouseEvent.pointerProperties().pointerType)] = false; |
| 203 } | 199 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 | 276 |
| 281 removePointer(pointerEvent); | 277 removePointer(pointerEvent); |
| 282 } | 278 } |
| 283 } | 279 } |
| 284 | 280 |
| 285 void PointerEventManager::unblockTouchPointers() { | 281 void PointerEventManager::unblockTouchPointers() { |
| 286 m_inCanceledStateForPointerTypeTouch = false; | 282 m_inCanceledStateForPointerTypeTouch = false; |
| 287 } | 283 } |
| 288 | 284 |
| 289 WebInputEventResult PointerEventManager::handleTouchEvents( | 285 WebInputEventResult PointerEventManager::handleTouchEvents( |
| 290 const PlatformTouchEvent& event) { | 286 const PlatformTouchEvent& event, |
| 287 const Vector<PlatformTouchEvent>& coalescedEvents) { |
| 291 if (event.type() == PlatformEvent::TouchScrollStarted) { | 288 if (event.type() == PlatformEvent::TouchScrollStarted) { |
| 292 blockTouchPointers(); | 289 blockTouchPointers(); |
| 293 return WebInputEventResult::HandledSystem; | 290 return WebInputEventResult::HandledSystem; |
| 294 } | 291 } |
| 295 | 292 |
| 296 bool newTouchSequence = true; | 293 bool newTouchSequence = true; |
| 297 for (const auto& touchPoint : event.touchPoints()) { | 294 for (const auto& touchPoint : event.touchPoints()) { |
| 298 if (touchPoint.state() != PlatformTouchPoint::TouchPressed) { | 295 if (touchPoint.state() != PlatformTouchPoint::TouchPressed) { |
| 299 newTouchSequence = false; | 296 newTouchSequence = false; |
| 300 break; | 297 break; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 318 // associated with so just pick the first finger. | 315 // associated with so just pick the first finger. |
| 319 RefPtr<UserGestureToken> possibleGestureToken; | 316 RefPtr<UserGestureToken> possibleGestureToken; |
| 320 if (event.type() == PlatformEvent::TouchEnd && | 317 if (event.type() == PlatformEvent::TouchEnd && |
| 321 !m_inCanceledStateForPointerTypeTouch && !touchInfos.isEmpty() && | 318 !m_inCanceledStateForPointerTypeTouch && !touchInfos.isEmpty() && |
| 322 touchInfos[0].targetFrame) { | 319 touchInfos[0].targetFrame) { |
| 323 possibleGestureToken = | 320 possibleGestureToken = |
| 324 DocumentUserGestureToken::create(touchInfos[0].targetFrame->document()); | 321 DocumentUserGestureToken::create(touchInfos[0].targetFrame->document()); |
| 325 } | 322 } |
| 326 UserGestureIndicator holder(possibleGestureToken); | 323 UserGestureIndicator holder(possibleGestureToken); |
| 327 | 324 |
| 328 dispatchTouchPointerEvents(event, touchInfos); | 325 dispatchTouchPointerEvents(event, coalescedEvents, touchInfos); |
| 329 | 326 |
| 330 return m_touchEventManager->handleTouchEvent(event, touchInfos); | 327 return m_touchEventManager->handleTouchEvent(event, touchInfos); |
| 331 } | 328 } |
| 332 | 329 |
| 333 void PointerEventManager::computeTouchTargets( | 330 void PointerEventManager::computeTouchTargets( |
| 334 const PlatformTouchEvent& event, | 331 const PlatformTouchEvent& event, |
| 335 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { | 332 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { |
| 336 for (const auto& touchPoint : event.touchPoints()) { | 333 for (const auto& touchPoint : event.touchPoints()) { |
| 337 TouchEventManager::TouchInfo touchInfo; | 334 TouchEventManager::TouchInfo touchInfo; |
| 338 touchInfo.point = touchPoint; | 335 touchInfo.point = touchPoint; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 m_pendingPointerCaptureTarget.get(pointerId)->toNode(); | 379 m_pendingPointerCaptureTarget.get(pointerId)->toNode(); |
| 383 touchInfo.targetFrame = touchInfo.touchNode->document().frame(); | 380 touchInfo.targetFrame = touchInfo.touchNode->document().frame(); |
| 384 } | 381 } |
| 385 | 382 |
| 386 touchInfos.append(touchInfo); | 383 touchInfos.append(touchInfo); |
| 387 } | 384 } |
| 388 } | 385 } |
| 389 | 386 |
| 390 void PointerEventManager::dispatchTouchPointerEvents( | 387 void PointerEventManager::dispatchTouchPointerEvents( |
| 391 const PlatformTouchEvent& event, | 388 const PlatformTouchEvent& event, |
| 389 const Vector<PlatformTouchEvent>& coalescedEvents, |
| 392 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { | 390 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { |
| 393 // Iterate through the touch points, sending PointerEvents to the targets as | 391 // Iterate through the touch points, sending PointerEvents to the targets as |
| 394 // required. | 392 // required. |
| 395 for (auto touchInfo : touchInfos) { | 393 for (auto touchInfo : touchInfos) { |
| 396 const PlatformTouchPoint& touchPoint = touchInfo.point; | 394 const PlatformTouchPoint& touchPoint = touchInfo.point; |
| 397 // Do not send pointer events for stationary touches or null targetFrame | 395 // Do not send pointer events for stationary touches or null targetFrame |
| 398 if (touchInfo.touchNode && touchInfo.targetFrame && | 396 if (touchInfo.touchNode && touchInfo.targetFrame && |
| 399 touchPoint.state() != PlatformTouchPoint::TouchStationary && | 397 touchPoint.state() != PlatformTouchPoint::TouchStationary && |
| 400 !m_inCanceledStateForPointerTypeTouch) { | 398 !m_inCanceledStateForPointerTypeTouch) { |
| 401 FloatPoint pagePoint = touchInfo.targetFrame->view()->rootFrameToContents( | |
| 402 touchInfo.point.pos()); | |
| 403 float scaleFactor = 1.0f / touchInfo.targetFrame->pageZoomFactor(); | |
| 404 FloatPoint scrollPosition(touchInfo.targetFrame->view()->scrollOffset()); | |
| 405 FloatPoint framePoint = pagePoint.scaledBy(scaleFactor); | |
| 406 framePoint.moveBy(scrollPosition.scaledBy(-scaleFactor)); | |
| 407 PointerEvent* pointerEvent = m_pointerEventFactory.create( | 399 PointerEvent* pointerEvent = m_pointerEventFactory.create( |
| 408 pointerEventNameForTouchPointState(touchPoint.state()), touchPoint, | 400 touchPoint, getCoalescedPoints(coalescedEvents, touchPoint.id()), |
| 409 event.getModifiers(), touchPoint.radius().scaledBy(scaleFactor), | 401 event.getModifiers(), touchInfo.targetFrame, |
| 410 framePoint, | |
| 411 touchInfo.touchNode ? touchInfo.touchNode->document().domWindow() | 402 touchInfo.touchNode ? touchInfo.touchNode->document().domWindow() |
| 412 : nullptr); | 403 : nullptr); |
| 413 | 404 |
| 414 WebInputEventResult result = | 405 WebInputEventResult result = |
| 415 sendTouchPointerEvent(touchInfo.touchNode, pointerEvent); | 406 sendTouchPointerEvent(touchInfo.touchNode, pointerEvent); |
| 416 | 407 |
| 417 // If a pointerdown has been canceled, queue the unique id to allow | 408 // If a pointerdown has been canceled, queue the unique id to allow |
| 418 // suppressing mouse events from gesture events. For mouse events | 409 // suppressing mouse events from gesture events. For mouse events |
| 419 // fired from GestureTap & GestureLongPress (which are triggered by | 410 // fired from GestureTap & GestureLongPress (which are triggered by |
| 420 // single touches only), it is enough to queue the ids only for | 411 // single touches only), it is enough to queue the ids only for |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 | 447 |
| 457 removePointer(pointerEvent); | 448 removePointer(pointerEvent); |
| 458 } | 449 } |
| 459 | 450 |
| 460 return result; | 451 return result; |
| 461 } | 452 } |
| 462 | 453 |
| 463 WebInputEventResult PointerEventManager::sendMousePointerEvent( | 454 WebInputEventResult PointerEventManager::sendMousePointerEvent( |
| 464 Node* target, | 455 Node* target, |
| 465 const AtomicString& mouseEventType, | 456 const AtomicString& mouseEventType, |
| 466 const PlatformMouseEvent& mouseEvent) { | 457 const PlatformMouseEvent& mouseEvent, |
| 467 PointerEvent* pointerEvent = m_pointerEventFactory.create( | 458 const Vector<PlatformMouseEvent>& coalescedEvents) { |
| 468 mouseEventType, mouseEvent, m_frame->document()->domWindow()); | 459 PointerEvent* pointerEvent = |
| 460 m_pointerEventFactory.create(mouseEventType, mouseEvent, coalescedEvents, |
| 461 m_frame->document()->domWindow()); |
| 469 | 462 |
| 470 // This is for when the mouse is released outside of the page. | 463 // This is for when the mouse is released outside of the page. |
| 471 if (pointerEvent->type() == EventTypeNames::pointermove && | 464 if (pointerEvent->type() == EventTypeNames::pointermove && |
| 472 !pointerEvent->buttons()) { | 465 !pointerEvent->buttons()) { |
| 473 releasePointerCapture(pointerEvent->pointerId()); | 466 releasePointerCapture(pointerEvent->pointerId()); |
| 474 // Send got/lostpointercapture rightaway if necessary. | 467 // Send got/lostpointercapture rightaway if necessary. |
| 475 processPendingPointerCapture(pointerEvent); | 468 processPendingPointerCapture(pointerEvent); |
| 476 | 469 |
| 477 if (pointerEvent->isPrimary()) { | 470 if (pointerEvent->isPrimary()) { |
| 478 m_preventMouseEventForPointerType[toPointerTypeIndex( | 471 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 return true; | 712 return true; |
| 720 } | 713 } |
| 721 return false; | 714 return false; |
| 722 } | 715 } |
| 723 | 716 |
| 724 EventTarget* PointerEventManager::getMouseCapturingNode() { | 717 EventTarget* PointerEventManager::getMouseCapturingNode() { |
| 725 return getCapturingNode(PointerEventFactory::s_mouseId); | 718 return getCapturingNode(PointerEventFactory::s_mouseId); |
| 726 } | 719 } |
| 727 | 720 |
| 728 } // namespace blink | 721 } // namespace blink |
| OLD | NEW |