| 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/ExecutionContextTask.h" | 8 #include "core/dom/ExecutionContextTask.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 19 matching lines...) Expand all Loading... |
| 30 return EventTypeNames::pointerup; | 30 return EventTypeNames::pointerup; |
| 31 case PlatformTouchPoint::TouchCancelled: | 31 case PlatformTouchPoint::TouchCancelled: |
| 32 return EventTypeNames::pointercancel; | 32 return EventTypeNames::pointercancel; |
| 33 case PlatformTouchPoint::TouchPressed: | 33 case PlatformTouchPoint::TouchPressed: |
| 34 return EventTypeNames::pointerdown; | 34 return EventTypeNames::pointerdown; |
| 35 case PlatformTouchPoint::TouchMoved: | 35 case PlatformTouchPoint::TouchMoved: |
| 36 return EventTypeNames::pointermove; | 36 return EventTypeNames::pointermove; |
| 37 case PlatformTouchPoint::TouchStationary: | 37 case PlatformTouchPoint::TouchStationary: |
| 38 // Fall through to default | 38 // Fall through to default |
| 39 default: | 39 default: |
| 40 ASSERT_NOT_REACHED(); | 40 NOTREACHED(); |
| 41 return emptyAtom; | 41 return emptyAtom; |
| 42 } | 42 } |
| 43 } | 43 } |
| 44 | 44 |
| 45 bool isInDocument(EventTarget* n) | 45 bool isInDocument(EventTarget* n) |
| 46 { | 46 { |
| 47 return n && n->toNode() && n->toNode()->isConnected(); | 47 return n && n->toNode() && n->toNode()->isConnected(); |
| 48 } | 48 } |
| 49 | 49 |
| 50 WebInputEventResult dispatchMouseEvent( | 50 WebInputEventResult dispatchMouseEvent( |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 | 204 |
| 205 void PointerEventManager::sendBoundaryEvents( | 205 void PointerEventManager::sendBoundaryEvents( |
| 206 EventTarget* exitedTarget, | 206 EventTarget* exitedTarget, |
| 207 EventTarget* enteredTarget, | 207 EventTarget* enteredTarget, |
| 208 PointerEvent* pointerEvent, | 208 PointerEvent* pointerEvent, |
| 209 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) | 209 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) |
| 210 { | 210 { |
| 211 if (exitedTarget == enteredTarget) | 211 if (exitedTarget == enteredTarget) |
| 212 return; | 212 return; |
| 213 | 213 |
| 214 if (EventTarget* capturingTarget = getCapturingNode(pointerEvent->pointerId(
))) { | |
| 215 if (capturingTarget == exitedTarget) | |
| 216 enteredTarget = nullptr; | |
| 217 else if (capturingTarget == enteredTarget) | |
| 218 exitedTarget = nullptr; | |
| 219 else | |
| 220 return; | |
| 221 } | |
| 222 | |
| 223 // Dispatch pointerout/mouseout events | 214 // Dispatch pointerout/mouseout events |
| 224 if (isInDocument(exitedTarget)) { | 215 if (isInDocument(exitedTarget)) { |
| 225 if (!sendMouseEvent) { | 216 if (!sendMouseEvent) { |
| 226 dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPoint
erBoundaryEvent( | 217 dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPoint
erBoundaryEvent( |
| 227 pointerEvent, EventTypeNames::pointerout, enteredTarget)); | 218 pointerEvent, EventTypeNames::pointerout, enteredTarget)); |
| 228 } else { | 219 } else { |
| 229 dispatchMouseEvent(exitedTarget, | 220 dispatchMouseEvent(exitedTarget, |
| 230 EventTypeNames::mouseout, | 221 EventTypeNames::mouseout, |
| 231 mouseEventWithRegion(exitedTarget->toNode(), mouseEvent), | 222 mouseEventWithRegion(exitedTarget->toNode(), mouseEvent), |
| 232 enteredTarget); | 223 enteredTarget); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 } else { | 305 } else { |
| 315 dispatchMouseEvent(enteredAncestors[i-1].get(), | 306 dispatchMouseEvent(enteredAncestors[i-1].get(), |
| 316 EventTypeNames::mouseenter, mouseEvent, exitedTarget, | 307 EventTypeNames::mouseenter, mouseEvent, exitedTarget, |
| 317 0, !enteredNodeHasCapturingAncestor); | 308 0, !enteredNodeHasCapturingAncestor); |
| 318 } | 309 } |
| 319 } | 310 } |
| 320 } | 311 } |
| 321 | 312 |
| 322 void PointerEventManager::setNodeUnderPointer( | 313 void PointerEventManager::setNodeUnderPointer( |
| 323 PointerEvent* pointerEvent, | 314 PointerEvent* pointerEvent, |
| 324 EventTarget* target, | 315 EventTarget* target) |
| 325 bool sendEvent) | |
| 326 { | 316 { |
| 327 if (m_nodeUnderPointer.contains(pointerEvent->pointerId())) { | 317 if (m_nodeUnderPointer.contains(pointerEvent->pointerId())) { |
| 328 EventTargetAttributes node = m_nodeUnderPointer.get( | 318 EventTargetAttributes node = m_nodeUnderPointer.get( |
| 329 pointerEvent->pointerId()); | 319 pointerEvent->pointerId()); |
| 330 if (!target) { | 320 if (!target) { |
| 331 m_nodeUnderPointer.remove(pointerEvent->pointerId()); | 321 m_nodeUnderPointer.remove(pointerEvent->pointerId()); |
| 332 } else if (target | 322 } else if (target |
| 333 != m_nodeUnderPointer.get(pointerEvent->pointerId()).target) { | 323 != m_nodeUnderPointer.get(pointerEvent->pointerId()).target) { |
| 334 m_nodeUnderPointer.set(pointerEvent->pointerId(), | 324 m_nodeUnderPointer.set(pointerEvent->pointerId(), |
| 335 EventTargetAttributes(target, false)); | 325 EventTargetAttributes(target, false)); |
| 336 } | 326 } |
| 337 if (sendEvent) | 327 sendBoundaryEvents(node.target, target, pointerEvent); |
| 338 sendBoundaryEvents(node.target, target, pointerEvent); | |
| 339 } else if (target) { | 328 } else if (target) { |
| 340 m_nodeUnderPointer.add(pointerEvent->pointerId(), | 329 m_nodeUnderPointer.add(pointerEvent->pointerId(), |
| 341 EventTargetAttributes(target, false)); | 330 EventTargetAttributes(target, false)); |
| 342 if (sendEvent) | 331 sendBoundaryEvents(nullptr, target, pointerEvent); |
| 343 sendBoundaryEvents(nullptr, target, pointerEvent); | |
| 344 } | 332 } |
| 345 } | 333 } |
| 346 | 334 |
| 347 void PointerEventManager::blockTouchPointers() | 335 void PointerEventManager::blockTouchPointers() |
| 348 { | 336 { |
| 349 if (m_inCanceledStateForPointerTypeTouch) | 337 if (m_inCanceledStateForPointerTypeTouch) |
| 350 return; | 338 return; |
| 351 m_inCanceledStateForPointerTypeTouch = true; | 339 m_inCanceledStateForPointerTypeTouch = true; |
| 352 | 340 |
| 353 Vector<int> touchPointerIds | 341 Vector<int> touchPointerIds |
| 354 = m_pointerEventFactory.getPointerIdsOfType(WebPointerProperties::Pointe
rType::Touch); | 342 = m_pointerEventFactory.getPointerIdsOfType(WebPointerProperties::Pointe
rType::Touch); |
| 355 | 343 |
| 356 for (int pointerId : touchPointerIds) { | 344 for (int pointerId : touchPointerIds) { |
| 357 PointerEvent* pointerEvent | 345 PointerEvent* pointerEvent |
| 358 = m_pointerEventFactory.createPointerCancelEvent( | 346 = m_pointerEventFactory.createPointerCancelEvent( |
| 359 pointerId, WebPointerProperties::PointerType::Touch); | 347 pointerId, WebPointerProperties::PointerType::Touch); |
| 360 | 348 |
| 361 ASSERT(m_nodeUnderPointer.contains(pointerId)); | 349 DCHECK(m_nodeUnderPointer.contains(pointerId)); |
| 362 EventTarget* target = m_nodeUnderPointer.get(pointerId).target; | 350 EventTarget* target = m_nodeUnderPointer.get(pointerId).target; |
| 363 | 351 |
| 364 processCaptureAndPositionOfPointerEvent(pointerEvent, target); | 352 processCaptureAndPositionOfPointerEvent(pointerEvent, target); |
| 365 | 353 |
| 366 // TODO(nzolghadr): This event follows implicit TE capture. The actual t
arget | 354 // TODO(nzolghadr): This event follows implicit TE capture. The actual t
arget |
| 367 // would depend on PE capturing. Perhaps need to split TE/PE event path
upstream? | 355 // would depend on PE capturing. Perhaps need to split TE/PE event path
upstream? |
| 368 // crbug.com/579553. | 356 // crbug.com/579553. |
| 369 dispatchPointerEvent( | 357 dispatchPointerEvent( |
| 370 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId())
, | 358 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId())
, |
| 371 pointerEvent); | 359 pointerEvent); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 // Setting the implicit capture for touch | 497 // Setting the implicit capture for touch |
| 510 if (pointerEvent->type() == EventTypeNames::pointerdown) | 498 if (pointerEvent->type() == EventTypeNames::pointerdown) |
| 511 setPointerCapture(pointerEvent->pointerId(), target); | 499 setPointerCapture(pointerEvent->pointerId(), target); |
| 512 | 500 |
| 513 WebInputEventResult result = dispatchPointerEvent( | 501 WebInputEventResult result = dispatchPointerEvent( |
| 514 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()), | 502 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()), |
| 515 pointerEvent); | 503 pointerEvent); |
| 516 | 504 |
| 517 if (pointerEvent->type() == EventTypeNames::pointerup | 505 if (pointerEvent->type() == EventTypeNames::pointerup |
| 518 || pointerEvent->type() == EventTypeNames::pointercancel) { | 506 || pointerEvent->type() == EventTypeNames::pointercancel) { |
| 519 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr); | 507 // Send the lostpointercapture right away. |
| 508 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr, true); |
| 520 | 509 |
| 521 // Sending the leave/out events and lostpointercapture | 510 // Sending the leave/out events and lostpointercapture because the next |
| 522 // because the next touch event will have a different id. So delayed | 511 // touch event will have a different id. |
| 523 // sending of lostpointercapture won't work here. | |
| 524 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr); | 512 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr); |
| 525 | 513 |
| 526 removePointer(pointerEvent); | 514 removePointer(pointerEvent); |
| 527 } | 515 } |
| 528 | 516 |
| 529 return result; | 517 return result; |
| 530 } | 518 } |
| 531 | 519 |
| 532 WebInputEventResult PointerEventManager::sendMousePointerEvent( | 520 WebInputEventResult PointerEventManager::sendMousePointerEvent( |
| 533 Node* target, const AtomicString& mouseEventType, | 521 Node* target, const AtomicString& mouseEventType, |
| 534 int clickCount, const PlatformMouseEvent& mouseEvent, | 522 int clickCount, const PlatformMouseEvent& mouseEvent, |
| 535 Node* relatedTarget, | 523 Node* relatedTarget, |
| 536 Node* lastNodeUnderMouse) | 524 Node* lastNodeUnderMouse) |
| 537 { | 525 { |
| 538 PointerEvent* pointerEvent = | 526 PointerEvent* pointerEvent = |
| 539 m_pointerEventFactory.create(mouseEventType, mouseEvent, | 527 m_pointerEventFactory.create(mouseEventType, mouseEvent, |
| 540 relatedTarget, m_frame->document()->domWindow()); | 528 relatedTarget, m_frame->document()->domWindow()); |
| 541 | 529 |
| 542 // This is for when the mouse is released outside of the page. | 530 // This is for when the mouse is released outside of the page. |
| 543 if (pointerEvent->type() == EventTypeNames::pointermove | 531 if (pointerEvent->type() == EventTypeNames::pointermove |
| 544 && !pointerEvent->buttons() | 532 && !pointerEvent->buttons() |
| 545 && pointerEvent->isPrimary()) { | 533 && pointerEvent->isPrimary()) { |
| 546 m_preventMouseEventForPointerType[toPointerTypeIndex( | 534 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 547 mouseEvent.pointerProperties().pointerType)] = false; | 535 mouseEvent.pointerProperties().pointerType)] = false; |
| 548 } | 536 } |
| 549 | 537 |
| 550 processCaptureAndPositionOfPointerEvent(pointerEvent, target, | 538 EventTarget* pointerEventTarget = processCaptureAndPositionOfPointerEvent(po
interEvent, target, |
| 551 lastNodeUnderMouse, mouseEvent, true, true); | 539 lastNodeUnderMouse, mouseEvent, true, true); |
| 552 | 540 |
| 553 EventTarget* effectiveTarget = | 541 EventTarget* effectiveTarget = |
| 554 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()); | 542 getEffectiveTargetForPointerEvent(pointerEventTarget, pointerEvent->poin
terId()); |
| 555 | 543 |
| 556 WebInputEventResult result = | 544 WebInputEventResult result = |
| 557 dispatchPointerEvent(effectiveTarget, pointerEvent); | 545 dispatchPointerEvent(effectiveTarget, pointerEvent); |
| 558 | 546 |
| 559 if (result != WebInputEventResult::NotHandled | 547 if (result != WebInputEventResult::NotHandled |
| 560 && pointerEvent->type() == EventTypeNames::pointerdown | 548 && pointerEvent->type() == EventTypeNames::pointerdown |
| 561 && pointerEvent->isPrimary()) { | 549 && pointerEvent->isPrimary()) { |
| 562 m_preventMouseEventForPointerType[toPointerTypeIndex( | 550 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 563 mouseEvent.pointerProperties().pointerType)] = true; | 551 mouseEvent.pointerProperties().pointerType)] = true; |
| 564 } | 552 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 575 break; | 563 break; |
| 576 } | 564 } |
| 577 } | 565 } |
| 578 } | 566 } |
| 579 result = EventHandler::mergeEventResult(result, | 567 result = EventHandler::mergeEventResult(result, |
| 580 dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent, | 568 dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent, |
| 581 nullptr, clickCount)); | 569 nullptr, clickCount)); |
| 582 } | 570 } |
| 583 | 571 |
| 584 if (pointerEvent->buttons() == 0) { | 572 if (pointerEvent->buttons() == 0) { |
| 585 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr); | 573 // Send the lostpointercapture right away. |
| 574 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr, true); |
| 586 if (pointerEvent->isPrimary()) { | 575 if (pointerEvent->isPrimary()) { |
| 587 m_preventMouseEventForPointerType[toPointerTypeIndex( | 576 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 588 mouseEvent.pointerProperties().pointerType)] = false; | 577 mouseEvent.pointerProperties().pointerType)] = false; |
| 589 } | 578 } |
| 590 } | 579 } |
| 591 | 580 |
| 592 return result; | 581 return result; |
| 593 } | 582 } |
| 594 | 583 |
| 595 PointerEventManager::PointerEventManager(LocalFrame* frame) | 584 PointerEventManager::PointerEventManager(LocalFrame* frame) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 613 m_touchIdsForCanceledPointerdowns.clear(); | 602 m_touchIdsForCanceledPointerdowns.clear(); |
| 614 m_nodeUnderPointer.clear(); | 603 m_nodeUnderPointer.clear(); |
| 615 m_pointerCaptureTarget.clear(); | 604 m_pointerCaptureTarget.clear(); |
| 616 m_pendingPointerCaptureTarget.clear(); | 605 m_pendingPointerCaptureTarget.clear(); |
| 617 } | 606 } |
| 618 | 607 |
| 619 bool PointerEventManager::getPointerCaptureState(int pointerId, | 608 bool PointerEventManager::getPointerCaptureState(int pointerId, |
| 620 EventTarget** pointerCaptureTarget, | 609 EventTarget** pointerCaptureTarget, |
| 621 EventTarget** pendingPointerCaptureTarget) | 610 EventTarget** pendingPointerCaptureTarget) |
| 622 { | 611 { |
| 623 PointerCapturingMap::iterator it; | 612 PointerCapturingMap::const_iterator it; |
| 624 | 613 |
| 625 it = m_pointerCaptureTarget.find(pointerId); | 614 it = m_pointerCaptureTarget.find(pointerId); |
| 626 EventTarget* pointercaptureTargetTemp = (it != m_pointerCaptureTarget.end())
? it->value : nullptr; | 615 EventTarget* pointerCaptureTargetTemp = (it != m_pointerCaptureTarget.end())
? it->value : nullptr; |
| 627 it = m_pendingPointerCaptureTarget.find(pointerId); | 616 it = m_pendingPointerCaptureTarget.find(pointerId); |
| 628 EventTarget* pendingPointercaptureTargetTemp = (it != m_pendingPointerCaptur
eTarget.end()) ? it->value : nullptr; | 617 EventTarget* pendingPointercaptureTargetTemp = (it != m_pendingPointerCaptur
eTarget.end()) ? it->value : nullptr; |
| 629 | 618 |
| 630 if (pointerCaptureTarget) | 619 if (pointerCaptureTarget) |
| 631 *pointerCaptureTarget = pointercaptureTargetTemp; | 620 *pointerCaptureTarget = pointerCaptureTargetTemp; |
| 632 if (pendingPointerCaptureTarget) | 621 if (pendingPointerCaptureTarget) |
| 633 *pendingPointerCaptureTarget = pendingPointercaptureTargetTemp; | 622 *pendingPointerCaptureTarget = pendingPointercaptureTargetTemp; |
| 634 | 623 |
| 635 return pointercaptureTargetTemp != pendingPointercaptureTargetTemp; | 624 return pointerCaptureTargetTemp != pendingPointercaptureTargetTemp; |
| 636 } | 625 } |
| 637 | 626 |
| 638 void PointerEventManager::processCaptureAndPositionOfPointerEvent( | 627 EventTarget* PointerEventManager::processCaptureAndPositionOfPointerEvent( |
| 639 PointerEvent* pointerEvent, | 628 PointerEvent* pointerEvent, |
| 640 EventTarget* hitTestTarget, | 629 EventTarget* hitTestTarget, |
| 641 EventTarget* lastNodeUnderMouse, | 630 EventTarget* lastNodeUnderMouse, |
| 642 const PlatformMouseEvent& mouseEvent, | 631 const PlatformMouseEvent& mouseEvent, |
| 643 bool sendMouseEvent, bool setPointerPosition) | 632 bool sendMouseEvent, bool setPointerPosition) |
| 644 { | 633 { |
| 645 bool isCaptureChanged = false; | 634 if (setPointerPosition) { |
| 635 processPendingPointerCapture(pointerEvent->pointerId()); |
| 646 | 636 |
| 647 if (setPointerPosition) { | 637 PointerCapturingMap::const_iterator it = m_pointerCaptureTarget.find(poi
nterEvent->pointerId()); |
| 648 isCaptureChanged = processPendingPointerCapture(pointerEvent, | 638 if (EventTarget* pointercaptureTarget = (it != m_pointerCaptureTarget.en
d()) ? it->value : nullptr) |
| 649 hitTestTarget, mouseEvent, sendMouseEvent); | 639 hitTestTarget = pointercaptureTarget; |
| 650 // If there was a change in capturing processPendingPointerCapture has | 640 |
| 651 // already taken care of transition events. So we don't need to send the | 641 setNodeUnderPointer(pointerEvent, hitTestTarget); |
| 652 // transition events here. | |
| 653 setNodeUnderPointer(pointerEvent, hitTestTarget, !isCaptureChanged); | |
| 654 } | 642 } |
| 655 if (sendMouseEvent && !isCaptureChanged) { | 643 if (sendMouseEvent) { |
| 656 // lastNodeUnderMouse is needed here because it is still stored in Event
Handler. | 644 // lastNodeUnderMouse is needed here because it is still stored in Event
Handler. |
| 657 sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget, | 645 sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget, |
| 658 pointerEvent, mouseEvent, true); | 646 pointerEvent, mouseEvent, true); |
| 659 } | 647 } |
| 648 return hitTestTarget; |
| 660 } | 649 } |
| 661 | 650 |
| 662 void PointerEventManager::immediatelyProcessPendingPointerCapture(int pointerId) | 651 void PointerEventManager::processPendingPointerCapture(int pointerId) |
| 663 { | 652 { |
| 664 EventTarget* pointerCaptureTarget; | 653 EventTarget* pointerCaptureTarget; |
| 665 EventTarget* pendingPointerCaptureTarget; | 654 EventTarget* pendingPointerCaptureTarget; |
| 666 const bool isCaptureChanged = getPointerCaptureState(pointerId, | 655 const bool isCaptureChanged = getPointerCaptureState(pointerId, |
| 667 &pointerCaptureTarget, &pendingPointerCaptureTarget); | 656 &pointerCaptureTarget, &pendingPointerCaptureTarget); |
| 668 | 657 |
| 669 if (!isCaptureChanged) | 658 if (!isCaptureChanged) |
| 670 return; | 659 return; |
| 671 | 660 |
| 661 // We have to check whether the pointerCaptureTarget is null or not because |
| 662 // we are checking whether it is still connected to its document or not. |
| 672 if (pointerCaptureTarget) { | 663 if (pointerCaptureTarget) { |
| 673 // Re-target lostpointercapture to the document when the element is | 664 // Re-target lostpointercapture to the document when the element is |
| 674 // no longer participating in the tree. | 665 // no longer participating in the tree. |
| 675 EventTarget* target = pointerCaptureTarget; | 666 EventTarget* target = pointerCaptureTarget; |
| 676 if (target->toNode() | 667 if (target->toNode() |
| 677 && !target->toNode()->isConnected()) { | 668 && !target->toNode()->isConnected()) { |
| 678 target = target->toNode()->ownerDocument(); | 669 target = target->toNode()->ownerDocument(); |
| 679 } | 670 } |
| 680 dispatchPointerEvent(target, | 671 dispatchPointerEvent(target, |
| 681 m_pointerEventFactory.createPointerCaptureEvent( | 672 m_pointerEventFactory.createPointerCaptureEvent( |
| 682 pointerId, EventTypeNames::lostpointercapture)); | 673 pointerId, EventTypeNames::lostpointercapture)); |
| 683 } | 674 } |
| 675 // Note that If pendingPointerCaptureTarget is null dispatchPointerEvent |
| 676 // automatically does nothing. |
| 684 dispatchPointerEvent(pendingPointerCaptureTarget, | 677 dispatchPointerEvent(pendingPointerCaptureTarget, |
| 685 m_pointerEventFactory.createPointerCaptureEvent( | 678 m_pointerEventFactory.createPointerCaptureEvent( |
| 686 pointerId, EventTypeNames::gotpointercapture)); | 679 pointerId, EventTypeNames::gotpointercapture)); |
| 687 | 680 |
| 688 // Setting |m_pointerCaptureTarget| comes at the end to prevent the infinite | 681 // Setting |m_pointerCaptureTarget| comes at the end to prevent the infinite |
| 689 // loop if js calls set/releasepointercapture in got/lostpointercapture | 682 // loop if js calls set/releasepointercapture in got/lostpointercapture |
| 690 // handlers. | 683 // handlers. |
| 691 if (pendingPointerCaptureTarget) | 684 if (pendingPointerCaptureTarget) |
| 692 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); | 685 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); |
| 693 else | 686 else |
| 694 m_pointerCaptureTarget.remove(pointerId); | 687 m_pointerCaptureTarget.remove(pointerId); |
| 695 } | 688 } |
| 696 | 689 |
| 697 // TODO(crbug.com/629921): This function should be merged with |immediatelyProce
ssPendingPointerCapture| | |
| 698 // when we stop hit-testing while a pointer is captured. | |
| 699 bool PointerEventManager::processPendingPointerCapture( | |
| 700 PointerEvent* pointerEvent, | |
| 701 EventTarget* hitTestTarget, | |
| 702 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) | |
| 703 { | |
| 704 int pointerId = pointerEvent->pointerId(); | |
| 705 EventTarget* pointerCaptureTarget; | |
| 706 EventTarget* pendingPointerCaptureTarget; | |
| 707 const bool isCaptureChanged = getPointerCaptureState(pointerId, | |
| 708 &pointerCaptureTarget, &pendingPointerCaptureTarget); | |
| 709 const EventTargetAttributes &nodeUnderPointerAtt = | |
| 710 m_nodeUnderPointer.contains(pointerId) | |
| 711 ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes(); | |
| 712 | |
| 713 if (isCaptureChanged) { | |
| 714 if ((hitTestTarget != nodeUnderPointerAtt.target | |
| 715 || (pendingPointerCaptureTarget | |
| 716 && pendingPointerCaptureTarget != nodeUnderPointerAtt.target)) | |
| 717 && nodeUnderPointerAtt.hasRecievedOverEvent) { | |
| 718 if (sendMouseEvent) { | |
| 719 // Send pointer event transitions as the line after this if | |
| 720 // block sends the mouse events | |
| 721 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr, | |
| 722 pointerEvent); | |
| 723 } | |
| 724 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr, | |
| 725 pointerEvent, mouseEvent, sendMouseEvent); | |
| 726 } | |
| 727 if (pointerCaptureTarget) { | |
| 728 // Re-target lostpointercapture to the document when the element is | |
| 729 // no longer participating in the tree. | |
| 730 EventTarget* target = pointerCaptureTarget; | |
| 731 if (target->toNode() | |
| 732 && !target->toNode()->isConnected()) { | |
| 733 target = target->toNode()->ownerDocument(); | |
| 734 } | |
| 735 dispatchPointerEvent(target, | |
| 736 m_pointerEventFactory.createPointerCaptureEvent( | |
| 737 pointerId, EventTypeNames::lostpointercapture)); | |
| 738 } | |
| 739 } | |
| 740 | |
| 741 // Set pointerCaptureTarget from pendingPointerCaptureTarget. This does | |
| 742 // affect the behavior of sendBoundaryEvents function. So the | |
| 743 // ordering of the surrounding blocks of code for sending transition events | |
| 744 // are important. | |
| 745 if (pendingPointerCaptureTarget) | |
| 746 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); | |
| 747 else | |
| 748 m_pointerCaptureTarget.remove(pointerId); | |
| 749 | |
| 750 if (isCaptureChanged) { | |
| 751 dispatchPointerEvent(pendingPointerCaptureTarget, | |
| 752 m_pointerEventFactory.createPointerCaptureEvent( | |
| 753 pointerId, EventTypeNames::gotpointercapture)); | |
| 754 if ((pendingPointerCaptureTarget == hitTestTarget | |
| 755 || !pendingPointerCaptureTarget) | |
| 756 && (nodeUnderPointerAtt.target != hitTestTarget | |
| 757 || !nodeUnderPointerAtt.hasRecievedOverEvent)) { | |
| 758 if (sendMouseEvent) { | |
| 759 // Send pointer event transitions as the line after this if | |
| 760 // block sends the mouse events | |
| 761 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent); | |
| 762 } | |
| 763 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent, | |
| 764 mouseEvent, sendMouseEvent); | |
| 765 } | |
| 766 } | |
| 767 return isCaptureChanged; | |
| 768 } | |
| 769 | |
| 770 void PointerEventManager::removeTargetFromPointerCapturingMapping( | 690 void PointerEventManager::removeTargetFromPointerCapturingMapping( |
| 771 PointerCapturingMap& map, const EventTarget* target) | 691 PointerCapturingMap& map, const EventTarget* target) |
| 772 { | 692 { |
| 773 // We could have kept a reverse mapping to make this deletion possibly | 693 // We could have kept a reverse mapping to make this deletion possibly |
| 774 // faster but it adds some code complication which might not be worth of | 694 // faster but it adds some code complication which might not be worth of |
| 775 // the performance improvement considering there might not be a lot of | 695 // the performance improvement considering there might not be a lot of |
| 776 // active pointer or pointer captures at the same time. | 696 // active pointer or pointer captures at the same time. |
| 777 PointerCapturingMap tmp = map; | 697 PointerCapturingMap tmp = map; |
| 778 for (PointerCapturingMap::iterator it = tmp.begin(); it != tmp.end(); ++it)
{ | 698 for (PointerCapturingMap::iterator it = tmp.begin(); it != tmp.end(); ++it)
{ |
| 779 if (it->value == target) | 699 if (it->value == target) |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 // |m_pointercaptureTarget|. |m_pointercaptureTarget| holds the element | 739 // |m_pointercaptureTarget|. |m_pointercaptureTarget| holds the element |
| 820 // that had the capture until now and has been receiving the pointerevents | 740 // that had the capture until now and has been receiving the pointerevents |
| 821 // but |m_pendingPointerCaptureTarget| indicated the element that gets the | 741 // but |m_pendingPointerCaptureTarget| indicated the element that gets the |
| 822 // very next pointer event. They will be the same if there was no change in | 742 // very next pointer event. They will be the same if there was no change in |
| 823 // capturing of a particular |pointerId|. See crbug.com/614481. | 743 // capturing of a particular |pointerId|. See crbug.com/614481. |
| 824 if (m_pendingPointerCaptureTarget.get(pointerId) == target) | 744 if (m_pendingPointerCaptureTarget.get(pointerId) == target) |
| 825 modifyPendingPointerCapture(pointerId, nullptr); | 745 modifyPendingPointerCapture(pointerId, nullptr); |
| 826 } | 746 } |
| 827 | 747 |
| 828 void PointerEventManager::modifyPendingPointerCapture( | 748 void PointerEventManager::modifyPendingPointerCapture( |
| 829 int pointerId, EventTarget* target) | 749 int pointerId, EventTarget* target, bool immediate) |
| 830 { | 750 { |
| 831 bool wasCaptureStationary = !getPointerCaptureState(pointerId, nullptr, null
ptr); | 751 bool wasCaptureStationary = !getPointerCaptureState(pointerId, nullptr, null
ptr); |
| 832 | 752 |
| 833 if (target) | 753 if (target) |
| 834 m_pendingPointerCaptureTarget.set(pointerId, target); | 754 m_pendingPointerCaptureTarget.set(pointerId, target); |
| 835 else | 755 else |
| 836 m_pendingPointerCaptureTarget.remove(pointerId); | 756 m_pendingPointerCaptureTarget.remove(pointerId); |
| 837 | 757 |
| 838 // Only queue the processing pending pointer capture if the pending | 758 // Only queue the processing pending pointer capture if the pending |
| 839 // capture target and capture target were the same to prevent infinite | 759 // capture target and capture target were the same to prevent infinite |
| 840 // got/lostpointercapture event sequence. | 760 // got/lostpointercapture event sequence. |
| 841 // See https://github.com/w3c/pointerevents/issues/32. | 761 // See https://github.com/w3c/pointerevents/issues/32. |
| 842 if (wasCaptureStationary) { | 762 if (immediate) { |
| 763 processPendingPointerCapture(pointerId); |
| 764 } else if (wasCaptureStationary) { |
| 843 m_frame->document()->postTask( | 765 m_frame->document()->postTask( |
| 844 BLINK_FROM_HERE, | 766 BLINK_FROM_HERE, |
| 845 createSameThreadTask( | 767 createSameThreadTask( |
| 846 &EventHandler::immediatelyProcessPendingPointerCapture, | 768 &EventHandler::immediatelyProcessPendingPointerCapture, |
| 847 wrapWeakPersistent(&m_frame->eventHandler()), pointerId)); | 769 wrapWeakPersistent(&m_frame->eventHandler()), pointerId)); |
| 848 } | 770 } |
| 849 } | 771 } |
| 850 | 772 |
| 851 bool PointerEventManager::isActive(const int pointerId) const | 773 bool PointerEventManager::isActive(const int pointerId) const |
| 852 { | 774 { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 867 uint32_t firstId = m_touchIdsForCanceledPointerdowns.first(); | 789 uint32_t firstId = m_touchIdsForCanceledPointerdowns.first(); |
| 868 if (firstId > uniqueTouchEventId) | 790 if (firstId > uniqueTouchEventId) |
| 869 return false; | 791 return false; |
| 870 m_touchIdsForCanceledPointerdowns.takeFirst(); | 792 m_touchIdsForCanceledPointerdowns.takeFirst(); |
| 871 if (firstId == uniqueTouchEventId) | 793 if (firstId == uniqueTouchEventId) |
| 872 return true; | 794 return true; |
| 873 } | 795 } |
| 874 return false; | 796 return false; |
| 875 } | 797 } |
| 876 | 798 |
| 799 EventTarget* PointerEventManager::getMouseCapturingNode() |
| 800 { |
| 801 return getCapturingNode(PointerEventFactory::s_mouseId); |
| 802 } |
| 803 |
| 877 DEFINE_TRACE(PointerEventManager) | 804 DEFINE_TRACE(PointerEventManager) |
| 878 { | 805 { |
| 879 visitor->trace(m_frame); | 806 visitor->trace(m_frame); |
| 880 visitor->trace(m_nodeUnderPointer); | 807 visitor->trace(m_nodeUnderPointer); |
| 881 visitor->trace(m_pointerCaptureTarget); | 808 visitor->trace(m_pointerCaptureTarget); |
| 882 visitor->trace(m_pendingPointerCaptureTarget); | 809 visitor->trace(m_pendingPointerCaptureTarget); |
| 883 visitor->trace(m_touchEventManager); | 810 visitor->trace(m_touchEventManager); |
| 884 } | 811 } |
| 885 | 812 |
| 886 | 813 |
| 887 } // namespace blink | 814 } // namespace blink |
| OLD | NEW |