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 |