Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: third_party/WebKit/Source/core/input/PointerEventManager.cpp

Issue 2174863002: Change mouse pointer event targets to the capturing node (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix redundant compat mouse boundary events Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698