| 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/ElementTraversal.h" | 7 #include "core/dom/ElementTraversal.h" |
| 8 #include "core/dom/shadow/FlatTreeTraversal.h" | 8 #include "core/dom/shadow/FlatTreeTraversal.h" |
| 9 #include "core/events/MouseEvent.h" | 9 #include "core/events/MouseEvent.h" |
| 10 #include "core/frame/FrameView.h" | 10 #include "core/frame/FrameView.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 return emptyAtom; | 45 return emptyAtom; |
| 46 } | 46 } |
| 47 } | 47 } |
| 48 | 48 |
| 49 bool isInDocument(EventTarget* n) { | 49 bool isInDocument(EventTarget* n) { |
| 50 return n && n->toNode() && n->toNode()->isConnected(); | 50 return n && n->toNode() && n->toNode()->isConnected(); |
| 51 } | 51 } |
| 52 | 52 |
| 53 } // namespace | 53 } // namespace |
| 54 | 54 |
| 55 PointerEventManager::PointerEventManager(LocalFrame* frame, |
| 56 MouseEventManager* mouseEventManager) |
| 57 : m_frame(frame), |
| 58 m_touchEventManager(new TouchEventManager(frame)), |
| 59 m_mouseEventManager(mouseEventManager) { |
| 60 clear(); |
| 61 } |
| 62 |
| 63 void PointerEventManager::clear() { |
| 64 for (auto& entry : m_preventMouseEventForPointerType) |
| 65 entry = false; |
| 66 m_touchEventManager->clear(); |
| 67 m_inCanceledStateForPointerTypeTouch = false; |
| 68 m_pointerEventFactory.clear(); |
| 69 m_touchIdsForCanceledPointerdowns.clear(); |
| 70 m_nodeUnderPointer.clear(); |
| 71 m_pointerCaptureTarget.clear(); |
| 72 m_pendingPointerCaptureTarget.clear(); |
| 73 } |
| 74 |
| 75 DEFINE_TRACE(PointerEventManager) { |
| 76 visitor->trace(m_frame); |
| 77 visitor->trace(m_nodeUnderPointer); |
| 78 visitor->trace(m_pointerCaptureTarget); |
| 79 visitor->trace(m_pendingPointerCaptureTarget); |
| 80 visitor->trace(m_touchEventManager); |
| 81 visitor->trace(m_mouseEventManager); |
| 82 } |
| 83 |
| 55 PointerEventManager::PointerEventBoundaryEventDispatcher:: | 84 PointerEventManager::PointerEventBoundaryEventDispatcher:: |
| 56 PointerEventBoundaryEventDispatcher( | 85 PointerEventBoundaryEventDispatcher( |
| 57 PointerEventManager* pointerEventManager, | 86 PointerEventManager* pointerEventManager, |
| 58 PointerEvent* pointerEvent) | 87 PointerEvent* pointerEvent) |
| 59 : m_pointerEventManager(pointerEventManager), | 88 : m_pointerEventManager(pointerEventManager), |
| 60 m_pointerEvent(pointerEvent) {} | 89 m_pointerEvent(pointerEvent) {} |
| 61 | 90 |
| 62 void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatchOut( | 91 void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatchOut( |
| 63 EventTarget* target, | 92 EventTarget* target, |
| 64 EventTarget* relatedTarget) { | 93 EventTarget* relatedTarget) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 } | 175 } |
| 147 | 176 |
| 148 EventTarget* PointerEventManager::getEffectiveTargetForPointerEvent( | 177 EventTarget* PointerEventManager::getEffectiveTargetForPointerEvent( |
| 149 EventTarget* target, | 178 EventTarget* target, |
| 150 int pointerId) { | 179 int pointerId) { |
| 151 if (EventTarget* capturingTarget = getCapturingNode(pointerId)) | 180 if (EventTarget* capturingTarget = getCapturingNode(pointerId)) |
| 152 return capturingTarget; | 181 return capturingTarget; |
| 153 return target; | 182 return target; |
| 154 } | 183 } |
| 155 | 184 |
| 156 void PointerEventManager::sendMouseAndPossiblyPointerBoundaryEvents( | 185 void PointerEventManager::sendMouseAndPointerBoundaryEvents( |
| 157 Node* exitedNode, | |
| 158 Node* enteredNode, | 186 Node* enteredNode, |
| 159 const PlatformMouseEvent& mouseEvent, | 187 const PlatformMouseEvent& mouseEvent) { |
| 160 bool isFrameBoundaryTransition) { | |
| 161 // Mouse event type does not matter as this pointerevent will only be used | 188 // Mouse event type does not matter as this pointerevent will only be used |
| 162 // to create boundary pointer events and its type will be overridden in | 189 // to create boundary pointer events and its type will be overridden in |
| 163 // |sendBoundaryEvents| function. | 190 // |sendBoundaryEvents| function. |
| 164 PointerEvent* dummyPointerEvent = m_pointerEventFactory.create( | 191 PointerEvent* dummyPointerEvent = m_pointerEventFactory.create( |
| 165 EventTypeNames::mousedown, mouseEvent, m_frame->document()->domWindow()); | 192 EventTypeNames::mousedown, mouseEvent, m_frame->document()->domWindow()); |
| 166 | 193 |
| 167 // TODO(crbug/545647): This state should reset with pointercancel too. | 194 // TODO(crbug/545647): This state should reset with pointercancel too. |
| 168 // This function also gets called for compat mouse events of touch at this | 195 // This function also gets called for compat mouse events of touch at this |
| 169 // stage. So if the event is not frame boundary transition it is only a | 196 // stage. So if the event is not frame boundary transition it is only a |
| 170 // compatibility mouse event and we do not need to change pointer event | 197 // compatibility mouse event and we do not need to change pointer event |
| 171 // behavior regarding preventMouseEvent state in that case. | 198 // behavior regarding preventMouseEvent state in that case. |
| 172 if (isFrameBoundaryTransition && dummyPointerEvent->buttons() == 0 && | 199 if (dummyPointerEvent->buttons() == 0 && dummyPointerEvent->isPrimary()) { |
| 173 dummyPointerEvent->isPrimary()) { | |
| 174 m_preventMouseEventForPointerType[toPointerTypeIndex( | 200 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 175 mouseEvent.pointerProperties().pointerType)] = false; | 201 mouseEvent.pointerProperties().pointerType)] = false; |
| 176 } | 202 } |
| 177 | 203 |
| 178 processCaptureAndPositionOfPointerEvent(dummyPointerEvent, enteredNode, | 204 processCaptureAndPositionOfPointerEvent(dummyPointerEvent, enteredNode, |
| 179 exitedNode, mouseEvent, true, | 205 mouseEvent, true); |
| 180 isFrameBoundaryTransition); | |
| 181 } | 206 } |
| 182 | 207 |
| 183 void PointerEventManager::sendBoundaryEvents(EventTarget* exitedTarget, | 208 void PointerEventManager::sendBoundaryEvents(EventTarget* exitedTarget, |
| 184 EventTarget* enteredTarget, | 209 EventTarget* enteredTarget, |
| 185 PointerEvent* pointerEvent) { | 210 PointerEvent* pointerEvent) { |
| 186 if (RuntimeEnabledFeatures::pointerEventV1SpecCapturingEnabled()) { | 211 if (RuntimeEnabledFeatures::pointerEventV1SpecCapturingEnabled()) { |
| 187 if (exitedTarget == enteredTarget) | 212 if (exitedTarget == enteredTarget) |
| 188 return; | 213 return; |
| 189 if (EventTarget* capturingTarget = | 214 if (EventTarget* capturingTarget = |
| 190 getCapturingNode(pointerEvent->pointerId())) { | 215 getCapturingNode(pointerEvent->pointerId())) { |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 | 428 |
| 404 removePointer(pointerEvent); | 429 removePointer(pointerEvent); |
| 405 } | 430 } |
| 406 | 431 |
| 407 return result; | 432 return result; |
| 408 } | 433 } |
| 409 | 434 |
| 410 WebInputEventResult PointerEventManager::sendMousePointerEvent( | 435 WebInputEventResult PointerEventManager::sendMousePointerEvent( |
| 411 Node* target, | 436 Node* target, |
| 412 const AtomicString& mouseEventType, | 437 const AtomicString& mouseEventType, |
| 413 int clickCount, | 438 const PlatformMouseEvent& mouseEvent) { |
| 414 const PlatformMouseEvent& mouseEvent, | |
| 415 Node* lastNodeUnderMouse, | |
| 416 Node** newNodeUnderMouse) { | |
| 417 PointerEvent* pointerEvent = m_pointerEventFactory.create( | 439 PointerEvent* pointerEvent = m_pointerEventFactory.create( |
| 418 mouseEventType, mouseEvent, m_frame->document()->domWindow()); | 440 mouseEventType, mouseEvent, m_frame->document()->domWindow()); |
| 419 | 441 |
| 420 // This is for when the mouse is released outside of the page. | 442 // This is for when the mouse is released outside of the page. |
| 421 if (pointerEvent->type() == EventTypeNames::pointermove && | 443 if (pointerEvent->type() == EventTypeNames::pointermove && |
| 422 !pointerEvent->buttons()) { | 444 !pointerEvent->buttons()) { |
| 423 releasePointerCapture(pointerEvent->pointerId()); | 445 releasePointerCapture(pointerEvent->pointerId()); |
| 424 // Send got/lostpointercapture rightaway if necessary. | 446 // Send got/lostpointercapture rightaway if necessary. |
| 425 processPendingPointerCapture(pointerEvent); | 447 processPendingPointerCapture(pointerEvent); |
| 426 | 448 |
| 427 if (pointerEvent->isPrimary()) { | 449 if (pointerEvent->isPrimary()) { |
| 428 m_preventMouseEventForPointerType[toPointerTypeIndex( | 450 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 429 mouseEvent.pointerProperties().pointerType)] = false; | 451 mouseEvent.pointerProperties().pointerType)] = false; |
| 430 } | 452 } |
| 431 } | 453 } |
| 432 | 454 |
| 433 EventTarget* pointerEventTarget = processCaptureAndPositionOfPointerEvent( | 455 EventTarget* pointerEventTarget = processCaptureAndPositionOfPointerEvent( |
| 434 pointerEvent, target, lastNodeUnderMouse, mouseEvent, true, true); | 456 pointerEvent, target, mouseEvent, true); |
| 435 | |
| 436 if (pointerEventTarget) { | |
| 437 // This is to prevent incorrect boundary events if capturing transition was | |
| 438 // delayed. | |
| 439 *newNodeUnderMouse = pointerEventTarget->toNode(); | |
| 440 DCHECK(*newNodeUnderMouse); | |
| 441 } | |
| 442 | 457 |
| 443 EventTarget* effectiveTarget = getEffectiveTargetForPointerEvent( | 458 EventTarget* effectiveTarget = getEffectiveTargetForPointerEvent( |
| 444 pointerEventTarget, pointerEvent->pointerId()); | 459 pointerEventTarget, pointerEvent->pointerId()); |
| 445 | 460 |
| 446 WebInputEventResult result = | 461 WebInputEventResult result = |
| 447 dispatchPointerEvent(effectiveTarget, pointerEvent); | 462 dispatchPointerEvent(effectiveTarget, pointerEvent); |
| 448 | 463 |
| 449 if (result != WebInputEventResult::NotHandled && | 464 if (result != WebInputEventResult::NotHandled && |
| 450 pointerEvent->type() == EventTypeNames::pointerdown && | 465 pointerEvent->type() == EventTypeNames::pointerdown && |
| 451 pointerEvent->isPrimary()) { | 466 pointerEvent->isPrimary()) { |
| 452 m_preventMouseEventForPointerType[toPointerTypeIndex( | 467 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 453 mouseEvent.pointerProperties().pointerType)] = true; | 468 mouseEvent.pointerProperties().pointerType)] = true; |
| 454 } | 469 } |
| 455 | 470 |
| 456 if (pointerEvent->isPrimary() && | 471 if (pointerEvent->isPrimary() && |
| 457 !m_preventMouseEventForPointerType[toPointerTypeIndex( | 472 !m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 458 mouseEvent.pointerProperties().pointerType)]) { | 473 mouseEvent.pointerProperties().pointerType)]) { |
| 459 EventTarget* mouseTarget = effectiveTarget; | 474 EventTarget* mouseTarget = effectiveTarget; |
| 460 // Event path could be null if pointer event is not dispatched and | 475 // Event path could be null if pointer event is not dispatched and |
| 461 // that happens for example when pointer event feature is not enabled. | 476 // that happens for example when pointer event feature is not enabled. |
| 462 if (!isInDocument(mouseTarget) && pointerEvent->hasEventPath()) { | 477 if (!isInDocument(mouseTarget) && pointerEvent->hasEventPath()) { |
| 463 for (size_t i = 0; i < pointerEvent->eventPath().size(); i++) { | 478 for (size_t i = 0; i < pointerEvent->eventPath().size(); i++) { |
| 464 if (isInDocument(pointerEvent->eventPath()[i].node())) { | 479 if (isInDocument(pointerEvent->eventPath()[i].node())) { |
| 465 mouseTarget = pointerEvent->eventPath()[i].node(); | 480 mouseTarget = pointerEvent->eventPath()[i].node(); |
| 466 break; | 481 break; |
| 467 } | 482 } |
| 468 } | 483 } |
| 469 } | 484 } |
| 470 result = EventHandlingUtil::mergeEventResult( | 485 result = EventHandlingUtil::mergeEventResult( |
| 471 result, | 486 result, m_mouseEventManager->dispatchMouseEvent( |
| 472 m_mouseEventManager->dispatchMouseEvent( | 487 mouseTarget, mouseEventType, mouseEvent, nullptr)); |
| 473 mouseTarget, mouseEventType, mouseEvent, nullptr, clickCount)); | |
| 474 } | 488 } |
| 475 | 489 |
| 476 if (pointerEvent->type() == EventTypeNames::pointerup || | 490 if (pointerEvent->type() == EventTypeNames::pointerup || |
| 477 pointerEvent->type() == EventTypeNames::pointercancel) { | 491 pointerEvent->type() == EventTypeNames::pointercancel) { |
| 478 releasePointerCapture(pointerEvent->pointerId()); | 492 releasePointerCapture(pointerEvent->pointerId()); |
| 479 // Send got/lostpointercapture rightaway if necessary. | 493 // Send got/lostpointercapture rightaway if necessary. |
| 480 processPendingPointerCapture(pointerEvent); | 494 processPendingPointerCapture(pointerEvent); |
| 481 | 495 |
| 482 if (pointerEvent->isPrimary()) { | 496 if (pointerEvent->isPrimary()) { |
| 483 m_preventMouseEventForPointerType[toPointerTypeIndex( | 497 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 484 mouseEvent.pointerProperties().pointerType)] = false; | 498 mouseEvent.pointerProperties().pointerType)] = false; |
| 485 } | 499 } |
| 486 } | 500 } |
| 487 | 501 |
| 488 return result; | 502 return result; |
| 489 } | 503 } |
| 490 | 504 |
| 491 PointerEventManager::PointerEventManager(LocalFrame* frame, | |
| 492 MouseEventManager* mouseEventManager) | |
| 493 : m_frame(frame), | |
| 494 m_touchEventManager(new TouchEventManager(frame)), | |
| 495 m_mouseEventManager(mouseEventManager) { | |
| 496 clear(); | |
| 497 } | |
| 498 | |
| 499 void PointerEventManager::clear() { | |
| 500 for (auto& entry : m_preventMouseEventForPointerType) | |
| 501 entry = false; | |
| 502 m_touchEventManager->clear(); | |
| 503 m_inCanceledStateForPointerTypeTouch = false; | |
| 504 m_pointerEventFactory.clear(); | |
| 505 m_touchIdsForCanceledPointerdowns.clear(); | |
| 506 m_nodeUnderPointer.clear(); | |
| 507 m_pointerCaptureTarget.clear(); | |
| 508 m_pendingPointerCaptureTarget.clear(); | |
| 509 } | |
| 510 | |
| 511 bool PointerEventManager::getPointerCaptureState( | 505 bool PointerEventManager::getPointerCaptureState( |
| 512 int pointerId, | 506 int pointerId, |
| 513 EventTarget** pointerCaptureTarget, | 507 EventTarget** pointerCaptureTarget, |
| 514 EventTarget** pendingPointerCaptureTarget) { | 508 EventTarget** pendingPointerCaptureTarget) { |
| 515 PointerCapturingMap::const_iterator it; | 509 PointerCapturingMap::const_iterator it; |
| 516 | 510 |
| 517 it = m_pointerCaptureTarget.find(pointerId); | 511 it = m_pointerCaptureTarget.find(pointerId); |
| 518 EventTarget* pointerCaptureTargetTemp = | 512 EventTarget* pointerCaptureTargetTemp = |
| 519 (it != m_pointerCaptureTarget.end()) ? it->value : nullptr; | 513 (it != m_pointerCaptureTarget.end()) ? it->value : nullptr; |
| 520 it = m_pendingPointerCaptureTarget.find(pointerId); | 514 it = m_pendingPointerCaptureTarget.find(pointerId); |
| 521 EventTarget* pendingPointercaptureTargetTemp = | 515 EventTarget* pendingPointercaptureTargetTemp = |
| 522 (it != m_pendingPointerCaptureTarget.end()) ? it->value : nullptr; | 516 (it != m_pendingPointerCaptureTarget.end()) ? it->value : nullptr; |
| 523 | 517 |
| 524 if (pointerCaptureTarget) | 518 if (pointerCaptureTarget) |
| 525 *pointerCaptureTarget = pointerCaptureTargetTemp; | 519 *pointerCaptureTarget = pointerCaptureTargetTemp; |
| 526 if (pendingPointerCaptureTarget) | 520 if (pendingPointerCaptureTarget) |
| 527 *pendingPointerCaptureTarget = pendingPointercaptureTargetTemp; | 521 *pendingPointerCaptureTarget = pendingPointercaptureTargetTemp; |
| 528 | 522 |
| 529 return pointerCaptureTargetTemp != pendingPointercaptureTargetTemp; | 523 return pointerCaptureTargetTemp != pendingPointercaptureTargetTemp; |
| 530 } | 524 } |
| 531 | 525 |
| 532 EventTarget* PointerEventManager::processCaptureAndPositionOfPointerEvent( | 526 EventTarget* PointerEventManager::processCaptureAndPositionOfPointerEvent( |
| 533 PointerEvent* pointerEvent, | 527 PointerEvent* pointerEvent, |
| 534 EventTarget* hitTestTarget, | 528 EventTarget* hitTestTarget, |
| 535 EventTarget* lastNodeUnderMouse, | |
| 536 const PlatformMouseEvent& mouseEvent, | 529 const PlatformMouseEvent& mouseEvent, |
| 537 bool sendMouseEvent, | 530 bool sendMouseEvent) { |
| 538 bool setPointerPosition) { | 531 processPendingPointerCapture(pointerEvent); |
| 539 if (setPointerPosition) { | |
| 540 processPendingPointerCapture(pointerEvent); | |
| 541 | 532 |
| 542 if (!RuntimeEnabledFeatures::pointerEventV1SpecCapturingEnabled()) { | 533 if (!RuntimeEnabledFeatures::pointerEventV1SpecCapturingEnabled()) { |
| 543 PointerCapturingMap::const_iterator it = | 534 PointerCapturingMap::const_iterator it = |
| 544 m_pointerCaptureTarget.find(pointerEvent->pointerId()); | 535 m_pointerCaptureTarget.find(pointerEvent->pointerId()); |
| 545 if (EventTarget* pointercaptureTarget = | 536 if (EventTarget* pointercaptureTarget = |
| 546 (it != m_pointerCaptureTarget.end()) ? it->value : nullptr) | 537 (it != m_pointerCaptureTarget.end()) ? it->value : nullptr) |
| 547 hitTestTarget = pointercaptureTarget; | 538 hitTestTarget = pointercaptureTarget; |
| 548 } | 539 } |
| 549 | 540 |
| 550 setNodeUnderPointer(pointerEvent, hitTestTarget); | 541 setNodeUnderPointer(pointerEvent, hitTestTarget); |
| 551 } | |
| 552 if (sendMouseEvent) { | 542 if (sendMouseEvent) { |
| 553 // lastNodeUnderMouse is needed here because it is still stored in EventHand
ler. | 543 m_mouseEventManager->setNodeUnderMouse( |
| 554 m_mouseEventManager->sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget, | 544 hitTestTarget ? hitTestTarget->toNode() : nullptr, mouseEvent); |
| 555 mouseEvent); | |
| 556 } | 545 } |
| 557 return hitTestTarget; | 546 return hitTestTarget; |
| 558 } | 547 } |
| 559 | 548 |
| 560 void PointerEventManager::processPendingPointerCapture( | 549 void PointerEventManager::processPendingPointerCapture( |
| 561 PointerEvent* pointerEvent) { | 550 PointerEvent* pointerEvent) { |
| 562 EventTarget* pointerCaptureTarget; | 551 EventTarget* pointerCaptureTarget; |
| 563 EventTarget* pendingPointerCaptureTarget; | 552 EventTarget* pendingPointerCaptureTarget; |
| 564 const int pointerId = pointerEvent->pointerId(); | 553 const int pointerId = pointerEvent->pointerId(); |
| 565 const bool isCaptureChanged = getPointerCaptureState( | 554 const bool isCaptureChanged = getPointerCaptureState( |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 if (firstId == uniqueTouchEventId) | 672 if (firstId == uniqueTouchEventId) |
| 684 return true; | 673 return true; |
| 685 } | 674 } |
| 686 return false; | 675 return false; |
| 687 } | 676 } |
| 688 | 677 |
| 689 EventTarget* PointerEventManager::getMouseCapturingNode() { | 678 EventTarget* PointerEventManager::getMouseCapturingNode() { |
| 690 return getCapturingNode(PointerEventFactory::s_mouseId); | 679 return getCapturingNode(PointerEventFactory::s_mouseId); |
| 691 } | 680 } |
| 692 | 681 |
| 693 DEFINE_TRACE(PointerEventManager) { | |
| 694 visitor->trace(m_frame); | |
| 695 visitor->trace(m_nodeUnderPointer); | |
| 696 visitor->trace(m_pointerCaptureTarget); | |
| 697 visitor->trace(m_pendingPointerCaptureTarget); | |
| 698 visitor->trace(m_touchEventManager); | |
| 699 visitor->trace(m_mouseEventManager); | |
| 700 } | |
| 701 | |
| 702 } // namespace blink | 682 } // namespace blink |
| OLD | NEW |