| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/renderer_host/input/touch_event_queue.h" | 5 #include "content/browser/renderer_host/input/touch_event_queue.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 // A sanity check on touches received to ensure that touch movement outside | 31 // A sanity check on touches received to ensure that touch movement outside |
| 32 // the platform slop region will cause scrolling. | 32 // the platform slop region will cause scrolling. |
| 33 const double kMaxConceivablePlatformSlopRegionLengthDipsSquared = 60. * 60.; | 33 const double kMaxConceivablePlatformSlopRegionLengthDipsSquared = 60. * 60.; |
| 34 | 34 |
| 35 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( | 35 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( |
| 36 const TouchEventWithLatencyInfo& event_to_cancel) { | 36 const TouchEventWithLatencyInfo& event_to_cancel) { |
| 37 TouchEventWithLatencyInfo event = event_to_cancel; | 37 TouchEventWithLatencyInfo event = event_to_cancel; |
| 38 WebTouchEventTraits::ResetTypeAndTouchStates( | 38 WebTouchEventTraits::ResetTypeAndTouchStates( |
| 39 WebInputEvent::TouchCancel, | 39 WebInputEvent::TouchCancel, |
| 40 // TODO(rbyers): Shouldn't we use a fresh timestamp? | 40 // TODO(rbyers): Shouldn't we use a fresh timestamp? |
| 41 event.event.timeStampSeconds, | 41 event.event.timeStampSeconds(), &event.event); |
| 42 &event.event); | |
| 43 return event; | 42 return event; |
| 44 } | 43 } |
| 45 | 44 |
| 46 bool ShouldTouchTriggerTimeout(const WebTouchEvent& event) { | 45 bool ShouldTouchTriggerTimeout(const WebTouchEvent& event) { |
| 47 return (event.type == WebInputEvent::TouchStart || | 46 return (event.type() == WebInputEvent::TouchStart || |
| 48 event.type == WebInputEvent::TouchMove) && | 47 event.type() == WebInputEvent::TouchMove) && |
| 49 event.dispatchType == WebInputEvent::Blocking; | 48 event.dispatchType == WebInputEvent::Blocking; |
| 50 } | 49 } |
| 51 | 50 |
| 52 // Compare all properties of touch points to determine the state. | 51 // Compare all properties of touch points to determine the state. |
| 53 bool HasPointChanged(const WebTouchPoint& point_1, | 52 bool HasPointChanged(const WebTouchPoint& point_1, |
| 54 const WebTouchPoint& point_2) { | 53 const WebTouchPoint& point_2) { |
| 55 DCHECK_EQ(point_1.id, point_2.id); | 54 DCHECK_EQ(point_1.id, point_2.id); |
| 56 if (point_1.screenPosition != point_2.screenPosition || | 55 if (point_1.screenPosition != point_2.screenPosition || |
| 57 point_1.position != point_2.position || | 56 point_1.position != point_2.position || |
| 58 point_1.radiusX != point_2.radiusX || | 57 point_1.radiusX != point_2.radiusX || |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 class TouchEventQueue::TouchMoveSlopSuppressor { | 290 class TouchEventQueue::TouchMoveSlopSuppressor { |
| 292 public: | 291 public: |
| 293 TouchMoveSlopSuppressor() : suppressing_touchmoves_(false) {} | 292 TouchMoveSlopSuppressor() : suppressing_touchmoves_(false) {} |
| 294 | 293 |
| 295 bool FilterEvent(const WebTouchEvent& event) { | 294 bool FilterEvent(const WebTouchEvent& event) { |
| 296 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { | 295 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { |
| 297 suppressing_touchmoves_ = true; | 296 suppressing_touchmoves_ = true; |
| 298 touch_start_location_ = gfx::PointF(event.touches[0].position); | 297 touch_start_location_ = gfx::PointF(event.touches[0].position); |
| 299 } | 298 } |
| 300 | 299 |
| 301 if (event.type == WebInputEvent::TouchEnd || | 300 if (event.type() == WebInputEvent::TouchEnd || |
| 302 event.type == WebInputEvent::TouchCancel) | 301 event.type() == WebInputEvent::TouchCancel) |
| 303 suppressing_touchmoves_ = false; | 302 suppressing_touchmoves_ = false; |
| 304 | 303 |
| 305 if (event.type != WebInputEvent::TouchMove) | 304 if (event.type() != WebInputEvent::TouchMove) |
| 306 return false; | 305 return false; |
| 307 | 306 |
| 308 if (suppressing_touchmoves_) { | 307 if (suppressing_touchmoves_) { |
| 309 if (event.touchesLength > 1) { | 308 if (event.touchesLength > 1) { |
| 310 suppressing_touchmoves_ = false; | 309 suppressing_touchmoves_ = false; |
| 311 } else if (event.movedBeyondSlopRegion) { | 310 } else if (event.movedBeyondSlopRegion) { |
| 312 suppressing_touchmoves_ = false; | 311 suppressing_touchmoves_ = false; |
| 313 } else { | 312 } else { |
| 314 // No sane slop region should be larger than 60 DIPs. | 313 // No sane slop region should be larger than 60 DIPs. |
| 315 DCHECK_LT((gfx::PointF(event.touches[0].position) - | 314 DCHECK_LT((gfx::PointF(event.touches[0].position) - |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 // We receive an ack for async touchmove from render. | 524 // We receive an ack for async touchmove from render. |
| 526 if (!ack_pending_async_touchmove_ids_.empty() && | 525 if (!ack_pending_async_touchmove_ids_.empty() && |
| 527 ack_pending_async_touchmove_ids_.front() == unique_touch_event_id) { | 526 ack_pending_async_touchmove_ids_.front() == unique_touch_event_id) { |
| 528 // Remove the first touchmove from the ack_pending_async_touchmove queue. | 527 // Remove the first touchmove from the ack_pending_async_touchmove queue. |
| 529 ack_pending_async_touchmove_ids_.pop_front(); | 528 ack_pending_async_touchmove_ids_.pop_front(); |
| 530 // Send the next pending async touch move once we receive all acks back. | 529 // Send the next pending async touch move once we receive all acks back. |
| 531 if (pending_async_touchmove_ && ack_pending_async_touchmove_ids_.empty()) { | 530 if (pending_async_touchmove_ && ack_pending_async_touchmove_ids_.empty()) { |
| 532 DCHECK(touch_queue_.empty()); | 531 DCHECK(touch_queue_.empty()); |
| 533 | 532 |
| 534 // Dispatch the next pending async touch move when time expires. | 533 // Dispatch the next pending async touch move when time expires. |
| 535 if (pending_async_touchmove_->event.timeStampSeconds >= | 534 if (pending_async_touchmove_->event.timeStampSeconds() >= |
| 536 last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec) { | 535 last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec) { |
| 537 FlushPendingAsyncTouchmove(); | 536 FlushPendingAsyncTouchmove(); |
| 538 } | 537 } |
| 539 } | 538 } |
| 540 return; | 539 return; |
| 541 } | 540 } |
| 542 | 541 |
| 543 DCHECK(!dispatching_touch_ack_); | 542 DCHECK(!dispatching_touch_ack_); |
| 544 dispatching_touch_ = false; | 543 dispatching_touch_ = false; |
| 545 | 544 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 } | 587 } |
| 589 | 588 |
| 590 void TouchEventQueue::ForwardNextEventToRenderer() { | 589 void TouchEventQueue::ForwardNextEventToRenderer() { |
| 591 TRACE_EVENT0("input", "TouchEventQueue::ForwardNextEventToRenderer"); | 590 TRACE_EVENT0("input", "TouchEventQueue::ForwardNextEventToRenderer"); |
| 592 | 591 |
| 593 DCHECK(!empty()); | 592 DCHECK(!empty()); |
| 594 DCHECK(!dispatching_touch_); | 593 DCHECK(!dispatching_touch_); |
| 595 TouchEventWithLatencyInfo touch = touch_queue_.front()->coalesced_event(); | 594 TouchEventWithLatencyInfo touch = touch_queue_.front()->coalesced_event(); |
| 596 | 595 |
| 597 if (send_touch_events_async_ && | 596 if (send_touch_events_async_ && |
| 598 touch.event.type == WebInputEvent::TouchMove) { | 597 touch.event.type() == WebInputEvent::TouchMove) { |
| 599 // Throttling touchmove's in a continuous touchmove stream while scrolling | 598 // Throttling touchmove's in a continuous touchmove stream while scrolling |
| 600 // reduces the risk of jank. However, it's still important that the web | 599 // reduces the risk of jank. However, it's still important that the web |
| 601 // application be sent touches at key points in the gesture stream, | 600 // application be sent touches at key points in the gesture stream, |
| 602 // e.g., when the application slop region is exceeded or touchmove | 601 // e.g., when the application slop region is exceeded or touchmove |
| 603 // coalescing fails because of different modifiers. | 602 // coalescing fails because of different modifiers. |
| 604 bool send_touchmove_now = size() > 1; | 603 bool send_touchmove_now = size() > 1; |
| 605 send_touchmove_now |= pending_async_touchmove_ && | 604 send_touchmove_now |= pending_async_touchmove_ && |
| 606 !pending_async_touchmove_->CanCoalesceWith(touch); | 605 !pending_async_touchmove_->CanCoalesceWith(touch); |
| 607 send_touchmove_now |= | 606 send_touchmove_now |= |
| 608 ack_pending_async_touchmove_ids_.empty() && | 607 ack_pending_async_touchmove_ids_.empty() && |
| 609 (touch.event.timeStampSeconds >= | 608 (touch.event.timeStampSeconds() >= |
| 610 last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec); | 609 last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec); |
| 611 | 610 |
| 612 if (!send_touchmove_now) { | 611 if (!send_touchmove_now) { |
| 613 if (!pending_async_touchmove_) { | 612 if (!pending_async_touchmove_) { |
| 614 pending_async_touchmove_.reset(new TouchEventWithLatencyInfo(touch)); | 613 pending_async_touchmove_.reset(new TouchEventWithLatencyInfo(touch)); |
| 615 } else { | 614 } else { |
| 616 DCHECK(pending_async_touchmove_->CanCoalesceWith(touch)); | 615 DCHECK(pending_async_touchmove_->CanCoalesceWith(touch)); |
| 617 pending_async_touchmove_->CoalesceWith(touch); | 616 pending_async_touchmove_->CoalesceWith(touch); |
| 618 } | 617 } |
| 619 DCHECK_EQ(1U, size()); | 618 DCHECK_EQ(1U, size()); |
| 620 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 619 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| 621 // It's possible (though unlikely) that ack'ing the current touch will | 620 // It's possible (though unlikely) that ack'ing the current touch will |
| 622 // trigger the queueing of another touch event (e.g., a touchcancel). As | 621 // trigger the queueing of another touch event (e.g., a touchcancel). As |
| 623 // forwarding of the queued event will be deferred while the ack is being | 622 // forwarding of the queued event will be deferred while the ack is being |
| 624 // dispatched (see |OnTouchEvent()|), try forwarding it now. | 623 // dispatched (see |OnTouchEvent()|), try forwarding it now. |
| 625 TryForwardNextEventToRenderer(); | 624 TryForwardNextEventToRenderer(); |
| 626 return; | 625 return; |
| 627 } | 626 } |
| 628 } | 627 } |
| 629 | 628 |
| 630 last_sent_touch_timestamp_sec_ = touch.event.timeStampSeconds; | 629 last_sent_touch_timestamp_sec_ = touch.event.timeStampSeconds(); |
| 631 | 630 |
| 632 // Flush any pending async touch move. If it can be combined with the current | 631 // Flush any pending async touch move. If it can be combined with the current |
| 633 // (touchmove) event, great, otherwise send it immediately but separately. Its | 632 // (touchmove) event, great, otherwise send it immediately but separately. Its |
| 634 // ack will trigger forwarding of the original |touch| event. | 633 // ack will trigger forwarding of the original |touch| event. |
| 635 if (pending_async_touchmove_) { | 634 if (pending_async_touchmove_) { |
| 636 if (pending_async_touchmove_->CanCoalesceWith(touch)) { | 635 if (pending_async_touchmove_->CanCoalesceWith(touch)) { |
| 637 pending_async_touchmove_->CoalesceWith(touch); | 636 pending_async_touchmove_->CoalesceWith(touch); |
| 638 pending_async_touchmove_->event.dispatchType = | 637 pending_async_touchmove_->event.dispatchType = |
| 639 send_touch_events_async_ ? WebInputEvent::EventNonBlocking | 638 send_touch_events_async_ ? WebInputEvent::EventNonBlocking |
| 640 : WebInputEvent::Blocking; | 639 : WebInputEvent::Blocking; |
| 641 touch = *pending_async_touchmove_; | 640 touch = *pending_async_touchmove_; |
| 642 pending_async_touchmove_.reset(); | 641 pending_async_touchmove_.reset(); |
| 643 } else { | 642 } else { |
| 644 FlushPendingAsyncTouchmove(); | 643 FlushPendingAsyncTouchmove(); |
| 645 return; | 644 return; |
| 646 } | 645 } |
| 647 } | 646 } |
| 648 | 647 |
| 649 // Note: Touchstart events are marked cancelable to allow transitions between | 648 // Note: Touchstart events are marked cancelable to allow transitions between |
| 650 // platform scrolling and JS pinching. Touchend events, however, remain | 649 // platform scrolling and JS pinching. Touchend events, however, remain |
| 651 // uncancelable, mitigating the risk of jank when transitioning to a fling. | 650 // uncancelable, mitigating the risk of jank when transitioning to a fling. |
| 652 if (send_touch_events_async_ && touch.event.type != WebInputEvent::TouchStart) | 651 if (send_touch_events_async_ && |
| 652 touch.event.type() != WebInputEvent::TouchStart) |
| 653 touch.event.dispatchType = WebInputEvent::EventNonBlocking; | 653 touch.event.dispatchType = WebInputEvent::EventNonBlocking; |
| 654 | 654 |
| 655 SendTouchEventImmediately(&touch); | 655 SendTouchEventImmediately(&touch); |
| 656 } | 656 } |
| 657 | 657 |
| 658 void TouchEventQueue::FlushPendingAsyncTouchmove() { | 658 void TouchEventQueue::FlushPendingAsyncTouchmove() { |
| 659 DCHECK(!dispatching_touch_); | 659 DCHECK(!dispatching_touch_); |
| 660 std::unique_ptr<TouchEventWithLatencyInfo> touch = | 660 std::unique_ptr<TouchEventWithLatencyInfo> touch = |
| 661 std::move(pending_async_touchmove_); | 661 std::move(pending_async_touchmove_); |
| 662 touch->event.dispatchType = WebInputEvent::EventNonBlocking; | 662 touch->event.dispatchType = WebInputEvent::EventNonBlocking; |
| 663 touch_queue_.push_front( | 663 touch_queue_.push_front( |
| 664 base::MakeUnique<CoalescedWebTouchEvent>(*touch, true)); | 664 base::MakeUnique<CoalescedWebTouchEvent>(*touch, true)); |
| 665 SendTouchEventImmediately(touch.get()); | 665 SendTouchEventImmediately(touch.get()); |
| 666 } | 666 } |
| 667 | 667 |
| 668 void TouchEventQueue::OnGestureScrollEvent( | 668 void TouchEventQueue::OnGestureScrollEvent( |
| 669 const GestureEventWithLatencyInfo& gesture_event) { | 669 const GestureEventWithLatencyInfo& gesture_event) { |
| 670 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { | 670 if (gesture_event.event.type() == blink::WebInputEvent::GestureScrollBegin) { |
| 671 if (has_handler_for_current_sequence_ && | 671 if (has_handler_for_current_sequence_ && |
| 672 !drop_remaining_touches_in_sequence_) { | 672 !drop_remaining_touches_in_sequence_) { |
| 673 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) | 673 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) |
| 674 << "A touch handler should be offered a touchmove before scrolling."; | 674 << "A touch handler should be offered a touchmove before scrolling."; |
| 675 } | 675 } |
| 676 | 676 |
| 677 pending_async_touchmove_.reset(); | 677 pending_async_touchmove_.reset(); |
| 678 | 678 |
| 679 return; | 679 return; |
| 680 } | 680 } |
| 681 | 681 |
| 682 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollUpdate && | 682 if (gesture_event.event.type() == blink::WebInputEvent::GestureScrollUpdate && |
| 683 gesture_event.event.resendingPluginId == -1) { | 683 gesture_event.event.resendingPluginId == -1) { |
| 684 send_touch_events_async_ = true; | 684 send_touch_events_async_ = true; |
| 685 } | 685 } |
| 686 } | 686 } |
| 687 | 687 |
| 688 void TouchEventQueue::OnGestureEventAck( | 688 void TouchEventQueue::OnGestureEventAck( |
| 689 const GestureEventWithLatencyInfo& event, | 689 const GestureEventWithLatencyInfo& event, |
| 690 InputEventAckState ack_result) { | 690 InputEventAckState ack_result) { |
| 691 // Throttle sending touchmove events as long as the scroll events are handled. | 691 // Throttle sending touchmove events as long as the scroll events are handled. |
| 692 // Note that there's no guarantee that this ACK is for the most recent | 692 // Note that there's no guarantee that this ACK is for the most recent |
| 693 // gesture event (or even part of the current sequence). Worst case, the | 693 // gesture event (or even part of the current sequence). Worst case, the |
| 694 // delay in updating the absorption state will result in minor UI glitches. | 694 // delay in updating the absorption state will result in minor UI glitches. |
| 695 // A valid |pending_async_touchmove_| will be flushed when the next event is | 695 // A valid |pending_async_touchmove_| will be flushed when the next event is |
| 696 // forwarded. Scroll updates that are being resent from a GuestView are | 696 // forwarded. Scroll updates that are being resent from a GuestView are |
| 697 // ignored. | 697 // ignored. |
| 698 if (event.event.type == blink::WebInputEvent::GestureScrollUpdate && | 698 if (event.event.type() == blink::WebInputEvent::GestureScrollUpdate && |
| 699 event.event.resendingPluginId == -1) { | 699 event.event.resendingPluginId == -1) { |
| 700 send_touch_events_async_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED); | 700 send_touch_events_async_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED); |
| 701 } | 701 } |
| 702 } | 702 } |
| 703 | 703 |
| 704 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { | 704 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { |
| 705 DCHECK(!dispatching_touch_ack_); | 705 DCHECK(!dispatching_touch_ack_); |
| 706 DCHECK(!dispatching_touch_); | 706 DCHECK(!dispatching_touch_); |
| 707 has_handlers_ = has_handlers; | 707 has_handlers_ = has_handlers; |
| 708 } | 708 } |
| 709 | 709 |
| 710 bool TouchEventQueue::IsPendingAckTouchStart() const { | 710 bool TouchEventQueue::IsPendingAckTouchStart() const { |
| 711 DCHECK(!dispatching_touch_ack_); | 711 DCHECK(!dispatching_touch_ack_); |
| 712 if (touch_queue_.empty()) | 712 if (touch_queue_.empty()) |
| 713 return false; | 713 return false; |
| 714 | 714 |
| 715 const blink::WebTouchEvent& event = | 715 const blink::WebTouchEvent& event = |
| 716 touch_queue_.front()->coalesced_event().event; | 716 touch_queue_.front()->coalesced_event().event; |
| 717 return (event.type == WebInputEvent::TouchStart); | 717 return (event.type() == WebInputEvent::TouchStart); |
| 718 } | 718 } |
| 719 | 719 |
| 720 void TouchEventQueue::SetAckTimeoutEnabled(bool enabled) { | 720 void TouchEventQueue::SetAckTimeoutEnabled(bool enabled) { |
| 721 if (timeout_handler_) | 721 if (timeout_handler_) |
| 722 timeout_handler_->SetEnabled(enabled); | 722 timeout_handler_->SetEnabled(enabled); |
| 723 } | 723 } |
| 724 | 724 |
| 725 void TouchEventQueue::SetIsMobileOptimizedSite(bool mobile_optimized_site) { | 725 void TouchEventQueue::SetIsMobileOptimizedSite(bool mobile_optimized_site) { |
| 726 if (timeout_handler_) | 726 if (timeout_handler_) |
| 727 timeout_handler_->SetUseMobileTimeout(mobile_optimized_site); | 727 timeout_handler_->SetUseMobileTimeout(mobile_optimized_site); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 std::move(touch_queue_.front()); | 775 std::move(touch_queue_.front()); |
| 776 DCHECK(acked_event); | 776 DCHECK(acked_event); |
| 777 | 777 |
| 778 UpdateTouchConsumerStates(acked_event->coalesced_event().event, ack_result); | 778 UpdateTouchConsumerStates(acked_event->coalesced_event().event, ack_result); |
| 779 | 779 |
| 780 // Note that acking the touch-event may result in multiple gestures being sent | 780 // Note that acking the touch-event may result in multiple gestures being sent |
| 781 // to the renderer, or touch-events being queued. | 781 // to the renderer, or touch-events being queued. |
| 782 base::AutoReset<bool> dispatching_touch_ack(&dispatching_touch_ack_, true); | 782 base::AutoReset<bool> dispatching_touch_ack(&dispatching_touch_ack_, true); |
| 783 | 783 |
| 784 // Skip ack for TouchScrollStarted since it was synthesized within the queue. | 784 // Skip ack for TouchScrollStarted since it was synthesized within the queue. |
| 785 if (acked_event->coalesced_event().event.type != | 785 if (acked_event->coalesced_event().event.type() != |
| 786 WebInputEvent::TouchScrollStarted) { | 786 WebInputEvent::TouchScrollStarted) { |
| 787 acked_event->DispatchAckToClient(ack_result, optional_latency_info, | 787 acked_event->DispatchAckToClient(ack_result, optional_latency_info, |
| 788 client_); | 788 client_); |
| 789 } | 789 } |
| 790 | 790 |
| 791 touch_queue_.pop_front(); | 791 touch_queue_.pop_front(); |
| 792 } | 792 } |
| 793 | 793 |
| 794 void TouchEventQueue::SendTouchEventImmediately( | 794 void TouchEventQueue::SendTouchEventImmediately( |
| 795 TouchEventWithLatencyInfo* touch) { | 795 TouchEventWithLatencyInfo* touch) { |
| 796 // TODO(crbug.com/600773): Hack to avoid cyclic reentry to this method. | 796 // TODO(crbug.com/600773): Hack to avoid cyclic reentry to this method. |
| 797 if (dispatching_touch_) | 797 if (dispatching_touch_) |
| 798 return; | 798 return; |
| 799 | 799 |
| 800 if (touch->event.type == WebInputEvent::TouchStart) | 800 if (touch->event.type() == WebInputEvent::TouchStart) |
| 801 touch->event.touchStartOrFirstTouchMove = true; | 801 touch->event.touchStartOrFirstTouchMove = true; |
| 802 | 802 |
| 803 // For touchmove events, compare touch points position from current event | 803 // For touchmove events, compare touch points position from current event |
| 804 // to last sent event and update touch points state. | 804 // to last sent event and update touch points state. |
| 805 if (touch->event.type == WebInputEvent::TouchMove) { | 805 if (touch->event.type() == WebInputEvent::TouchMove) { |
| 806 CHECK(last_sent_touchevent_); | 806 CHECK(last_sent_touchevent_); |
| 807 if (last_sent_touchevent_->type == WebInputEvent::TouchStart) | 807 if (last_sent_touchevent_->type() == WebInputEvent::TouchStart) |
| 808 touch->event.touchStartOrFirstTouchMove = true; | 808 touch->event.touchStartOrFirstTouchMove = true; |
| 809 for (unsigned int i = 0; i < last_sent_touchevent_->touchesLength; ++i) { | 809 for (unsigned int i = 0; i < last_sent_touchevent_->touchesLength; ++i) { |
| 810 const WebTouchPoint& last_touch_point = | 810 const WebTouchPoint& last_touch_point = |
| 811 last_sent_touchevent_->touches[i]; | 811 last_sent_touchevent_->touches[i]; |
| 812 // Touches with same id may not have same index in Touches array. | 812 // Touches with same id may not have same index in Touches array. |
| 813 for (unsigned int j = 0; j < touch->event.touchesLength; ++j) { | 813 for (unsigned int j = 0; j < touch->event.touchesLength; ++j) { |
| 814 const WebTouchPoint& current_touchmove_point = touch->event.touches[j]; | 814 const WebTouchPoint& current_touchmove_point = touch->event.touches[j]; |
| 815 if (current_touchmove_point.id != last_touch_point.id) | 815 if (current_touchmove_point.id != last_touch_point.id) |
| 816 continue; | 816 continue; |
| 817 | 817 |
| 818 if (!HasPointChanged(last_touch_point, current_touchmove_point)) | 818 if (!HasPointChanged(last_touch_point, current_touchmove_point)) |
| 819 touch->event.touches[j].state = WebTouchPoint::StateStationary; | 819 touch->event.touches[j].state = WebTouchPoint::StateStationary; |
| 820 | 820 |
| 821 break; | 821 break; |
| 822 } | 822 } |
| 823 } | 823 } |
| 824 } | 824 } |
| 825 | 825 |
| 826 if (touch->event.type != WebInputEvent::TouchScrollStarted) { | 826 if (touch->event.type() != WebInputEvent::TouchScrollStarted) { |
| 827 if (last_sent_touchevent_) | 827 if (last_sent_touchevent_) |
| 828 *last_sent_touchevent_ = touch->event; | 828 *last_sent_touchevent_ = touch->event; |
| 829 else | 829 else |
| 830 last_sent_touchevent_.reset(new WebTouchEvent(touch->event)); | 830 last_sent_touchevent_.reset(new WebTouchEvent(touch->event)); |
| 831 } | 831 } |
| 832 | 832 |
| 833 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); | 833 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); |
| 834 | 834 |
| 835 client_->SendTouchEventImmediately(*touch); | 835 client_->SendTouchEventImmediately(*touch); |
| 836 | 836 |
| 837 // A synchronous ack will reset |dispatching_touch_|, in which case the touch | 837 // A synchronous ack will reset |dispatching_touch_|, in which case the touch |
| 838 // timeout should not be started and the count also should not be increased. | 838 // timeout should not be started and the count also should not be increased. |
| 839 if (dispatching_touch_) { | 839 if (dispatching_touch_) { |
| 840 if (touch->event.type == WebInputEvent::TouchMove && | 840 if (touch->event.type() == WebInputEvent::TouchMove && |
| 841 touch->event.dispatchType != WebInputEvent::Blocking) { | 841 touch->event.dispatchType != WebInputEvent::Blocking) { |
| 842 // When we send out a uncancelable touch move, we increase the count and | 842 // When we send out a uncancelable touch move, we increase the count and |
| 843 // we do not process input event ack any more, we will just ack to client | 843 // we do not process input event ack any more, we will just ack to client |
| 844 // and wait for the ack from render. Also we will remove it from the front | 844 // and wait for the ack from render. Also we will remove it from the front |
| 845 // of the queue. | 845 // of the queue. |
| 846 ack_pending_async_touchmove_ids_.push_back( | 846 ack_pending_async_touchmove_ids_.push_back( |
| 847 touch->event.uniqueTouchEventId); | 847 touch->event.uniqueTouchEventId); |
| 848 dispatching_touch_ = false; | 848 dispatching_touch_ = false; |
| 849 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_IGNORED); | 849 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_IGNORED); |
| 850 TryForwardNextEventToRenderer(); | 850 TryForwardNextEventToRenderer(); |
| 851 return; | 851 return; |
| 852 } | 852 } |
| 853 | 853 |
| 854 if (timeout_handler_) | 854 if (timeout_handler_) |
| 855 timeout_handler_->StartIfNecessary(*touch); | 855 timeout_handler_->StartIfNecessary(*touch); |
| 856 } | 856 } |
| 857 } | 857 } |
| 858 | 858 |
| 859 TouchEventQueue::PreFilterResult | 859 TouchEventQueue::PreFilterResult |
| 860 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { | 860 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { |
| 861 if (event.type == WebInputEvent::TouchScrollStarted) | 861 if (event.type() == WebInputEvent::TouchScrollStarted) |
| 862 return FORWARD_TO_RENDERER; | 862 return FORWARD_TO_RENDERER; |
| 863 | 863 |
| 864 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { | 864 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { |
| 865 has_handler_for_current_sequence_ = false; | 865 has_handler_for_current_sequence_ = false; |
| 866 send_touch_events_async_ = false; | 866 send_touch_events_async_ = false; |
| 867 pending_async_touchmove_.reset(); | 867 pending_async_touchmove_.reset(); |
| 868 last_sent_touchevent_.reset(); | 868 last_sent_touchevent_.reset(); |
| 869 | 869 |
| 870 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position); | 870 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position); |
| 871 drop_remaining_touches_in_sequence_ = false; | 871 drop_remaining_touches_in_sequence_ = false; |
| 872 if (!has_handlers_) { | 872 if (!has_handlers_) { |
| 873 drop_remaining_touches_in_sequence_ = true; | 873 drop_remaining_touches_in_sequence_ = true; |
| 874 return ACK_WITH_NO_CONSUMER_EXISTS; | 874 return ACK_WITH_NO_CONSUMER_EXISTS; |
| 875 } | 875 } |
| 876 } | 876 } |
| 877 | 877 |
| 878 if (timeout_handler_ && timeout_handler_->FilterEvent(event)) | 878 if (timeout_handler_ && timeout_handler_->FilterEvent(event)) |
| 879 return ACK_WITH_NO_CONSUMER_EXISTS; | 879 return ACK_WITH_NO_CONSUMER_EXISTS; |
| 880 | 880 |
| 881 if (touchmove_slop_suppressor_->FilterEvent(event)) | 881 if (touchmove_slop_suppressor_->FilterEvent(event)) |
| 882 return ACK_WITH_NOT_CONSUMED; | 882 return ACK_WITH_NOT_CONSUMED; |
| 883 | 883 |
| 884 if (drop_remaining_touches_in_sequence_ && | 884 if (drop_remaining_touches_in_sequence_ && |
| 885 event.type != WebInputEvent::TouchCancel) { | 885 event.type() != WebInputEvent::TouchCancel) { |
| 886 return ACK_WITH_NO_CONSUMER_EXISTS; | 886 return ACK_WITH_NO_CONSUMER_EXISTS; |
| 887 } | 887 } |
| 888 | 888 |
| 889 if (event.type == WebInputEvent::TouchStart) { | 889 if (event.type() == WebInputEvent::TouchStart) { |
| 890 return (has_handlers_ || has_handler_for_current_sequence_) | 890 return (has_handlers_ || has_handler_for_current_sequence_) |
| 891 ? FORWARD_TO_RENDERER | 891 ? FORWARD_TO_RENDERER |
| 892 : ACK_WITH_NO_CONSUMER_EXISTS; | 892 : ACK_WITH_NO_CONSUMER_EXISTS; |
| 893 } | 893 } |
| 894 | 894 |
| 895 if (has_handler_for_current_sequence_) { | 895 if (has_handler_for_current_sequence_) { |
| 896 // Only forward a touch if it has a non-stationary pointer that is active | 896 // Only forward a touch if it has a non-stationary pointer that is active |
| 897 // in the current touch sequence. | 897 // in the current touch sequence. |
| 898 for (size_t i = 0; i < event.touchesLength; ++i) { | 898 for (size_t i = 0; i < event.touchesLength; ++i) { |
| 899 const WebTouchPoint& point = event.touches[i]; | 899 const WebTouchPoint& point = event.touches[i]; |
| 900 if (point.state == WebTouchPoint::StateStationary) | 900 if (point.state == WebTouchPoint::StateStationary) |
| 901 continue; | 901 continue; |
| 902 | 902 |
| 903 // |last_sent_touchevent_| will be non-null as long as there is an | 903 // |last_sent_touchevent_| will be non-null as long as there is an |
| 904 // active touch sequence being forwarded to the renderer. | 904 // active touch sequence being forwarded to the renderer. |
| 905 if (!last_sent_touchevent_) | 905 if (!last_sent_touchevent_) |
| 906 continue; | 906 continue; |
| 907 | 907 |
| 908 for (size_t j = 0; j < last_sent_touchevent_->touchesLength; ++j) { | 908 for (size_t j = 0; j < last_sent_touchevent_->touchesLength; ++j) { |
| 909 if (point.id != last_sent_touchevent_->touches[j].id) | 909 if (point.id != last_sent_touchevent_->touches[j].id) |
| 910 continue; | 910 continue; |
| 911 | 911 |
| 912 if (event.type != WebInputEvent::TouchMove) | 912 if (event.type() != WebInputEvent::TouchMove) |
| 913 return FORWARD_TO_RENDERER; | 913 return FORWARD_TO_RENDERER; |
| 914 | 914 |
| 915 // All pointers in TouchMove events may have state as StateMoved, | 915 // All pointers in TouchMove events may have state as StateMoved, |
| 916 // even though none of the pointers have not changed in real. | 916 // even though none of the pointers have not changed in real. |
| 917 // Forward these events when at least one pointer has changed. | 917 // Forward these events when at least one pointer has changed. |
| 918 if (HasPointChanged(last_sent_touchevent_->touches[j], point)) | 918 if (HasPointChanged(last_sent_touchevent_->touches[j], point)) |
| 919 return FORWARD_TO_RENDERER; | 919 return FORWARD_TO_RENDERER; |
| 920 | 920 |
| 921 // This is a TouchMove event for which we have yet to find a | 921 // This is a TouchMove event for which we have yet to find a |
| 922 // non-stationary pointer. Continue checking the next pointers | 922 // non-stationary pointer. Continue checking the next pointers |
| 923 // in the |event|. | 923 // in the |event|. |
| 924 break; | 924 break; |
| 925 } | 925 } |
| 926 | 926 |
| 927 } | 927 } |
| 928 } | 928 } |
| 929 | 929 |
| 930 return ACK_WITH_NO_CONSUMER_EXISTS; | 930 return ACK_WITH_NO_CONSUMER_EXISTS; |
| 931 } | 931 } |
| 932 | 932 |
| 933 void TouchEventQueue::UpdateTouchConsumerStates(const WebTouchEvent& event, | 933 void TouchEventQueue::UpdateTouchConsumerStates(const WebTouchEvent& event, |
| 934 InputEventAckState ack_result) { | 934 InputEventAckState ack_result) { |
| 935 if (event.type == WebInputEvent::TouchStart) { | 935 if (event.type() == WebInputEvent::TouchStart) { |
| 936 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) | 936 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) |
| 937 send_touch_events_async_ = false; | 937 send_touch_events_async_ = false; |
| 938 has_handler_for_current_sequence_ |= | 938 has_handler_for_current_sequence_ |= |
| 939 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; | 939 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; |
| 940 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { | 940 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { |
| 941 has_handler_for_current_sequence_ = false; | 941 has_handler_for_current_sequence_ = false; |
| 942 } | 942 } |
| 943 } | 943 } |
| 944 | 944 |
| 945 } // namespace content | 945 } // namespace content |
| OLD | NEW |