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 |