| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "ui/events/gesture_detection/gesture_provider.h" | 5 #include "ui/events/gesture_detection/gesture_provider.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 e2.GetFlags())); | 397 e2.GetFlags())); |
| 398 return true; | 398 return true; |
| 399 } | 399 } |
| 400 | 400 |
| 401 void OnShowPress(const MotionEvent& e) override { | 401 void OnShowPress(const MotionEvent& e) override { |
| 402 GestureEventDetails show_press_details(ET_GESTURE_SHOW_PRESS); | 402 GestureEventDetails show_press_details(ET_GESTURE_SHOW_PRESS); |
| 403 show_press_event_sent_ = true; | 403 show_press_event_sent_ = true; |
| 404 Send(CreateGesture(show_press_details, e)); | 404 Send(CreateGesture(show_press_details, e)); |
| 405 } | 405 } |
| 406 | 406 |
| 407 bool OnSingleTapUp(const MotionEvent& e) override { | 407 bool OnSingleTapUp(const MotionEvent& e, int tap_count) override { |
| 408 // This is a hack to address the issue where user hovers | 408 // This is a hack to address the issue where user hovers |
| 409 // over a link for longer than double_tap_timeout_, then | 409 // over a link for longer than double_tap_timeout_, then |
| 410 // OnSingleTapConfirmed() is not triggered. But we still | 410 // OnSingleTapConfirmed() is not triggered. But we still |
| 411 // want to trigger the tap event at UP. So we override | 411 // want to trigger the tap event at UP. So we override |
| 412 // OnSingleTapUp() in this case. This assumes singleTapUp | 412 // OnSingleTapUp() in this case. This assumes singleTapUp |
| 413 // gets always called before singleTapConfirmed. | 413 // gets always called before singleTapConfirmed. |
| 414 if (!ignore_single_tap_) { | 414 if (!ignore_single_tap_) { |
| 415 if (e.GetEventTime() - current_down_time_ > | 415 if (e.GetEventTime() - current_down_time_ > |
| 416 config_.gesture_detector_config.double_tap_timeout) { | 416 config_.gesture_detector_config.double_tap_timeout) { |
| 417 return OnSingleTapConfirmed(e); | 417 return OnSingleTapImpl(e, tap_count); |
| 418 } else if (!IsDoubleTapEnabled()) { | 418 } else if (!IsDoubleTapEnabled()) { |
| 419 // If double-tap has been disabled, there is no need to wait | 419 // If double-tap has been disabled, there is no need to wait |
| 420 // for the double-tap timeout. | 420 // for the double-tap timeout. |
| 421 return OnSingleTapConfirmed(e); | 421 return OnSingleTapImpl(e, tap_count); |
| 422 } else { | 422 } else { |
| 423 // Notify Blink about this tapUp event anyway, when none of the above | 423 // Notify Blink about this tapUp event anyway, when none of the above |
| 424 // conditions applied. | 424 // conditions applied. |
| 425 Send(CreateTapGesture(ET_GESTURE_TAP_UNCONFIRMED, e)); | 425 Send(CreateTapGesture(ET_GESTURE_TAP_UNCONFIRMED, e, 1)); |
| 426 } | 426 } |
| 427 } | 427 } |
| 428 | 428 |
| 429 if (e.GetAction() == MotionEvent::ACTION_UP && | 429 if (e.GetAction() == MotionEvent::ACTION_UP && |
| 430 !current_longpress_time_.is_null() && | 430 !current_longpress_time_.is_null() && |
| 431 !IsScaleGestureDetectionInProgress()) { | 431 !IsScaleGestureDetectionInProgress()) { |
| 432 GestureEventDetails long_tap_details(ET_GESTURE_LONG_TAP); | 432 GestureEventDetails long_tap_details(ET_GESTURE_LONG_TAP); |
| 433 Send(CreateGesture(long_tap_details, e)); | 433 Send(CreateGesture(long_tap_details, e)); |
| 434 return true; | 434 return true; |
| 435 } | 435 } |
| 436 | 436 |
| 437 return false; | 437 return false; |
| 438 } | 438 } |
| 439 | 439 |
| 440 // DoubleTapListener implementation. | 440 // DoubleTapListener implementation. |
| 441 bool OnSingleTapConfirmed(const MotionEvent& e) override { | 441 bool OnSingleTapConfirmed(const MotionEvent& e) override { |
| 442 // Long taps in the edges of the screen have their events delayed by | 442 return OnSingleTapImpl(e, 1); |
| 443 // ContentViewHolder for tab swipe operations. As a consequence of the delay | |
| 444 // this method might be called after receiving the up event. | |
| 445 // These corner cases should be ignored. | |
| 446 if (ignore_single_tap_) | |
| 447 return true; | |
| 448 | |
| 449 ignore_single_tap_ = true; | |
| 450 | |
| 451 Send(CreateTapGesture(ET_GESTURE_TAP, e)); | |
| 452 return true; | |
| 453 } | 443 } |
| 454 | 444 |
| 455 bool OnDoubleTap(const MotionEvent& e) override { | 445 bool OnDoubleTap(const MotionEvent& e) override { |
| 456 return scale_gesture_detector_.OnDoubleTap(e); | 446 return scale_gesture_detector_.OnDoubleTap(e); |
| 457 } | 447 } |
| 458 | 448 |
| 459 bool OnDoubleTapEvent(const MotionEvent& e) override { | 449 bool OnDoubleTapEvent(const MotionEvent& e) override { |
| 460 switch (e.GetAction()) { | 450 switch (e.GetAction()) { |
| 461 case MotionEvent::ACTION_DOWN: | 451 case MotionEvent::ACTION_DOWN: |
| 462 gesture_detector_.set_longpress_enabled(false); | 452 gesture_detector_.set_longpress_enabled(false); |
| 463 break; | 453 break; |
| 464 | 454 |
| 465 case MotionEvent::ACTION_UP: | 455 case MotionEvent::ACTION_UP: |
| 466 if (!IsPinchInProgress() && !IsScrollInProgress()) { | 456 if (!IsPinchInProgress() && !IsScrollInProgress()) { |
| 467 Send(CreateTapGesture(ET_GESTURE_DOUBLE_TAP, e)); | 457 Send(CreateTapGesture(ET_GESTURE_DOUBLE_TAP, e, 1)); |
| 468 return true; | 458 return true; |
| 469 } | 459 } |
| 470 break; | 460 break; |
| 471 | 461 |
| 472 default: | 462 default: |
| 473 break; | 463 break; |
| 474 } | 464 } |
| 475 return false; | 465 return false; |
| 476 } | 466 } |
| 477 | 467 |
| 478 void OnLongPress(const MotionEvent& e) override { | 468 void OnLongPress(const MotionEvent& e) override { |
| 479 DCHECK(!IsDoubleTapInProgress()); | 469 DCHECK(!IsDoubleTapInProgress()); |
| 480 SetIgnoreSingleTap(true); | 470 SetIgnoreSingleTap(true); |
| 481 GestureEventDetails long_press_details(ET_GESTURE_LONG_PRESS); | 471 GestureEventDetails long_press_details(ET_GESTURE_LONG_PRESS); |
| 482 Send(CreateGesture(long_press_details, e)); | 472 Send(CreateGesture(long_press_details, e)); |
| 483 } | 473 } |
| 484 | 474 |
| 485 GestureEventData CreateGesture(const GestureEventDetails& details, | 475 GestureEventData CreateGesture(const GestureEventDetails& details, |
| 486 int motion_event_id, | 476 int motion_event_id, |
| 487 MotionEvent::ToolType primary_tool_type, | 477 MotionEvent::ToolType primary_tool_type, |
| 488 base::TimeTicks time, | 478 base::TimeTicks time, |
| 489 float x, | 479 float x, |
| 490 float y, | 480 float y, |
| 491 float raw_x, | 481 float raw_x, |
| 492 float raw_y, | 482 float raw_y, |
| 493 size_t touch_point_count, | 483 size_t touch_point_count, |
| 494 const gfx::RectF& bounding_box, | 484 const gfx::RectF& bounding_box, |
| 495 int flags) { | 485 int flags) const { |
| 496 return GestureEventData(details, | 486 return GestureEventData(details, |
| 497 motion_event_id, | 487 motion_event_id, |
| 498 primary_tool_type, | 488 primary_tool_type, |
| 499 time, | 489 time, |
| 500 x, | 490 x, |
| 501 y, | 491 y, |
| 502 raw_x, | 492 raw_x, |
| 503 raw_y, | 493 raw_y, |
| 504 touch_point_count, | 494 touch_point_count, |
| 505 bounding_box, | 495 bounding_box, |
| 506 flags); | 496 flags); |
| 507 } | 497 } |
| 508 | 498 |
| 509 GestureEventData CreateGesture(EventType type, | 499 GestureEventData CreateGesture(EventType type, |
| 510 int motion_event_id, | 500 int motion_event_id, |
| 511 MotionEvent::ToolType primary_tool_type, | 501 MotionEvent::ToolType primary_tool_type, |
| 512 base::TimeTicks time, | 502 base::TimeTicks time, |
| 513 float x, | 503 float x, |
| 514 float y, | 504 float y, |
| 515 float raw_x, | 505 float raw_x, |
| 516 float raw_y, | 506 float raw_y, |
| 517 size_t touch_point_count, | 507 size_t touch_point_count, |
| 518 const gfx::RectF& bounding_box, | 508 const gfx::RectF& bounding_box, |
| 519 int flags) { | 509 int flags) const { |
| 520 return GestureEventData(GestureEventDetails(type), | 510 return GestureEventData(GestureEventDetails(type), |
| 521 motion_event_id, | 511 motion_event_id, |
| 522 primary_tool_type, | 512 primary_tool_type, |
| 523 time, | 513 time, |
| 524 x, | 514 x, |
| 525 y, | 515 y, |
| 526 raw_x, | 516 raw_x, |
| 527 raw_y, | 517 raw_y, |
| 528 touch_point_count, | 518 touch_point_count, |
| 529 bounding_box, | 519 bounding_box, |
| 530 flags); | 520 flags); |
| 531 } | 521 } |
| 532 | 522 |
| 533 GestureEventData CreateGesture(const GestureEventDetails& details, | 523 GestureEventData CreateGesture(const GestureEventDetails& details, |
| 534 const MotionEvent& event) { | 524 const MotionEvent& event) const { |
| 535 return GestureEventData(details, | 525 return GestureEventData(details, |
| 536 event.GetPointerId(), | 526 event.GetPointerId(), |
| 537 event.GetToolType(), | 527 event.GetToolType(), |
| 538 event.GetEventTime(), | 528 event.GetEventTime(), |
| 539 event.GetX(), | 529 event.GetX(), |
| 540 event.GetY(), | 530 event.GetY(), |
| 541 event.GetRawX(), | 531 event.GetRawX(), |
| 542 event.GetRawY(), | 532 event.GetRawY(), |
| 543 event.GetPointerCount(), | 533 event.GetPointerCount(), |
| 544 GetBoundingBox(event, details.type()), | 534 GetBoundingBox(event, details.type()), |
| 545 event.GetFlags()); | 535 event.GetFlags()); |
| 546 } | 536 } |
| 547 | 537 |
| 548 GestureEventData CreateGesture(EventType type, const MotionEvent& event) { | 538 GestureEventData CreateGesture(EventType type, |
| 539 const MotionEvent& event) const { |
| 549 return CreateGesture(GestureEventDetails(type), event); | 540 return CreateGesture(GestureEventDetails(type), event); |
| 550 } | 541 } |
| 551 | 542 |
| 552 GestureEventData CreateTapGesture(EventType type, const MotionEvent& event) { | 543 GestureEventData CreateTapGesture(EventType type, |
| 553 // Set the tap count to 1 even for ET_GESTURE_DOUBLE_TAP, in order to be | 544 const MotionEvent& event, |
| 554 // consistent with double tap behavior on a mobile viewport. See | 545 int tap_count) const { |
| 555 // crbug.com/234986 for context. | 546 DCHECK_GE(tap_count, 0); |
| 556 GestureEventDetails details(type); | 547 GestureEventDetails details(type); |
| 557 details.set_tap_count(1); | 548 details.set_tap_count(tap_count); |
| 558 return CreateGesture(details, event); | 549 return CreateGesture(details, event); |
| 559 } | 550 } |
| 560 | 551 |
| 561 gfx::RectF GetBoundingBox(const MotionEvent& event, EventType type) { | 552 gfx::RectF GetBoundingBox(const MotionEvent& event, EventType type) const { |
| 562 // Can't use gfx::RectF::Union, as it ignores touches with a radius of 0. | 553 // Can't use gfx::RectF::Union, as it ignores touches with a radius of 0. |
| 563 float left = std::numeric_limits<float>::max(); | 554 float left = std::numeric_limits<float>::max(); |
| 564 float top = std::numeric_limits<float>::max(); | 555 float top = std::numeric_limits<float>::max(); |
| 565 float right = -std::numeric_limits<float>::max(); | 556 float right = -std::numeric_limits<float>::max(); |
| 566 float bottom = -std::numeric_limits<float>::max(); | 557 float bottom = -std::numeric_limits<float>::max(); |
| 567 for (size_t i = 0; i < event.GetPointerCount(); ++i) { | 558 for (size_t i = 0; i < event.GetPointerCount(); ++i) { |
| 568 float x, y, diameter; | 559 float x, y, diameter; |
| 569 // Only for the show press and tap events, the bounding box is calculated | 560 // Only for the show press and tap events, the bounding box is calculated |
| 570 // based on the touch start point and the maximum diameter before the | 561 // based on the touch start point and the maximum diameter before the |
| 571 // show press event is sent. | 562 // show press event is sent. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 bool IsDoubleTapInProgress() const { | 597 bool IsDoubleTapInProgress() const { |
| 607 return gesture_detector_.is_double_tapping() || | 598 return gesture_detector_.is_double_tapping() || |
| 608 (IsScaleGestureDetectionInProgress() && InDoubleTapMode()); | 599 (IsScaleGestureDetectionInProgress() && InDoubleTapMode()); |
| 609 } | 600 } |
| 610 | 601 |
| 611 bool IsScrollInProgress() const { return scroll_event_sent_; } | 602 bool IsScrollInProgress() const { return scroll_event_sent_; } |
| 612 | 603 |
| 613 bool IsPinchInProgress() const { return pinch_event_sent_; } | 604 bool IsPinchInProgress() const { return pinch_event_sent_; } |
| 614 | 605 |
| 615 private: | 606 private: |
| 607 bool OnSingleTapImpl(const MotionEvent& e, int tap_count) { |
| 608 // Long taps in the edges of the screen have their events delayed by |
| 609 // ContentViewHolder for tab swipe operations. As a consequence of the delay |
| 610 // this method might be called after receiving the up event. |
| 611 // These corner cases should be ignored. |
| 612 if (ignore_single_tap_) |
| 613 return true; |
| 614 |
| 615 ignore_single_tap_ = true; |
| 616 |
| 617 Send(CreateTapGesture(ET_GESTURE_TAP, e, tap_count)); |
| 618 return true; |
| 619 } |
| 620 |
| 616 bool IsScaleGestureDetectionInProgress() const { | 621 bool IsScaleGestureDetectionInProgress() const { |
| 617 return scale_gesture_detector_.IsInProgress(); | 622 return scale_gesture_detector_.IsInProgress(); |
| 618 } | 623 } |
| 619 | 624 |
| 620 bool InDoubleTapMode() const { | 625 bool InDoubleTapMode() const { |
| 621 return scale_gesture_detector_.InDoubleTapMode(); | 626 return scale_gesture_detector_.InDoubleTapMode(); |
| 622 } | 627 } |
| 623 | 628 |
| 624 bool IsDoubleTapEnabled() const { | 629 bool IsDoubleTapEnabled() const { |
| 625 return gesture_detector_.has_doubletap_listener(); | 630 return gesture_detector_.has_doubletap_listener(); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 // null'ing of the listener until the sequence has ended. | 826 // null'ing of the listener until the sequence has ended. |
| 822 if (current_down_event_) | 827 if (current_down_event_) |
| 823 return; | 828 return; |
| 824 | 829 |
| 825 const bool double_tap_enabled = | 830 const bool double_tap_enabled = |
| 826 double_tap_support_for_page_ && double_tap_support_for_platform_; | 831 double_tap_support_for_page_ && double_tap_support_for_platform_; |
| 827 gesture_listener_->SetDoubleTapEnabled(double_tap_enabled); | 832 gesture_listener_->SetDoubleTapEnabled(double_tap_enabled); |
| 828 } | 833 } |
| 829 | 834 |
| 830 } // namespace ui | 835 } // namespace ui |
| OLD | NEW |