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

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

Issue 2193473002: Revert "Send got/lostpointercapture immediately if possible" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
« no previous file with comments | « third_party/WebKit/Source/core/input/PointerEventManager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
9 #include "core/dom/shadow/FlatTreeTraversal.h" 8 #include "core/dom/shadow/FlatTreeTraversal.h"
10 #include "core/events/MouseEvent.h" 9 #include "core/events/MouseEvent.h"
11 #include "core/frame/FrameView.h" 10 #include "core/frame/FrameView.h"
12 #include "core/frame/UseCounter.h" 11 #include "core/frame/UseCounter.h"
13 #include "core/html/HTMLCanvasElement.h" 12 #include "core/html/HTMLCanvasElement.h"
14 #include "core/input/EventHandler.h" 13 #include "core/input/EventHandler.h"
15 #include "core/input/TouchActionUtil.h" 14 #include "core/input/TouchActionUtil.h"
16 #include "core/page/ChromeClient.h" 15 #include "core/page/ChromeClient.h"
17 #include "core/page/Page.h" 16 #include "core/page/Page.h"
18 #include "platform/PlatformTouchEvent.h" 17 #include "platform/PlatformTouchEvent.h"
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 362
364 processCaptureAndPositionOfPointerEvent(pointerEvent, target); 363 processCaptureAndPositionOfPointerEvent(pointerEvent, target);
365 364
366 // TODO(nzolghadr): This event follows implicit TE capture. The actual t arget 365 // 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? 366 // would depend on PE capturing. Perhaps need to split TE/PE event path upstream?
368 // crbug.com/579553. 367 // crbug.com/579553.
369 dispatchPointerEvent( 368 dispatchPointerEvent(
370 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()) , 369 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()) ,
371 pointerEvent); 370 pointerEvent);
372 371
373 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr); 372 releasePointerCapture(pointerEvent->pointerId());
374 373
375 // Sending the leave/out events and lostpointercapture 374 // Sending the leave/out events and lostpointercapture
376 // because the next touch event will have a different id. So delayed 375 // because the next touch event will have a different id. So delayed
377 // sending of lostpointercapture won't work here. 376 // sending of lostpointercapture won't work here.
378 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr); 377 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr);
379 378
380 removePointer(pointerEvent); 379 removePointer(pointerEvent);
381 } 380 }
382 } 381 }
383 382
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 // Setting the implicit capture for touch 508 // Setting the implicit capture for touch
510 if (pointerEvent->type() == EventTypeNames::pointerdown) 509 if (pointerEvent->type() == EventTypeNames::pointerdown)
511 setPointerCapture(pointerEvent->pointerId(), target); 510 setPointerCapture(pointerEvent->pointerId(), target);
512 511
513 WebInputEventResult result = dispatchPointerEvent( 512 WebInputEventResult result = dispatchPointerEvent(
514 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()), 513 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()),
515 pointerEvent); 514 pointerEvent);
516 515
517 if (pointerEvent->type() == EventTypeNames::pointerup 516 if (pointerEvent->type() == EventTypeNames::pointerup
518 || pointerEvent->type() == EventTypeNames::pointercancel) { 517 || pointerEvent->type() == EventTypeNames::pointercancel) {
519 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr); 518 releasePointerCapture(pointerEvent->pointerId());
520 519
521 // Sending the leave/out events and lostpointercapture 520 // Sending the leave/out events and lostpointercapture
522 // because the next touch event will have a different id. So delayed 521 // because the next touch event will have a different id. So delayed
523 // sending of lostpointercapture won't work here. 522 // sending of lostpointercapture won't work here.
524 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr); 523 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr);
525 524
526 removePointer(pointerEvent); 525 removePointer(pointerEvent);
527 } 526 }
528 527
529 return result; 528 return result;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 break; 574 break;
576 } 575 }
577 } 576 }
578 } 577 }
579 result = EventHandler::mergeEventResult(result, 578 result = EventHandler::mergeEventResult(result,
580 dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent, 579 dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent,
581 nullptr, clickCount)); 580 nullptr, clickCount));
582 } 581 }
583 582
584 if (pointerEvent->buttons() == 0) { 583 if (pointerEvent->buttons() == 0) {
585 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr); 584 releasePointerCapture(pointerEvent->pointerId());
586 if (pointerEvent->isPrimary()) { 585 if (pointerEvent->isPrimary()) {
587 m_preventMouseEventForPointerType[toPointerTypeIndex( 586 m_preventMouseEventForPointerType[toPointerTypeIndex(
588 mouseEvent.pointerProperties().pointerType)] = false; 587 mouseEvent.pointerProperties().pointerType)] = false;
589 } 588 }
590 } 589 }
591 590
592 return result; 591 return result;
593 } 592 }
594 593
595 PointerEventManager::PointerEventManager(LocalFrame* frame) 594 PointerEventManager::PointerEventManager(LocalFrame* frame)
(...skipping 13 matching lines...) Expand all
609 entry = false; 608 entry = false;
610 m_touchEventManager.clear(); 609 m_touchEventManager.clear();
611 m_inCanceledStateForPointerTypeTouch = false; 610 m_inCanceledStateForPointerTypeTouch = false;
612 m_pointerEventFactory.clear(); 611 m_pointerEventFactory.clear();
613 m_touchIdsForCanceledPointerdowns.clear(); 612 m_touchIdsForCanceledPointerdowns.clear();
614 m_nodeUnderPointer.clear(); 613 m_nodeUnderPointer.clear();
615 m_pointerCaptureTarget.clear(); 614 m_pointerCaptureTarget.clear();
616 m_pendingPointerCaptureTarget.clear(); 615 m_pendingPointerCaptureTarget.clear();
617 } 616 }
618 617
619 bool PointerEventManager::getPointerCaptureState(int pointerId,
620 EventTarget** pointerCaptureTarget,
621 EventTarget** pendingPointerCaptureTarget)
622 {
623 PointerCapturingMap::iterator it;
624
625 it = m_pointerCaptureTarget.find(pointerId);
626 EventTarget* pointercaptureTargetTemp = (it != m_pointerCaptureTarget.end()) ? it->value : nullptr;
627 it = m_pendingPointerCaptureTarget.find(pointerId);
628 EventTarget* pendingPointercaptureTargetTemp = (it != m_pendingPointerCaptur eTarget.end()) ? it->value : nullptr;
629
630 if (pointerCaptureTarget)
631 *pointerCaptureTarget = pointercaptureTargetTemp;
632 if (pendingPointerCaptureTarget)
633 *pendingPointerCaptureTarget = pendingPointercaptureTargetTemp;
634
635 return pointercaptureTargetTemp != pendingPointercaptureTargetTemp;
636 }
637
638 void PointerEventManager::processCaptureAndPositionOfPointerEvent( 618 void PointerEventManager::processCaptureAndPositionOfPointerEvent(
639 PointerEvent* pointerEvent, 619 PointerEvent* pointerEvent,
640 EventTarget* hitTestTarget, 620 EventTarget* hitTestTarget,
641 EventTarget* lastNodeUnderMouse, 621 EventTarget* lastNodeUnderMouse,
642 const PlatformMouseEvent& mouseEvent, 622 const PlatformMouseEvent& mouseEvent,
643 bool sendMouseEvent, bool setPointerPosition) 623 bool sendMouseEvent, bool setPointerPosition)
644 { 624 {
645 bool isCaptureChanged = false; 625 bool isCaptureChanged = false;
646 626
647 if (setPointerPosition) { 627 if (setPointerPosition) {
648 isCaptureChanged = processPendingPointerCapture(pointerEvent, 628 isCaptureChanged = processPendingPointerCapture(pointerEvent,
649 hitTestTarget, mouseEvent, sendMouseEvent); 629 hitTestTarget, mouseEvent, sendMouseEvent);
650 // If there was a change in capturing processPendingPointerCapture has 630 // If there was a change in capturing processPendingPointerCapture has
651 // already taken care of transition events. So we don't need to send the 631 // already taken care of transition events. So we don't need to send the
652 // transition events here. 632 // transition events here.
653 setNodeUnderPointer(pointerEvent, hitTestTarget, !isCaptureChanged); 633 setNodeUnderPointer(pointerEvent, hitTestTarget, !isCaptureChanged);
654 } 634 }
655 if (sendMouseEvent && !isCaptureChanged) { 635 if (sendMouseEvent && !isCaptureChanged) {
656 // lastNodeUnderMouse is needed here because it is still stored in Event Handler. 636 // lastNodeUnderMouse is needed here because it is still stored in Event Handler.
657 sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget, 637 sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget,
658 pointerEvent, mouseEvent, true); 638 pointerEvent, mouseEvent, true);
659 } 639 }
660 } 640 }
661 641
662 void PointerEventManager::immediatelyProcessPendingPointerCapture(int pointerId)
663 {
664 EventTarget* pointerCaptureTarget;
665 EventTarget* pendingPointerCaptureTarget;
666 const bool isCaptureChanged = getPointerCaptureState(pointerId,
667 &pointerCaptureTarget, &pendingPointerCaptureTarget);
668
669 if (!isCaptureChanged)
670 return;
671
672 if (pointerCaptureTarget) {
673 // Re-target lostpointercapture to the document when the element is
674 // no longer participating in the tree.
675 EventTarget* target = pointerCaptureTarget;
676 if (target->toNode()
677 && !target->toNode()->isConnected()) {
678 target = target->toNode()->ownerDocument();
679 }
680 dispatchPointerEvent(target,
681 m_pointerEventFactory.createPointerCaptureEvent(
682 pointerId, EventTypeNames::lostpointercapture));
683 }
684 dispatchPointerEvent(pendingPointerCaptureTarget,
685 m_pointerEventFactory.createPointerCaptureEvent(
686 pointerId, EventTypeNames::gotpointercapture));
687
688 // Setting |m_pointerCaptureTarget| comes at the end to prevent the infinite
689 // loop if js calls set/releasepointercapture in got/lostpointercapture
690 // handlers.
691 if (pendingPointerCaptureTarget)
692 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget);
693 else
694 m_pointerCaptureTarget.remove(pointerId);
695 }
696
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( 642 bool PointerEventManager::processPendingPointerCapture(
700 PointerEvent* pointerEvent, 643 PointerEvent* pointerEvent,
701 EventTarget* hitTestTarget, 644 EventTarget* hitTestTarget,
702 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) 645 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent)
703 { 646 {
704 int pointerId = pointerEvent->pointerId(); 647 int pointerId = pointerEvent->pointerId();
705 EventTarget* pointerCaptureTarget; 648 EventTarget* pointerCaptureTarget =
706 EventTarget* pendingPointerCaptureTarget; 649 m_pointerCaptureTarget.contains(pointerId)
707 const bool isCaptureChanged = getPointerCaptureState(pointerId, 650 ? m_pointerCaptureTarget.get(pointerId) : nullptr;
708 &pointerCaptureTarget, &pendingPointerCaptureTarget); 651 EventTarget* pendingPointerCaptureTarget =
652 m_pendingPointerCaptureTarget.contains(pointerId)
653 ? m_pendingPointerCaptureTarget.get(pointerId) : nullptr;
709 const EventTargetAttributes &nodeUnderPointerAtt = 654 const EventTargetAttributes &nodeUnderPointerAtt =
710 m_nodeUnderPointer.contains(pointerId) 655 m_nodeUnderPointer.contains(pointerId)
711 ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes(); 656 ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes();
657 const bool isCaptureChanged =
658 pointerCaptureTarget != pendingPointerCaptureTarget;
712 659
713 if (isCaptureChanged) { 660 if (isCaptureChanged) {
714 if ((hitTestTarget != nodeUnderPointerAtt.target 661 if ((hitTestTarget != nodeUnderPointerAtt.target
715 || (pendingPointerCaptureTarget 662 || (pendingPointerCaptureTarget
716 && pendingPointerCaptureTarget != nodeUnderPointerAtt.target)) 663 && pendingPointerCaptureTarget != nodeUnderPointerAtt.target))
717 && nodeUnderPointerAtt.hasRecievedOverEvent) { 664 && nodeUnderPointerAtt.hasRecievedOverEvent) {
718 if (sendMouseEvent) { 665 if (sendMouseEvent) {
719 // Send pointer event transitions as the line after this if 666 // Send pointer event transitions as the line after this if
720 // block sends the mouse events 667 // block sends the mouse events
721 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr, 668 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr,
722 pointerEvent); 669 pointerEvent);
723 } 670 }
724 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr, 671 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr,
725 pointerEvent, mouseEvent, sendMouseEvent); 672 pointerEvent, mouseEvent, sendMouseEvent);
726 } 673 }
727 if (pointerCaptureTarget) { 674 if (pointerCaptureTarget) {
728 // Re-target lostpointercapture to the document when the element is 675 // Re-target lostpointercapture to the document when the element is
729 // no longer participating in the tree. 676 // no longer participating in the tree.
730 EventTarget* target = pointerCaptureTarget; 677 EventTarget* target = pointerCaptureTarget;
731 if (target->toNode() 678 if (target->toNode()
732 && !target->toNode()->isConnected()) { 679 && !target->toNode()->isConnected()) {
733 target = target->toNode()->ownerDocument(); 680 target = target->toNode()->ownerDocument();
734 } 681 }
735 dispatchPointerEvent(target, 682 dispatchPointerEvent(target,
736 m_pointerEventFactory.createPointerCaptureEvent( 683 m_pointerEventFactory.createPointerCaptureEvent(
737 pointerId, EventTypeNames::lostpointercapture)); 684 pointerEvent, EventTypeNames::lostpointercapture));
738 } 685 }
739 } 686 }
740 687
741 // Set pointerCaptureTarget from pendingPointerCaptureTarget. This does 688 // Set pointerCaptureTarget from pendingPointerCaptureTarget. This does
742 // affect the behavior of sendBoundaryEvents function. So the 689 // affect the behavior of sendBoundaryEvents function. So the
743 // ordering of the surrounding blocks of code for sending transition events 690 // ordering of the surrounding blocks of code for sending transition events
744 // are important. 691 // are important.
745 if (pendingPointerCaptureTarget) 692 if (pendingPointerCaptureTarget)
746 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); 693 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget);
747 else 694 else
748 m_pointerCaptureTarget.remove(pointerId); 695 m_pointerCaptureTarget.remove(pointerId);
749 696
750 if (isCaptureChanged) { 697 if (isCaptureChanged) {
751 dispatchPointerEvent(pendingPointerCaptureTarget, 698 dispatchPointerEvent(pendingPointerCaptureTarget,
752 m_pointerEventFactory.createPointerCaptureEvent( 699 m_pointerEventFactory.createPointerCaptureEvent(
753 pointerId, EventTypeNames::gotpointercapture)); 700 pointerEvent, EventTypeNames::gotpointercapture));
754 if ((pendingPointerCaptureTarget == hitTestTarget 701 if ((pendingPointerCaptureTarget == hitTestTarget
755 || !pendingPointerCaptureTarget) 702 || !pendingPointerCaptureTarget)
756 && (nodeUnderPointerAtt.target != hitTestTarget 703 && (nodeUnderPointerAtt.target != hitTestTarget
757 || !nodeUnderPointerAtt.hasRecievedOverEvent)) { 704 || !nodeUnderPointerAtt.hasRecievedOverEvent)) {
758 if (sendMouseEvent) { 705 if (sendMouseEvent) {
759 // Send pointer event transitions as the line after this if 706 // Send pointer event transitions as the line after this if
760 // block sends the mouse events 707 // block sends the mouse events
761 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent); 708 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent);
762 } 709 }
763 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent, 710 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 } 747 }
801 748
802 void PointerEventManager::elementRemoved(EventTarget* target) 749 void PointerEventManager::elementRemoved(EventTarget* target)
803 { 750 {
804 removeTargetFromPointerCapturingMapping(m_pendingPointerCaptureTarget, targe t); 751 removeTargetFromPointerCapturingMapping(m_pendingPointerCaptureTarget, targe t);
805 } 752 }
806 753
807 void PointerEventManager::setPointerCapture(int pointerId, EventTarget* target) 754 void PointerEventManager::setPointerCapture(int pointerId, EventTarget* target)
808 { 755 {
809 UseCounter::count(m_frame->document(), UseCounter::PointerEventSetCapture); 756 UseCounter::count(m_frame->document(), UseCounter::PointerEventSetCapture);
810 if (m_pointerEventFactory.isActiveButtonsState(pointerId)) { 757 if (m_pointerEventFactory.isActiveButtonsState(pointerId))
811 modifyPendingPointerCapture(pointerId, target); 758 m_pendingPointerCaptureTarget.set(pointerId, target);
812 }
813 } 759 }
814 760
815 void PointerEventManager::releasePointerCapture(int pointerId, EventTarget* targ et) 761 void PointerEventManager::releasePointerCapture(int pointerId, EventTarget* targ et)
816 { 762 {
817 // Only the element that is going to get the next pointer event can release 763 // Only the element that is going to get the next pointer event can release
818 // the capture. Note that this might be different from 764 // the capture. Note that this might be different from
819 // |m_pointercaptureTarget|. |m_pointercaptureTarget| holds the element 765 // |m_pointercaptureTarget|. |m_pointercaptureTarget| holds the element
820 // that had the capture until now and has been receiving the pointerevents 766 // that had the capture until now and has been receiving the pointerevents
821 // but |m_pendingPointerCaptureTarget| indicated the element that gets the 767 // 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 768 // 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. 769 // capturing of a particular |pointerId|. See crbug.com/614481.
824 if (m_pendingPointerCaptureTarget.get(pointerId) == target) 770 if (m_pendingPointerCaptureTarget.get(pointerId) == target)
825 modifyPendingPointerCapture(pointerId, nullptr); 771 releasePointerCapture(pointerId);
826 } 772 }
827 773
828 void PointerEventManager::modifyPendingPointerCapture( 774 void PointerEventManager::releasePointerCapture(int pointerId)
829 int pointerId, EventTarget* target)
830 { 775 {
831 bool wasCaptureStationary = !getPointerCaptureState(pointerId, nullptr, null ptr); 776 m_pendingPointerCaptureTarget.remove(pointerId);
832
833 if (target)
834 m_pendingPointerCaptureTarget.set(pointerId, target);
835 else
836 m_pendingPointerCaptureTarget.remove(pointerId);
837
838 // Only queue the processing pending pointer capture if the pending
839 // capture target and capture target were the same to prevent infinite
840 // got/lostpointercapture event sequence.
841 // See https://github.com/w3c/pointerevents/issues/32.
842 if (wasCaptureStationary) {
843 m_frame->document()->postTask(
844 BLINK_FROM_HERE,
845 createSameThreadTask(
846 &EventHandler::immediatelyProcessPendingPointerCapture,
847 wrapWeakPersistent(&m_frame->eventHandler()), pointerId));
848 }
849 } 777 }
850 778
851 bool PointerEventManager::isActive(const int pointerId) const 779 bool PointerEventManager::isActive(const int pointerId) const
852 { 780 {
853 return m_pointerEventFactory.isActive(pointerId); 781 return m_pointerEventFactory.isActive(pointerId);
854 } 782 }
855 783
856 bool PointerEventManager::isAnyTouchActive() const 784 bool PointerEventManager::isAnyTouchActive() const
857 { 785 {
858 return m_touchEventManager.isAnyTouchActive(); 786 return m_touchEventManager.isAnyTouchActive();
(...skipping 19 matching lines...) Expand all
878 { 806 {
879 visitor->trace(m_frame); 807 visitor->trace(m_frame);
880 visitor->trace(m_nodeUnderPointer); 808 visitor->trace(m_nodeUnderPointer);
881 visitor->trace(m_pointerCaptureTarget); 809 visitor->trace(m_pointerCaptureTarget);
882 visitor->trace(m_pendingPointerCaptureTarget); 810 visitor->trace(m_pendingPointerCaptureTarget);
883 visitor->trace(m_touchEventManager); 811 visitor->trace(m_touchEventManager);
884 } 812 }
885 813
886 814
887 } // namespace blink 815 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/input/PointerEventManager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698