| 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/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 for (size_t i = 0; i < event.GetPointerCount(); ++i) { | 35 for (size_t i = 0; i < event.GetPointerCount(); ++i) { |
| 36 float diameter = event.GetTouchMajor(i); | 36 float diameter = event.GetTouchMajor(i); |
| 37 bounds.Union(gfx::RectF(event.GetX(i) - diameter / 2, | 37 bounds.Union(gfx::RectF(event.GetX(i) - diameter / 2, |
| 38 event.GetY(i) - diameter / 2, | 38 event.GetY(i) - diameter / 2, |
| 39 diameter, | 39 diameter, |
| 40 diameter)); | 40 diameter)); |
| 41 } | 41 } |
| 42 return bounds; | 42 return bounds; |
| 43 } | 43 } |
| 44 | 44 |
| 45 GestureEventData CreateGesture(EventType type, | 45 GestureEventData CreateGesture(const GestureEventDetails& details, |
| 46 int motion_event_id, | 46 int motion_event_id, |
| 47 base::TimeTicks time, | 47 base::TimeTicks time, |
| 48 float x, | 48 float x, |
| 49 float y, | 49 float y, |
| 50 size_t touch_point_count, | 50 size_t touch_point_count, |
| 51 const gfx::RectF& bounding_box, | 51 const gfx::RectF& bounding_box) { |
| 52 const GestureEventDetails& details) { | 52 return GestureEventData(details, |
| 53 return GestureEventData(type, | |
| 54 motion_event_id, | 53 motion_event_id, |
| 55 time, | 54 time, |
| 56 x, | 55 x, |
| 57 y, | 56 y, |
| 58 static_cast<int>(touch_point_count), | 57 static_cast<int>(touch_point_count), |
| 59 bounding_box, | 58 bounding_box); |
| 60 details); | |
| 61 } | 59 } |
| 62 | 60 |
| 63 GestureEventData CreateGesture(EventType type, | 61 GestureEventData CreateGesture(EventType type, |
| 64 int motion_event_id, | 62 int motion_event_id, |
| 65 base::TimeTicks time, | 63 base::TimeTicks time, |
| 66 float x, | 64 float x, |
| 67 float y, | 65 float y, |
| 68 size_t touch_point_count, | 66 size_t touch_point_count, |
| 69 const gfx::RectF& bounding_box) { | 67 const gfx::RectF& bounding_box) { |
| 70 return GestureEventData(type, | 68 return GestureEventData(type, |
| 71 motion_event_id, | 69 motion_event_id, |
| 72 time, | 70 time, |
| 73 x, | 71 x, |
| 74 y, | 72 y, |
| 75 static_cast<int>(touch_point_count), | 73 static_cast<int>(touch_point_count), |
| 76 bounding_box); | 74 bounding_box); |
| 77 } | 75 } |
| 78 | 76 |
| 79 GestureEventData CreateGesture(EventType type, | 77 GestureEventData CreateGesture(const GestureEventDetails& details, |
| 80 const MotionEvent& event, | 78 const MotionEvent& event) { |
| 81 const GestureEventDetails& details) { | 79 return CreateGesture(details, |
| 82 return CreateGesture(type, | |
| 83 event.GetId(), | 80 event.GetId(), |
| 84 event.GetEventTime(), | 81 event.GetEventTime(), |
| 85 event.GetX(), | 82 event.GetX(), |
| 86 event.GetY(), | 83 event.GetY(), |
| 87 event.GetPointerCount(), | 84 event.GetPointerCount(), |
| 88 GetBoundingBox(event), | 85 GetBoundingBox(event)); |
| 89 details); | |
| 90 } | 86 } |
| 91 | 87 |
| 92 GestureEventData CreateGesture(EventType type, | 88 GestureEventData CreateGesture(EventType type, |
| 93 const MotionEvent& event) { | 89 const MotionEvent& event) { |
| 94 return CreateGesture(type, | 90 return CreateGesture(type, |
| 95 event.GetId(), | 91 event.GetId(), |
| 96 event.GetEventTime(), | 92 event.GetEventTime(), |
| 97 event.GetX(), | 93 event.GetX(), |
| 98 event.GetY(), | 94 event.GetY(), |
| 99 event.GetPointerCount(), | 95 event.GetPointerCount(), |
| 100 GetBoundingBox(event)); | 96 GetBoundingBox(event)); |
| 101 } | 97 } |
| 102 | 98 |
| 103 GestureEventDetails CreateTapGestureDetails(EventType type, | 99 GestureEventDetails CreateTapGestureDetails(EventType type) { |
| 104 const MotionEvent& event) { | |
| 105 // Set the tap count to 1 even for ET_GESTURE_DOUBLE_TAP, in order to be | 100 // Set the tap count to 1 even for ET_GESTURE_DOUBLE_TAP, in order to be |
| 106 // consistent with double tap behavior on a mobile viewport. See | 101 // consistent with double tap behavior on a mobile viewport. See |
| 107 // crbug.com/234986 for context. | 102 // crbug.com/234986 for context. |
| 108 GestureEventDetails tap_details(type, 1, 0); | 103 GestureEventDetails tap_details(type, 1, 0); |
| 109 return tap_details; | 104 return tap_details; |
| 110 } | 105 } |
| 111 | 106 |
| 112 } // namespace | 107 } // namespace |
| 113 | 108 |
| 114 // GestureProvider:::Config | 109 // GestureProvider:::Config |
| 115 | 110 |
| 116 GestureProvider::Config::Config() | 111 GestureProvider::Config::Config() |
| 117 : display(gfx::Display::kInvalidDisplayID, gfx::Rect(1, 1)), | 112 : display(gfx::Display::kInvalidDisplayID, gfx::Rect(1, 1)), |
| 118 disable_click_delay(false), | 113 disable_click_delay(false), |
| 119 gesture_begin_end_types_enabled(false) {} | 114 gesture_begin_end_types_enabled(false), |
| 115 min_gesture_bounds_length(0) {} |
| 120 | 116 |
| 121 GestureProvider::Config::~Config() {} | 117 GestureProvider::Config::~Config() {} |
| 122 | 118 |
| 123 // GestureProvider::ScaleGestureListener | 119 // GestureProvider::ScaleGestureListener |
| 124 | 120 |
| 125 class GestureProvider::ScaleGestureListenerImpl | 121 class GestureProvider::ScaleGestureListenerImpl |
| 126 : public ScaleGestureDetector::ScaleGestureListener { | 122 : public ScaleGestureDetector::ScaleGestureListener { |
| 127 public: | 123 public: |
| 128 ScaleGestureListenerImpl(const ScaleGestureDetector::Config& config, | 124 ScaleGestureListenerImpl(const ScaleGestureDetector::Config& config, |
| 129 GestureProvider* provider) | 125 GestureProvider* provider) |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 // For historical reasons, Chrome has instead adopted a scale factor | 194 // For historical reasons, Chrome has instead adopted a scale factor |
| 199 // computation that is invariant to the focal distance, where | 195 // computation that is invariant to the focal distance, where |
| 200 // the scale delta remains constant if the touch velocity is constant. | 196 // the scale delta remains constant if the touch velocity is constant. |
| 201 float dy = | 197 float dy = |
| 202 (detector.GetCurrentSpanY() - detector.GetPreviousSpanY()) * 0.5f; | 198 (detector.GetCurrentSpanY() - detector.GetPreviousSpanY()) * 0.5f; |
| 203 scale = std::pow(scale > 1 ? 1.0f + kDoubleTapDragZoomSpeed | 199 scale = std::pow(scale > 1 ? 1.0f + kDoubleTapDragZoomSpeed |
| 204 : 1.0f - kDoubleTapDragZoomSpeed, | 200 : 1.0f - kDoubleTapDragZoomSpeed, |
| 205 std::abs(dy)); | 201 std::abs(dy)); |
| 206 } | 202 } |
| 207 GestureEventDetails pinch_details(ET_GESTURE_PINCH_UPDATE, scale, 0); | 203 GestureEventDetails pinch_details(ET_GESTURE_PINCH_UPDATE, scale, 0); |
| 208 provider_->Send(CreateGesture(ET_GESTURE_PINCH_UPDATE, | 204 provider_->Send(CreateGesture(pinch_details, |
| 209 e.GetId(), | 205 e.GetId(), |
| 210 detector.GetEventTime(), | 206 detector.GetEventTime(), |
| 211 detector.GetFocusX(), | 207 detector.GetFocusX(), |
| 212 detector.GetFocusY(), | 208 detector.GetFocusY(), |
| 213 e.GetPointerCount(), | 209 e.GetPointerCount(), |
| 214 GetBoundingBox(e), | 210 GetBoundingBox(e))); |
| 215 pinch_details)); | |
| 216 return true; | 211 return true; |
| 217 } | 212 } |
| 218 | 213 |
| 219 void SetDoubleTapEnabled(bool enabled) { | 214 void SetDoubleTapEnabled(bool enabled) { |
| 220 DCHECK(!IsDoubleTapInProgress()); | 215 DCHECK(!IsDoubleTapInProgress()); |
| 221 scale_gesture_detector_.SetQuickScaleEnabled(enabled); | 216 scale_gesture_detector_.SetQuickScaleEnabled(enabled); |
| 222 } | 217 } |
| 223 | 218 |
| 224 void SetMultiTouchEnabled(bool enabled) { | 219 void SetMultiTouchEnabled(bool enabled) { |
| 225 // Note that returning false from OnScaleBegin / OnScale makes the | 220 // Note that returning false from OnScaleBegin / OnScale makes the |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 return gesture_detector_.OnTouchEvent(e); | 291 return gesture_detector_.OnTouchEvent(e); |
| 297 } | 292 } |
| 298 | 293 |
| 299 // GestureDetector::GestureListener implementation. | 294 // GestureDetector::GestureListener implementation. |
| 300 virtual bool OnDown(const MotionEvent& e) OVERRIDE { | 295 virtual bool OnDown(const MotionEvent& e) OVERRIDE { |
| 301 current_down_time_ = e.GetEventTime(); | 296 current_down_time_ = e.GetEventTime(); |
| 302 ignore_single_tap_ = false; | 297 ignore_single_tap_ = false; |
| 303 seen_first_scroll_event_ = false; | 298 seen_first_scroll_event_ = false; |
| 304 | 299 |
| 305 GestureEventDetails tap_details(ET_GESTURE_TAP_DOWN, 0, 0); | 300 GestureEventDetails tap_details(ET_GESTURE_TAP_DOWN, 0, 0); |
| 306 provider_->Send(CreateGesture(ET_GESTURE_TAP_DOWN, e, tap_details)); | 301 provider_->Send(CreateGesture(tap_details, e)); |
| 307 | 302 |
| 308 // Return true to indicate that we want to handle touch. | 303 // Return true to indicate that we want to handle touch. |
| 309 return true; | 304 return true; |
| 310 } | 305 } |
| 311 | 306 |
| 312 virtual bool OnScroll(const MotionEvent& e1, | 307 virtual bool OnScroll(const MotionEvent& e1, |
| 313 const MotionEvent& e2, | 308 const MotionEvent& e2, |
| 314 float raw_distance_x, | 309 float raw_distance_x, |
| 315 float raw_distance_y) OVERRIDE { | 310 float raw_distance_y) OVERRIDE { |
| 316 float distance_x = raw_distance_x; | 311 float distance_x = raw_distance_x; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 338 } | 333 } |
| 339 | 334 |
| 340 if (!provider_->IsScrollInProgress()) { | 335 if (!provider_->IsScrollInProgress()) { |
| 341 // Note that scroll start hints are in distance traveled, where | 336 // Note that scroll start hints are in distance traveled, where |
| 342 // scroll deltas are in the opposite direction. | 337 // scroll deltas are in the opposite direction. |
| 343 GestureEventDetails scroll_details( | 338 GestureEventDetails scroll_details( |
| 344 ET_GESTURE_SCROLL_BEGIN, -raw_distance_x, -raw_distance_y); | 339 ET_GESTURE_SCROLL_BEGIN, -raw_distance_x, -raw_distance_y); |
| 345 | 340 |
| 346 // Use the co-ordinates from the touch down, as these co-ordinates are | 341 // Use the co-ordinates from the touch down, as these co-ordinates are |
| 347 // used to determine which layer the scroll should affect. | 342 // used to determine which layer the scroll should affect. |
| 348 provider_->Send(CreateGesture(ET_GESTURE_SCROLL_BEGIN, | 343 provider_->Send(CreateGesture(scroll_details, |
| 349 e2.GetId(), | 344 e2.GetId(), |
| 350 e2.GetEventTime(), | 345 e2.GetEventTime(), |
| 351 e1.GetX(), | 346 e1.GetX(), |
| 352 e1.GetY(), | 347 e1.GetY(), |
| 353 e2.GetPointerCount(), | 348 e2.GetPointerCount(), |
| 354 GetBoundingBox(e2), | 349 GetBoundingBox(e2))); |
| 355 scroll_details)); | |
| 356 } | 350 } |
| 357 | 351 |
| 358 if (distance_x || distance_y) { | 352 if (distance_x || distance_y) { |
| 359 const gfx::RectF bounding_box = GetBoundingBox(e2); | 353 const gfx::RectF bounding_box = GetBoundingBox(e2); |
| 360 GestureEventDetails scroll_details( | 354 GestureEventDetails scroll_details( |
| 361 ET_GESTURE_SCROLL_UPDATE, -distance_x, -distance_y); | 355 ET_GESTURE_SCROLL_UPDATE, -distance_x, -distance_y); |
| 362 provider_->Send(CreateGesture(ET_GESTURE_SCROLL_UPDATE, | 356 provider_->Send(CreateGesture(scroll_details, |
| 363 e2.GetId(), | 357 e2.GetId(), |
| 364 e2.GetEventTime(), | 358 e2.GetEventTime(), |
| 365 bounding_box.CenterPoint().x(), | 359 bounding_box.CenterPoint().x(), |
| 366 bounding_box.CenterPoint().y(), | 360 bounding_box.CenterPoint().y(), |
| 367 e2.GetPointerCount(), | 361 e2.GetPointerCount(), |
| 368 bounding_box, | 362 bounding_box)); |
| 369 scroll_details)); | |
| 370 } | 363 } |
| 371 | 364 |
| 372 return true; | 365 return true; |
| 373 } | 366 } |
| 374 | 367 |
| 375 virtual bool OnFling(const MotionEvent& e1, | 368 virtual bool OnFling(const MotionEvent& e1, |
| 376 const MotionEvent& e2, | 369 const MotionEvent& e2, |
| 377 float velocity_x, | 370 float velocity_x, |
| 378 float velocity_y) OVERRIDE { | 371 float velocity_y) OVERRIDE { |
| 379 if (snap_scroll_controller_.IsSnappingScrolls()) { | 372 if (snap_scroll_controller_.IsSnappingScrolls()) { |
| 380 if (snap_scroll_controller_.IsSnapHorizontal()) { | 373 if (snap_scroll_controller_.IsSnapHorizontal()) { |
| 381 velocity_y = 0; | 374 velocity_y = 0; |
| 382 } else { | 375 } else { |
| 383 velocity_x = 0; | 376 velocity_x = 0; |
| 384 } | 377 } |
| 385 } | 378 } |
| 386 | 379 |
| 387 provider_->Fling(e2, velocity_x, velocity_y); | 380 provider_->Fling(e2, velocity_x, velocity_y); |
| 388 return true; | 381 return true; |
| 389 } | 382 } |
| 390 | 383 |
| 391 virtual bool OnSwipe(const MotionEvent& e1, | 384 virtual bool OnSwipe(const MotionEvent& e1, |
| 392 const MotionEvent& e2, | 385 const MotionEvent& e2, |
| 393 float velocity_x, | 386 float velocity_x, |
| 394 float velocity_y) OVERRIDE { | 387 float velocity_y) OVERRIDE { |
| 395 GestureEventDetails swipe_details(ET_GESTURE_SWIPE, velocity_x, velocity_y); | 388 GestureEventDetails swipe_details(ET_GESTURE_SWIPE, velocity_x, velocity_y); |
| 396 provider_->Send(CreateGesture(ET_GESTURE_SWIPE, e2, swipe_details)); | 389 provider_->Send(CreateGesture(swipe_details, e2)); |
| 397 return true; | 390 return true; |
| 398 } | 391 } |
| 399 | 392 |
| 400 virtual bool OnTwoFingerTap(const MotionEvent& e1, | 393 virtual bool OnTwoFingerTap(const MotionEvent& e1, |
| 401 const MotionEvent& e2) OVERRIDE { | 394 const MotionEvent& e2) OVERRIDE { |
| 402 // The location of the two finger tap event should be the location of the | 395 // The location of the two finger tap event should be the location of the |
| 403 // primary pointer. | 396 // primary pointer. |
| 404 GestureEventDetails two_finger_tap_details(ET_GESTURE_TWO_FINGER_TAP, | 397 GestureEventDetails two_finger_tap_details(ET_GESTURE_TWO_FINGER_TAP, |
| 405 e1.GetTouchMajor(), | 398 e1.GetTouchMajor(), |
| 406 e1.GetTouchMajor()); | 399 e1.GetTouchMajor()); |
| 407 provider_->Send(CreateGesture(ET_GESTURE_TWO_FINGER_TAP, | 400 provider_->Send(CreateGesture(two_finger_tap_details, |
| 408 e2.GetId(), | 401 e2.GetId(), |
| 409 e2.GetEventTime(), | 402 e2.GetEventTime(), |
| 410 e1.GetX(), | 403 e1.GetX(), |
| 411 e1.GetY(), | 404 e1.GetY(), |
| 412 e2.GetPointerCount(), | 405 e2.GetPointerCount(), |
| 413 GetBoundingBox(e2), | 406 GetBoundingBox(e2))); |
| 414 two_finger_tap_details)); | |
| 415 return true; | 407 return true; |
| 416 } | 408 } |
| 417 | 409 |
| 418 virtual void OnShowPress(const MotionEvent& e) OVERRIDE { | 410 virtual void OnShowPress(const MotionEvent& e) OVERRIDE { |
| 419 GestureEventDetails show_press_details(ET_GESTURE_SHOW_PRESS, 0, 0); | 411 GestureEventDetails show_press_details(ET_GESTURE_SHOW_PRESS, 0, 0); |
| 420 provider_->Send( | 412 provider_->Send(CreateGesture(show_press_details, e)); |
| 421 CreateGesture(ET_GESTURE_SHOW_PRESS, e, show_press_details)); | |
| 422 } | 413 } |
| 423 | 414 |
| 424 virtual bool OnSingleTapUp(const MotionEvent& e) OVERRIDE { | 415 virtual bool OnSingleTapUp(const MotionEvent& e) OVERRIDE { |
| 425 // This is a hack to address the issue where user hovers | 416 // This is a hack to address the issue where user hovers |
| 426 // over a link for longer than double_tap_timeout_, then | 417 // over a link for longer than double_tap_timeout_, then |
| 427 // OnSingleTapConfirmed() is not triggered. But we still | 418 // OnSingleTapConfirmed() is not triggered. But we still |
| 428 // want to trigger the tap event at UP. So we override | 419 // want to trigger the tap event at UP. So we override |
| 429 // OnSingleTapUp() in this case. This assumes singleTapUp | 420 // OnSingleTapUp() in this case. This assumes singleTapUp |
| 430 // gets always called before singleTapConfirmed. | 421 // gets always called before singleTapConfirmed. |
| 431 if (!ignore_single_tap_) { | 422 if (!ignore_single_tap_) { |
| 432 if (e.GetEventTime() - current_down_time_ > double_tap_timeout_) { | 423 if (e.GetEventTime() - current_down_time_ > double_tap_timeout_) { |
| 433 return OnSingleTapConfirmed(e); | 424 return OnSingleTapConfirmed(e); |
| 434 } else if (!IsDoubleTapEnabled() || disable_click_delay_) { | 425 } else if (!IsDoubleTapEnabled() || disable_click_delay_) { |
| 435 // If double-tap has been disabled, there is no need to wait | 426 // If double-tap has been disabled, there is no need to wait |
| 436 // for the double-tap timeout. | 427 // for the double-tap timeout. |
| 437 return OnSingleTapConfirmed(e); | 428 return OnSingleTapConfirmed(e); |
| 438 } else { | 429 } else { |
| 439 // Notify Blink about this tapUp event anyway, when none of the above | 430 // Notify Blink about this tapUp event anyway, when none of the above |
| 440 // conditions applied. | 431 // conditions applied. |
| 441 provider_->Send(CreateGesture( | 432 provider_->Send(CreateGesture( |
| 442 ET_GESTURE_TAP_UNCONFIRMED, | 433 CreateTapGestureDetails(ET_GESTURE_TAP_UNCONFIRMED), e)); |
| 443 e, | |
| 444 CreateTapGestureDetails(ET_GESTURE_TAP_UNCONFIRMED, e))); | |
| 445 } | 434 } |
| 446 } | 435 } |
| 447 | 436 |
| 448 return provider_->SendLongTapIfNecessary(e); | 437 return provider_->SendLongTapIfNecessary(e); |
| 449 } | 438 } |
| 450 | 439 |
| 451 // GestureDetector::DoubleTapListener implementation. | 440 // GestureDetector::DoubleTapListener implementation. |
| 452 virtual bool OnSingleTapConfirmed(const MotionEvent& e) OVERRIDE { | 441 virtual bool OnSingleTapConfirmed(const MotionEvent& e) OVERRIDE { |
| 453 // Long taps in the edges of the screen have their events delayed by | 442 // Long taps in the edges of the screen have their events delayed by |
| 454 // ContentViewHolder for tab swipe operations. As a consequence of the delay | 443 // ContentViewHolder for tab swipe operations. As a consequence of the delay |
| 455 // this method might be called after receiving the up event. | 444 // this method might be called after receiving the up event. |
| 456 // These corner cases should be ignored. | 445 // These corner cases should be ignored. |
| 457 if (ignore_single_tap_) | 446 if (ignore_single_tap_) |
| 458 return true; | 447 return true; |
| 459 | 448 |
| 460 ignore_single_tap_ = true; | 449 ignore_single_tap_ = true; |
| 461 | 450 |
| 462 provider_->Send(CreateGesture( | 451 provider_->Send(CreateGesture(CreateTapGestureDetails(ET_GESTURE_TAP), e)); |
| 463 ET_GESTURE_TAP, e, CreateTapGestureDetails(ET_GESTURE_TAP, e))); | |
| 464 return true; | 452 return true; |
| 465 } | 453 } |
| 466 | 454 |
| 467 virtual bool OnDoubleTap(const MotionEvent& e) OVERRIDE { return false; } | 455 virtual bool OnDoubleTap(const MotionEvent& e) OVERRIDE { return false; } |
| 468 | 456 |
| 469 virtual bool OnDoubleTapEvent(const MotionEvent& e) OVERRIDE { | 457 virtual bool OnDoubleTapEvent(const MotionEvent& e) OVERRIDE { |
| 470 switch (e.GetAction()) { | 458 switch (e.GetAction()) { |
| 471 case MotionEvent::ACTION_DOWN: | 459 case MotionEvent::ACTION_DOWN: |
| 472 gesture_detector_.set_longpress_enabled(false); | 460 gesture_detector_.set_longpress_enabled(false); |
| 473 break; | 461 break; |
| 474 | 462 |
| 475 case MotionEvent::ACTION_UP: | 463 case MotionEvent::ACTION_UP: |
| 476 if (!provider_->IsPinchInProgress() && | 464 if (!provider_->IsPinchInProgress() && |
| 477 !provider_->IsScrollInProgress()) { | 465 !provider_->IsScrollInProgress()) { |
| 478 provider_->Send( | 466 provider_->Send( |
| 479 CreateGesture(ET_GESTURE_DOUBLE_TAP, | 467 CreateGesture(CreateTapGestureDetails(ET_GESTURE_DOUBLE_TAP), e)); |
| 480 e, | |
| 481 CreateTapGestureDetails(ET_GESTURE_DOUBLE_TAP, e))); | |
| 482 return true; | 468 return true; |
| 483 } | 469 } |
| 484 break; | 470 break; |
| 485 default: | 471 default: |
| 486 break; | 472 break; |
| 487 } | 473 } |
| 488 return false; | 474 return false; |
| 489 } | 475 } |
| 490 | 476 |
| 491 virtual bool OnLongPress(const MotionEvent& e) OVERRIDE { | 477 virtual bool OnLongPress(const MotionEvent& e) OVERRIDE { |
| 492 DCHECK(!IsDoubleTapInProgress()); | 478 DCHECK(!IsDoubleTapInProgress()); |
| 493 SetIgnoreSingleTap(true); | 479 SetIgnoreSingleTap(true); |
| 494 | 480 |
| 495 GestureEventDetails long_press_details(ET_GESTURE_LONG_PRESS, 0, 0); | 481 GestureEventDetails long_press_details(ET_GESTURE_LONG_PRESS, 0, 0); |
| 496 provider_->Send( | 482 provider_->Send(CreateGesture(long_press_details, e)); |
| 497 CreateGesture(ET_GESTURE_LONG_PRESS, e, long_press_details)); | |
| 498 | 483 |
| 499 // Returning true puts the GestureDetector in "longpress" mode, disabling | 484 // Returning true puts the GestureDetector in "longpress" mode, disabling |
| 500 // further scrolling. This is undesirable, as it is quite common for a | 485 // further scrolling. This is undesirable, as it is quite common for a |
| 501 // longpress gesture to fire on content that won't trigger a context menu. | 486 // longpress gesture to fire on content that won't trigger a context menu. |
| 502 return false; | 487 return false; |
| 503 } | 488 } |
| 504 | 489 |
| 505 void SetDoubleTapEnabled(bool enabled) { | 490 void SetDoubleTapEnabled(bool enabled) { |
| 506 DCHECK(!IsDoubleTapInProgress()); | 491 DCHECK(!IsDoubleTapInProgress()); |
| 507 gesture_detector_.SetDoubleTapListener(enabled ? this : NULL); | 492 gesture_detector_.SetDoubleTapListener(enabled ? this : NULL); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 | 532 |
| 548 // GestureProvider | 533 // GestureProvider |
| 549 | 534 |
| 550 GestureProvider::GestureProvider(const Config& config, | 535 GestureProvider::GestureProvider(const Config& config, |
| 551 GestureProviderClient* client) | 536 GestureProviderClient* client) |
| 552 : client_(client), | 537 : client_(client), |
| 553 touch_scroll_in_progress_(false), | 538 touch_scroll_in_progress_(false), |
| 554 pinch_in_progress_(false), | 539 pinch_in_progress_(false), |
| 555 double_tap_support_for_page_(true), | 540 double_tap_support_for_page_(true), |
| 556 double_tap_support_for_platform_(true), | 541 double_tap_support_for_platform_(true), |
| 557 gesture_begin_end_types_enabled_(config.gesture_begin_end_types_enabled) { | 542 gesture_begin_end_types_enabled_(config.gesture_begin_end_types_enabled), |
| 543 min_gesture_bounds_length_(config.min_gesture_bounds_length) { |
| 558 DCHECK(client); | 544 DCHECK(client); |
| 559 InitGestureDetectors(config); | 545 InitGestureDetectors(config); |
| 560 } | 546 } |
| 561 | 547 |
| 562 GestureProvider::~GestureProvider() {} | 548 GestureProvider::~GestureProvider() {} |
| 563 | 549 |
| 564 bool GestureProvider::OnTouchEvent(const MotionEvent& event) { | 550 bool GestureProvider::OnTouchEvent(const MotionEvent& event) { |
| 565 TRACE_EVENT1("input", "GestureProvider::OnTouchEvent", | 551 TRACE_EVENT1("input", "GestureProvider::OnTouchEvent", |
| 566 "action", GetMotionEventActionName(event.GetAction())); | 552 "action", GetMotionEventActionName(event.GetAction())); |
| 567 | 553 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 return; | 623 return; |
| 638 } | 624 } |
| 639 | 625 |
| 640 if (!touch_scroll_in_progress_) { | 626 if (!touch_scroll_in_progress_) { |
| 641 // The native side needs a ET_GESTURE_SCROLL_BEGIN before | 627 // The native side needs a ET_GESTURE_SCROLL_BEGIN before |
| 642 // ET_SCROLL_FLING_START to send the fling to the correct target. Send if it | 628 // ET_SCROLL_FLING_START to send the fling to the correct target. Send if it |
| 643 // has not sent. The distance traveled in one second is a reasonable scroll | 629 // has not sent. The distance traveled in one second is a reasonable scroll |
| 644 // start hint. | 630 // start hint. |
| 645 GestureEventDetails scroll_details( | 631 GestureEventDetails scroll_details( |
| 646 ET_GESTURE_SCROLL_BEGIN, velocity_x, velocity_y); | 632 ET_GESTURE_SCROLL_BEGIN, velocity_x, velocity_y); |
| 647 Send(CreateGesture(ET_GESTURE_SCROLL_BEGIN, event, scroll_details)); | 633 Send(CreateGesture(scroll_details, event)); |
| 648 } | 634 } |
| 649 EndTouchScrollIfNecessary(event, false); | 635 EndTouchScrollIfNecessary(event, false); |
| 650 | 636 |
| 651 GestureEventDetails fling_details( | 637 GestureEventDetails fling_details( |
| 652 ET_SCROLL_FLING_START, velocity_x, velocity_y); | 638 ET_SCROLL_FLING_START, velocity_x, velocity_y); |
| 653 Send(CreateGesture( | 639 Send(CreateGesture(fling_details, event)); |
| 654 ET_SCROLL_FLING_START, event, fling_details)); | |
| 655 } | 640 } |
| 656 | 641 |
| 657 void GestureProvider::Send(const GestureEventData& gesture) { | 642 void GestureProvider::Send(GestureEventData gesture) { |
| 658 DCHECK(!gesture.time.is_null()); | 643 DCHECK(!gesture.time.is_null()); |
| 659 // The only valid events that should be sent without an active touch sequence | 644 // The only valid events that should be sent without an active touch sequence |
| 660 // are SHOW_PRESS and TAP, potentially triggered by the double-tap | 645 // are SHOW_PRESS and TAP, potentially triggered by the double-tap |
| 661 // delay timing out. | 646 // delay timing out. |
| 662 DCHECK(current_down_event_ || gesture.type == ET_GESTURE_TAP || | 647 DCHECK(current_down_event_ || gesture.type() == ET_GESTURE_TAP || |
| 663 gesture.type == ET_GESTURE_SHOW_PRESS); | 648 gesture.type() == ET_GESTURE_SHOW_PRESS); |
| 664 | 649 |
| 665 switch (gesture.type) { | 650 // TODO(jdduke): Provide a way of skipping this clamping for stylus and/or |
| 651 // mouse-based input, perhaps by exposing the source type on MotionEvent. |
| 652 const gfx::RectF& gesture_bounds = gesture.details.bounding_box_f(); |
| 653 gesture.details.set_bounding_box(gfx::RectF( |
| 654 gesture_bounds.x(), |
| 655 gesture_bounds.y(), |
| 656 std::max(min_gesture_bounds_length_, gesture_bounds.width()), |
| 657 std::max(min_gesture_bounds_length_, gesture_bounds.height()))); |
| 658 |
| 659 switch (gesture.type()) { |
| 666 case ET_GESTURE_LONG_PRESS: | 660 case ET_GESTURE_LONG_PRESS: |
| 667 DCHECK(!scale_gesture_listener_->IsScaleGestureDetectionInProgress()); | 661 DCHECK(!scale_gesture_listener_->IsScaleGestureDetectionInProgress()); |
| 668 current_longpress_time_ = gesture.time; | 662 current_longpress_time_ = gesture.time; |
| 669 break; | 663 break; |
| 670 case ET_GESTURE_LONG_TAP: | 664 case ET_GESTURE_LONG_TAP: |
| 671 current_longpress_time_ = base::TimeTicks(); | 665 current_longpress_time_ = base::TimeTicks(); |
| 672 break; | 666 break; |
| 673 case ET_GESTURE_SCROLL_BEGIN: | 667 case ET_GESTURE_SCROLL_BEGIN: |
| 674 DCHECK(!touch_scroll_in_progress_); | 668 DCHECK(!touch_scroll_in_progress_); |
| 675 touch_scroll_in_progress_ = true; | 669 touch_scroll_in_progress_ = true; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 }; | 707 }; |
| 714 | 708 |
| 715 client_->OnGestureEvent(gesture); | 709 client_->OnGestureEvent(gesture); |
| 716 } | 710 } |
| 717 | 711 |
| 718 bool GestureProvider::SendLongTapIfNecessary(const MotionEvent& event) { | 712 bool GestureProvider::SendLongTapIfNecessary(const MotionEvent& event) { |
| 719 if (event.GetAction() == MotionEvent::ACTION_UP && | 713 if (event.GetAction() == MotionEvent::ACTION_UP && |
| 720 !current_longpress_time_.is_null() && | 714 !current_longpress_time_.is_null() && |
| 721 !scale_gesture_listener_->IsScaleGestureDetectionInProgress()) { | 715 !scale_gesture_listener_->IsScaleGestureDetectionInProgress()) { |
| 722 GestureEventDetails long_tap_details(ET_GESTURE_LONG_TAP, 0, 0); | 716 GestureEventDetails long_tap_details(ET_GESTURE_LONG_TAP, 0, 0); |
| 723 Send(CreateGesture(ET_GESTURE_LONG_TAP, event, long_tap_details)); | 717 Send(CreateGesture(long_tap_details, event)); |
| 724 return true; | 718 return true; |
| 725 } | 719 } |
| 726 return false; | 720 return false; |
| 727 } | 721 } |
| 728 | 722 |
| 729 void GestureProvider::EndTouchScrollIfNecessary(const MotionEvent& event, | 723 void GestureProvider::EndTouchScrollIfNecessary(const MotionEvent& event, |
| 730 bool send_scroll_end_event) { | 724 bool send_scroll_end_event) { |
| 731 if (!touch_scroll_in_progress_) | 725 if (!touch_scroll_in_progress_) |
| 732 return; | 726 return; |
| 733 if (send_scroll_end_event) | 727 if (send_scroll_end_event) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 if (current_down_event_) | 803 if (current_down_event_) |
| 810 return; | 804 return; |
| 811 | 805 |
| 812 const bool double_tap_enabled = double_tap_support_for_page_ && | 806 const bool double_tap_enabled = double_tap_support_for_page_ && |
| 813 double_tap_support_for_platform_; | 807 double_tap_support_for_platform_; |
| 814 gesture_listener_->SetDoubleTapEnabled(double_tap_enabled); | 808 gesture_listener_->SetDoubleTapEnabled(double_tap_enabled); |
| 815 scale_gesture_listener_->SetDoubleTapEnabled(double_tap_enabled); | 809 scale_gesture_listener_->SetDoubleTapEnabled(double_tap_enabled); |
| 816 } | 810 } |
| 817 | 811 |
| 818 } // namespace ui | 812 } // namespace ui |
| OLD | NEW |