| 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, |
| 525 Node** newNodeUnderMouse) |
| 537 { | 526 { |
| 538 PointerEvent* pointerEvent = | 527 PointerEvent* pointerEvent = |
| 539 m_pointerEventFactory.create(mouseEventType, mouseEvent, | 528 m_pointerEventFactory.create(mouseEventType, mouseEvent, |
| 540 relatedTarget, m_frame->document()->domWindow()); | 529 relatedTarget, m_frame->document()->domWindow()); |
| 541 | 530 |
| 542 // This is for when the mouse is released outside of the page. | 531 // This is for when the mouse is released outside of the page. |
| 543 if (pointerEvent->type() == EventTypeNames::pointermove | 532 if (pointerEvent->type() == EventTypeNames::pointermove |
| 544 && !pointerEvent->buttons() | 533 && !pointerEvent->buttons() |
| 545 && pointerEvent->isPrimary()) { | 534 && pointerEvent->isPrimary()) { |
| 546 m_preventMouseEventForPointerType[toPointerTypeIndex( | 535 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 547 mouseEvent.pointerProperties().pointerType)] = false; | 536 mouseEvent.pointerProperties().pointerType)] = false; |
| 548 } | 537 } |
| 549 | 538 |
| 550 processCaptureAndPositionOfPointerEvent(pointerEvent, target, | 539 EventTarget* pointerEventTarget = processCaptureAndPositionOfPointerEvent(po
interEvent, target, |
| 551 lastNodeUnderMouse, mouseEvent, true, true); | 540 lastNodeUnderMouse, mouseEvent, true, true); |
| 552 | 541 |
| 542 if (pointerEventTarget) { |
| 543 // This is to prevent incorrect boundary events if capturing transition
was |
| 544 // delayed. |
| 545 *newNodeUnderMouse = pointerEventTarget->toNode(); |
| 546 DCHECK(*newNodeUnderMouse); |
| 547 } |
| 548 |
| 553 EventTarget* effectiveTarget = | 549 EventTarget* effectiveTarget = |
| 554 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()); | 550 getEffectiveTargetForPointerEvent(pointerEventTarget, pointerEvent->poin
terId()); |
| 555 | 551 |
| 556 WebInputEventResult result = | 552 WebInputEventResult result = |
| 557 dispatchPointerEvent(effectiveTarget, pointerEvent); | 553 dispatchPointerEvent(effectiveTarget, pointerEvent); |
| 558 | 554 |
| 559 if (result != WebInputEventResult::NotHandled | 555 if (result != WebInputEventResult::NotHandled |
| 560 && pointerEvent->type() == EventTypeNames::pointerdown | 556 && pointerEvent->type() == EventTypeNames::pointerdown |
| 561 && pointerEvent->isPrimary()) { | 557 && pointerEvent->isPrimary()) { |
| 562 m_preventMouseEventForPointerType[toPointerTypeIndex( | 558 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 563 mouseEvent.pointerProperties().pointerType)] = true; | 559 mouseEvent.pointerProperties().pointerType)] = true; |
| 564 } | 560 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 575 break; | 571 break; |
| 576 } | 572 } |
| 577 } | 573 } |
| 578 } | 574 } |
| 579 result = EventHandler::mergeEventResult(result, | 575 result = EventHandler::mergeEventResult(result, |
| 580 dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent, | 576 dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent, |
| 581 nullptr, clickCount)); | 577 nullptr, clickCount)); |
| 582 } | 578 } |
| 583 | 579 |
| 584 if (pointerEvent->buttons() == 0) { | 580 if (pointerEvent->buttons() == 0) { |
| 585 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr); | 581 // Send the lostpointercapture right away. |
| 582 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr, true); |
| 586 if (pointerEvent->isPrimary()) { | 583 if (pointerEvent->isPrimary()) { |
| 587 m_preventMouseEventForPointerType[toPointerTypeIndex( | 584 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 588 mouseEvent.pointerProperties().pointerType)] = false; | 585 mouseEvent.pointerProperties().pointerType)] = false; |
| 589 } | 586 } |
| 590 } | 587 } |
| 591 | 588 |
| 592 return result; | 589 return result; |
| 593 } | 590 } |
| 594 | 591 |
| 595 PointerEventManager::PointerEventManager(LocalFrame* frame) | 592 PointerEventManager::PointerEventManager(LocalFrame* frame) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 613 m_touchIdsForCanceledPointerdowns.clear(); | 610 m_touchIdsForCanceledPointerdowns.clear(); |
| 614 m_nodeUnderPointer.clear(); | 611 m_nodeUnderPointer.clear(); |
| 615 m_pointerCaptureTarget.clear(); | 612 m_pointerCaptureTarget.clear(); |
| 616 m_pendingPointerCaptureTarget.clear(); | 613 m_pendingPointerCaptureTarget.clear(); |
| 617 } | 614 } |
| 618 | 615 |
| 619 bool PointerEventManager::getPointerCaptureState(int pointerId, | 616 bool PointerEventManager::getPointerCaptureState(int pointerId, |
| 620 EventTarget** pointerCaptureTarget, | 617 EventTarget** pointerCaptureTarget, |
| 621 EventTarget** pendingPointerCaptureTarget) | 618 EventTarget** pendingPointerCaptureTarget) |
| 622 { | 619 { |
| 623 PointerCapturingMap::iterator it; | 620 PointerCapturingMap::const_iterator it; |
| 624 | 621 |
| 625 it = m_pointerCaptureTarget.find(pointerId); | 622 it = m_pointerCaptureTarget.find(pointerId); |
| 626 EventTarget* pointercaptureTargetTemp = (it != m_pointerCaptureTarget.end())
? it->value : nullptr; | 623 EventTarget* pointerCaptureTargetTemp = (it != m_pointerCaptureTarget.end())
? it->value : nullptr; |
| 627 it = m_pendingPointerCaptureTarget.find(pointerId); | 624 it = m_pendingPointerCaptureTarget.find(pointerId); |
| 628 EventTarget* pendingPointercaptureTargetTemp = (it != m_pendingPointerCaptur
eTarget.end()) ? it->value : nullptr; | 625 EventTarget* pendingPointercaptureTargetTemp = (it != m_pendingPointerCaptur
eTarget.end()) ? it->value : nullptr; |
| 629 | 626 |
| 630 if (pointerCaptureTarget) | 627 if (pointerCaptureTarget) |
| 631 *pointerCaptureTarget = pointercaptureTargetTemp; | 628 *pointerCaptureTarget = pointerCaptureTargetTemp; |
| 632 if (pendingPointerCaptureTarget) | 629 if (pendingPointerCaptureTarget) |
| 633 *pendingPointerCaptureTarget = pendingPointercaptureTargetTemp; | 630 *pendingPointerCaptureTarget = pendingPointercaptureTargetTemp; |
| 634 | 631 |
| 635 return pointercaptureTargetTemp != pendingPointercaptureTargetTemp; | 632 return pointerCaptureTargetTemp != pendingPointercaptureTargetTemp; |
| 636 } | 633 } |
| 637 | 634 |
| 638 void PointerEventManager::processCaptureAndPositionOfPointerEvent( | 635 EventTarget* PointerEventManager::processCaptureAndPositionOfPointerEvent( |
| 639 PointerEvent* pointerEvent, | 636 PointerEvent* pointerEvent, |
| 640 EventTarget* hitTestTarget, | 637 EventTarget* hitTestTarget, |
| 641 EventTarget* lastNodeUnderMouse, | 638 EventTarget* lastNodeUnderMouse, |
| 642 const PlatformMouseEvent& mouseEvent, | 639 const PlatformMouseEvent& mouseEvent, |
| 643 bool sendMouseEvent, bool setPointerPosition) | 640 bool sendMouseEvent, bool setPointerPosition) |
| 644 { | 641 { |
| 645 bool isCaptureChanged = false; | 642 if (setPointerPosition) { |
| 643 processPendingPointerCapture(pointerEvent->pointerId()); |
| 646 | 644 |
| 647 if (setPointerPosition) { | 645 PointerCapturingMap::const_iterator it = m_pointerCaptureTarget.find(poi
nterEvent->pointerId()); |
| 648 isCaptureChanged = processPendingPointerCapture(pointerEvent, | 646 if (EventTarget* pointercaptureTarget = (it != m_pointerCaptureTarget.en
d()) ? it->value : nullptr) |
| 649 hitTestTarget, mouseEvent, sendMouseEvent); | 647 hitTestTarget = pointercaptureTarget; |
| 650 // If there was a change in capturing processPendingPointerCapture has | 648 |
| 651 // already taken care of transition events. So we don't need to send the | 649 setNodeUnderPointer(pointerEvent, hitTestTarget); |
| 652 // transition events here. | |
| 653 setNodeUnderPointer(pointerEvent, hitTestTarget, !isCaptureChanged); | |
| 654 } | 650 } |
| 655 if (sendMouseEvent && !isCaptureChanged) { | 651 if (sendMouseEvent) { |
| 656 // lastNodeUnderMouse is needed here because it is still stored in Event
Handler. | 652 // lastNodeUnderMouse is needed here because it is still stored in Event
Handler. |
| 657 sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget, | 653 sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget, |
| 658 pointerEvent, mouseEvent, true); | 654 pointerEvent, mouseEvent, true); |
| 659 } | 655 } |
| 656 return hitTestTarget; |
| 660 } | 657 } |
| 661 | 658 |
| 662 void PointerEventManager::immediatelyProcessPendingPointerCapture(int pointerId) | 659 void PointerEventManager::processPendingPointerCapture(int pointerId) |
| 663 { | 660 { |
| 664 EventTarget* pointerCaptureTarget; | 661 EventTarget* pointerCaptureTarget; |
| 665 EventTarget* pendingPointerCaptureTarget; | 662 EventTarget* pendingPointerCaptureTarget; |
| 666 const bool isCaptureChanged = getPointerCaptureState(pointerId, | 663 const bool isCaptureChanged = getPointerCaptureState(pointerId, |
| 667 &pointerCaptureTarget, &pendingPointerCaptureTarget); | 664 &pointerCaptureTarget, &pendingPointerCaptureTarget); |
| 668 | 665 |
| 669 if (!isCaptureChanged) | 666 if (!isCaptureChanged) |
| 670 return; | 667 return; |
| 671 | 668 |
| 669 // We have to check whether the pointerCaptureTarget is null or not because |
| 670 // we are checking whether it is still connected to its document or not. |
| 672 if (pointerCaptureTarget) { | 671 if (pointerCaptureTarget) { |
| 673 // Re-target lostpointercapture to the document when the element is | 672 // Re-target lostpointercapture to the document when the element is |
| 674 // no longer participating in the tree. | 673 // no longer participating in the tree. |
| 675 EventTarget* target = pointerCaptureTarget; | 674 EventTarget* target = pointerCaptureTarget; |
| 676 if (target->toNode() | 675 if (target->toNode() |
| 677 && !target->toNode()->isConnected()) { | 676 && !target->toNode()->isConnected()) { |
| 678 target = target->toNode()->ownerDocument(); | 677 target = target->toNode()->ownerDocument(); |
| 679 } | 678 } |
| 680 dispatchPointerEvent(target, | 679 dispatchPointerEvent(target, |
| 681 m_pointerEventFactory.createPointerCaptureEvent( | 680 m_pointerEventFactory.createPointerCaptureEvent( |
| 682 pointerId, EventTypeNames::lostpointercapture)); | 681 pointerId, EventTypeNames::lostpointercapture)); |
| 683 } | 682 } |
| 683 // Note that If pendingPointerCaptureTarget is null dispatchPointerEvent |
| 684 // automatically does nothing. |
| 684 dispatchPointerEvent(pendingPointerCaptureTarget, | 685 dispatchPointerEvent(pendingPointerCaptureTarget, |
| 685 m_pointerEventFactory.createPointerCaptureEvent( | 686 m_pointerEventFactory.createPointerCaptureEvent( |
| 686 pointerId, EventTypeNames::gotpointercapture)); | 687 pointerId, EventTypeNames::gotpointercapture)); |
| 687 | 688 |
| 688 // Setting |m_pointerCaptureTarget| comes at the end to prevent the infinite | 689 // Setting |m_pointerCaptureTarget| comes at the end to prevent the infinite |
| 689 // loop if js calls set/releasepointercapture in got/lostpointercapture | 690 // loop if js calls set/releasepointercapture in got/lostpointercapture |
| 690 // handlers. | 691 // handlers. |
| 691 if (pendingPointerCaptureTarget) | 692 if (pendingPointerCaptureTarget) |
| 692 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); | 693 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); |
| 693 else | 694 else |
| 694 m_pointerCaptureTarget.remove(pointerId); | 695 m_pointerCaptureTarget.remove(pointerId); |
| 695 } | 696 } |
| 696 | 697 |
| 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( | 698 void PointerEventManager::removeTargetFromPointerCapturingMapping( |
| 771 PointerCapturingMap& map, const EventTarget* target) | 699 PointerCapturingMap& map, const EventTarget* target) |
| 772 { | 700 { |
| 773 // We could have kept a reverse mapping to make this deletion possibly | 701 // 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 | 702 // 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 | 703 // the performance improvement considering there might not be a lot of |
| 776 // active pointer or pointer captures at the same time. | 704 // active pointer or pointer captures at the same time. |
| 777 PointerCapturingMap tmp = map; | 705 PointerCapturingMap tmp = map; |
| 778 for (PointerCapturingMap::iterator it = tmp.begin(); it != tmp.end(); ++it)
{ | 706 for (PointerCapturingMap::iterator it = tmp.begin(); it != tmp.end(); ++it)
{ |
| 779 if (it->value == target) | 707 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 | 747 // |m_pointercaptureTarget|. |m_pointercaptureTarget| holds the element |
| 820 // that had the capture until now and has been receiving the pointerevents | 748 // that had the capture until now and has been receiving the pointerevents |
| 821 // but |m_pendingPointerCaptureTarget| indicated the element that gets the | 749 // 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 | 750 // 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. | 751 // capturing of a particular |pointerId|. See crbug.com/614481. |
| 824 if (m_pendingPointerCaptureTarget.get(pointerId) == target) | 752 if (m_pendingPointerCaptureTarget.get(pointerId) == target) |
| 825 modifyPendingPointerCapture(pointerId, nullptr); | 753 modifyPendingPointerCapture(pointerId, nullptr); |
| 826 } | 754 } |
| 827 | 755 |
| 828 void PointerEventManager::modifyPendingPointerCapture( | 756 void PointerEventManager::modifyPendingPointerCapture( |
| 829 int pointerId, EventTarget* target) | 757 int pointerId, EventTarget* target, bool immediate) |
| 830 { | 758 { |
| 831 bool wasCaptureStationary = !getPointerCaptureState(pointerId, nullptr, null
ptr); | 759 bool wasCaptureStationary = !getPointerCaptureState(pointerId, nullptr, null
ptr); |
| 832 | 760 |
| 833 if (target) | 761 if (target) |
| 834 m_pendingPointerCaptureTarget.set(pointerId, target); | 762 m_pendingPointerCaptureTarget.set(pointerId, target); |
| 835 else | 763 else |
| 836 m_pendingPointerCaptureTarget.remove(pointerId); | 764 m_pendingPointerCaptureTarget.remove(pointerId); |
| 837 | 765 |
| 838 // Only queue the processing pending pointer capture if the pending | 766 // Only queue the processing pending pointer capture if the pending |
| 839 // capture target and capture target were the same to prevent infinite | 767 // capture target and capture target were the same to prevent infinite |
| 840 // got/lostpointercapture event sequence. | 768 // got/lostpointercapture event sequence. |
| 841 // See https://github.com/w3c/pointerevents/issues/32. | 769 // See https://github.com/w3c/pointerevents/issues/32. |
| 842 if (wasCaptureStationary) { | 770 if (immediate) { |
| 771 processPendingPointerCapture(pointerId); |
| 772 } else if (wasCaptureStationary) { |
| 843 m_frame->document()->postTask( | 773 m_frame->document()->postTask( |
| 844 BLINK_FROM_HERE, | 774 BLINK_FROM_HERE, |
| 845 createSameThreadTask( | 775 createSameThreadTask( |
| 846 &EventHandler::immediatelyProcessPendingPointerCapture, | 776 &EventHandler::immediatelyProcessPendingPointerCapture, |
| 847 wrapWeakPersistent(&m_frame->eventHandler()), pointerId)); | 777 wrapWeakPersistent(&m_frame->eventHandler()), pointerId)); |
| 848 } | 778 } |
| 849 } | 779 } |
| 850 | 780 |
| 851 bool PointerEventManager::isActive(const int pointerId) const | 781 bool PointerEventManager::isActive(const int pointerId) const |
| 852 { | 782 { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 867 uint32_t firstId = m_touchIdsForCanceledPointerdowns.first(); | 797 uint32_t firstId = m_touchIdsForCanceledPointerdowns.first(); |
| 868 if (firstId > uniqueTouchEventId) | 798 if (firstId > uniqueTouchEventId) |
| 869 return false; | 799 return false; |
| 870 m_touchIdsForCanceledPointerdowns.takeFirst(); | 800 m_touchIdsForCanceledPointerdowns.takeFirst(); |
| 871 if (firstId == uniqueTouchEventId) | 801 if (firstId == uniqueTouchEventId) |
| 872 return true; | 802 return true; |
| 873 } | 803 } |
| 874 return false; | 804 return false; |
| 875 } | 805 } |
| 876 | 806 |
| 807 EventTarget* PointerEventManager::getMouseCapturingNode() |
| 808 { |
| 809 return getCapturingNode(PointerEventFactory::s_mouseId); |
| 810 } |
| 811 |
| 877 DEFINE_TRACE(PointerEventManager) | 812 DEFINE_TRACE(PointerEventManager) |
| 878 { | 813 { |
| 879 visitor->trace(m_frame); | 814 visitor->trace(m_frame); |
| 880 visitor->trace(m_nodeUnderPointer); | 815 visitor->trace(m_nodeUnderPointer); |
| 881 visitor->trace(m_pointerCaptureTarget); | 816 visitor->trace(m_pointerCaptureTarget); |
| 882 visitor->trace(m_pendingPointerCaptureTarget); | 817 visitor->trace(m_pendingPointerCaptureTarget); |
| 883 visitor->trace(m_touchEventManager); | 818 visitor->trace(m_touchEventManager); |
| 884 } | 819 } |
| 885 | 820 |
| 886 | 821 |
| 887 } // namespace blink | 822 } // namespace blink |
| OLD | NEW |