Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Side by Side Diff: content/browser/renderer_host/input/touch_event_queue.cc

Issue 166923002: Add touch scrolling modes experimental flags (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix out of order initializer error. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 WebTouchEventWithLatencyList events_; 281 WebTouchEventWithLatencyList events_;
282 282
283 // If |ignore_ack_| is true, don't send this touch event to client 283 // If |ignore_ack_| is true, don't send this touch event to client
284 // when the event is acked. 284 // when the event is acked.
285 bool ignore_ack_; 285 bool ignore_ack_;
286 286
287 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent); 287 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent);
288 }; 288 };
289 289
290 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client, 290 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client,
291 TouchScrollingMode mode,
291 double touchmove_suppression_length_dips) 292 double touchmove_suppression_length_dips)
292 : client_(client), 293 : client_(client),
293 dispatching_touch_ack_(NULL), 294 dispatching_touch_ack_(NULL),
294 dispatching_touch_(false), 295 dispatching_touch_(false),
295 touch_filtering_state_(TOUCH_FILTERING_STATE_DEFAULT), 296 touch_filtering_state_(TOUCH_FILTERING_STATE_DEFAULT),
296 ack_timeout_enabled_(false), 297 ack_timeout_enabled_(false),
297 touchmove_slop_suppressor_( 298 touchmove_slop_suppressor_(
298 new TouchMoveSlopSuppressor(touchmove_suppression_length_dips)) { 299 new TouchMoveSlopSuppressor(touchmove_suppression_length_dips)),
300 absorbing_touch_moves_(false),
301 touch_scrolling_mode_(mode) {
299 DCHECK(client); 302 DCHECK(client);
300 } 303 }
301 304
302 TouchEventQueue::~TouchEventQueue() { 305 TouchEventQueue::~TouchEventQueue() {
303 if (!touch_queue_.empty()) 306 if (!touch_queue_.empty())
304 STLDeleteElements(&touch_queue_); 307 STLDeleteElements(&touch_queue_);
305 } 308 }
306 309
307 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { 310 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
308 TRACE_EVENT0("input", "TouchEventQueue::QueueEvent"); 311 TRACE_EVENT0("input", "TouchEventQueue::QueueEvent");
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 TRACE_EVENT0("input", "TouchEventQueue::ForwardToRenderer"); 394 TRACE_EVENT0("input", "TouchEventQueue::ForwardToRenderer");
392 395
393 DCHECK(!dispatching_touch_); 396 DCHECK(!dispatching_touch_);
394 DCHECK_NE(touch_filtering_state_, DROP_ALL_TOUCHES); 397 DCHECK_NE(touch_filtering_state_, DROP_ALL_TOUCHES);
395 398
396 if (IsNewTouchSequence(touch.event)) { 399 if (IsNewTouchSequence(touch.event)) {
397 touch_filtering_state_ = 400 touch_filtering_state_ =
398 ack_timeout_enabled_ ? FORWARD_TOUCHES_UNTIL_TIMEOUT 401 ack_timeout_enabled_ ? FORWARD_TOUCHES_UNTIL_TIMEOUT
399 : FORWARD_ALL_TOUCHES; 402 : FORWARD_ALL_TOUCHES;
400 touch_ack_states_.clear(); 403 touch_ack_states_.clear();
404 absorbing_touch_moves_ = false;
401 } 405 }
402 406
403 // A synchronous ack will reset |dispatching_touch_|, in which case 407 // A synchronous ack will reset |dispatching_touch_|, in which case
404 // the touch timeout should not be started. 408 // the touch timeout should not be started.
405 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); 409 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true);
406 client_->SendTouchEventImmediately(touch); 410 client_->SendTouchEventImmediately(touch);
407 if (dispatching_touch_ && 411 if (dispatching_touch_ &&
408 touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT && 412 touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT &&
409 ShouldTouchTypeTriggerTimeout(touch.event.type)) { 413 ShouldTouchTypeTriggerTimeout(touch.event.type)) {
410 DCHECK(timeout_handler_); 414 DCHECK(timeout_handler_);
411 timeout_handler_->Start(touch); 415 timeout_handler_->Start(touch);
412 } 416 }
413 } 417 }
414 418
415 void TouchEventQueue::OnGestureScrollEvent( 419 void TouchEventQueue::OnGestureScrollEvent(
416 const GestureEventWithLatencyInfo& gesture_event) { 420 const GestureEventWithLatencyInfo& gesture_event) {
417 if (gesture_event.event.type != blink::WebInputEvent::GestureScrollBegin) 421 if (gesture_event.event.type != blink::WebInputEvent::GestureScrollBegin)
418 return; 422 return;
419 423
424 if (touch_scrolling_mode_ != TOUCH_SCROLLING_MODE_TOUCHCANCEL)
425 return;
426
420 // We assume that scroll events are generated synchronously from 427 // We assume that scroll events are generated synchronously from
421 // dispatching a touch event ack. This allows us to generate a synthetic 428 // dispatching a touch event ack. This allows us to generate a synthetic
422 // cancel event that has the same touch ids as the touch event that 429 // cancel event that has the same touch ids as the touch event that
423 // is being acked. Otherwise, we don't perform the touch-cancel optimization. 430 // is being acked. Otherwise, we don't perform the touch-cancel optimization.
424 if (!dispatching_touch_ack_) 431 if (!dispatching_touch_ack_)
425 return; 432 return;
426 433
427 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE) 434 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE)
428 return; 435 return;
429 436
430 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE; 437 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
431 438
432 // Fake a TouchCancel to cancel the touch points of the touch event 439 // Fake a TouchCancel to cancel the touch points of the touch event
433 // that is currently being acked. 440 // that is currently being acked.
434 // Note: |dispatching_touch_ack_| is non-null when we reach here, meaning we 441 // Note: |dispatching_touch_ack_| is non-null when we reach here, meaning we
435 // are in the scope of PopTouchEventToClient() and that no touch event 442 // are in the scope of PopTouchEventToClient() and that no touch event
436 // in the queue is waiting for ack from renderer. So we can just insert 443 // in the queue is waiting for ack from renderer. So we can just insert
437 // the touch cancel at the beginning of the queue. 444 // the touch cancel at the beginning of the queue.
438 touch_queue_.push_front(new CoalescedWebTouchEvent( 445 touch_queue_.push_front(new CoalescedWebTouchEvent(
439 ObtainCancelEventForTouchEvent( 446 ObtainCancelEventForTouchEvent(
440 dispatching_touch_ack_->coalesced_event()), true)); 447 dispatching_touch_ack_->coalesced_event()), true));
441 } 448 }
442 449
450 void TouchEventQueue::OnGestureEventAck(
451 const GestureEventWithLatencyInfo& event,
452 InputEventAckState ack_result) {
453 if (touch_scrolling_mode_ != TOUCH_SCROLLING_MODE_ABSORB_TOUCHMOVE)
454 return;
455
456 if (event.event.type != blink::WebInputEvent::GestureScrollUpdate)
457 return;
458
459 // Suspend sending touchmove events as long as the scroll events are handled.
460 // Note that there's no guarantee that this ACK is for the most recent
461 // gesture event (or even part of the current sequence). Worst case, the
462 // delay in updating the absorption state should only result in minor UI
463 // glitches.
464 // TODO(rbyers): Define precise timing requirements and potentially implement
465 // mitigations for races.
466 absorbing_touch_moves_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED);
467 }
468
443 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { 469 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) {
444 DCHECK(!dispatching_touch_ack_); 470 DCHECK(!dispatching_touch_ack_);
445 DCHECK(!dispatching_touch_); 471 DCHECK(!dispatching_touch_);
446 472
447 if (has_handlers) { 473 if (has_handlers) {
448 if (touch_filtering_state_ == DROP_ALL_TOUCHES) { 474 if (touch_filtering_state_ == DROP_ALL_TOUCHES) {
449 // If no touch handler was previously registered, ensure that we don't 475 // If no touch handler was previously registered, ensure that we don't
450 // send a partial touch sequence to the renderer. 476 // send a partial touch sequence to the renderer.
451 DCHECK(touch_queue_.empty()); 477 DCHECK(touch_queue_.empty());
452 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE; 478 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 if (touch_filtering_state_ == DROP_ALL_TOUCHES) 568 if (touch_filtering_state_ == DROP_ALL_TOUCHES)
543 return ACK_WITH_NO_CONSUMER_EXISTS; 569 return ACK_WITH_NO_CONSUMER_EXISTS;
544 570
545 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE && 571 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE &&
546 event.type != WebInputEvent::TouchCancel) { 572 event.type != WebInputEvent::TouchCancel) {
547 if (IsNewTouchSequence(event)) 573 if (IsNewTouchSequence(event))
548 return FORWARD_TO_RENDERER; 574 return FORWARD_TO_RENDERER;
549 return ACK_WITH_NOT_CONSUMED; 575 return ACK_WITH_NOT_CONSUMED;
550 } 576 }
551 577
578 if (absorbing_touch_moves_ && event.type == WebInputEvent::TouchMove)
579 return ACK_WITH_NOT_CONSUMED;
580
552 // Touch press events should always be forwarded to the renderer. 581 // Touch press events should always be forwarded to the renderer.
553 if (event.type == WebInputEvent::TouchStart) 582 if (event.type == WebInputEvent::TouchStart)
554 return FORWARD_TO_RENDERER; 583 return FORWARD_TO_RENDERER;
555 584
556 for (unsigned int i = 0; i < event.touchesLength; ++i) { 585 for (unsigned int i = 0; i < event.touchesLength; ++i) {
557 const WebTouchPoint& point = event.touches[i]; 586 const WebTouchPoint& point = event.touches[i];
558 // If a point has been stationary, then don't take it into account. 587 // If a point has been stationary, then don't take it into account.
559 if (point.state == WebTouchPoint::StateStationary) 588 if (point.state == WebTouchPoint::StateStationary)
560 continue; 589 continue;
561 590
(...skipping 26 matching lines...) Expand all
588 } else if (event.type == WebInputEvent::TouchStart) { 617 } else if (event.type == WebInputEvent::TouchStart) {
589 for (unsigned i = 0; i < event.touchesLength; ++i) { 618 for (unsigned i = 0; i < event.touchesLength; ++i) {
590 const WebTouchPoint& point = event.touches[i]; 619 const WebTouchPoint& point = event.touches[i];
591 if (point.state == WebTouchPoint::StatePressed) 620 if (point.state == WebTouchPoint::StatePressed)
592 touch_ack_states_[point.id] = ack_result; 621 touch_ack_states_[point.id] = ack_result;
593 } 622 }
594 } 623 }
595 } 624 }
596 625
597 } // namespace content 626 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698