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 |