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

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

Issue 140253005: Add touch scrolling modes experimental flags (DEPRECATED) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update for eager GR 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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 bool ignore_ack_; 233 bool ignore_ack_;
234 234
235 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent); 235 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent);
236 }; 236 };
237 237
238 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client) 238 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client)
239 : client_(client), 239 : client_(client),
240 dispatching_touch_ack_(NULL), 240 dispatching_touch_ack_(NULL),
241 dispatching_touch_(false), 241 dispatching_touch_(false),
242 touch_filtering_state_(TOUCH_FILTERING_STATE_DEFAULT), 242 touch_filtering_state_(TOUCH_FILTERING_STATE_DEFAULT),
243 ack_timeout_enabled_(false) { 243 ack_timeout_enabled_(false),
244 touch_scrolling_mode_(GetTouchScrollingMode()),
245 absorbing_touch_moves_(false) {
244 DCHECK(client); 246 DCHECK(client);
245 } 247 }
246 248
247 TouchEventQueue::~TouchEventQueue() { 249 TouchEventQueue::~TouchEventQueue() {
248 if (!touch_queue_.empty()) 250 if (!touch_queue_.empty())
249 STLDeleteElements(&touch_queue_); 251 STLDeleteElements(&touch_queue_);
250 } 252 }
251 253
252 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { 254 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
253 // If the queueing of |event| was triggered by an ack dispatch, defer 255 // If the queueing of |event| was triggered by an ack dispatch, defer
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 void TouchEventQueue::ForwardToRenderer( 321 void TouchEventQueue::ForwardToRenderer(
320 const TouchEventWithLatencyInfo& touch) { 322 const TouchEventWithLatencyInfo& touch) {
321 DCHECK(!dispatching_touch_); 323 DCHECK(!dispatching_touch_);
322 DCHECK_NE(touch_filtering_state_, DROP_ALL_TOUCHES); 324 DCHECK_NE(touch_filtering_state_, DROP_ALL_TOUCHES);
323 325
324 if (IsNewTouchSequence(touch.event)) { 326 if (IsNewTouchSequence(touch.event)) {
325 touch_filtering_state_ = 327 touch_filtering_state_ =
326 ack_timeout_enabled_ ? FORWARD_TOUCHES_UNTIL_TIMEOUT 328 ack_timeout_enabled_ ? FORWARD_TOUCHES_UNTIL_TIMEOUT
327 : FORWARD_ALL_TOUCHES; 329 : FORWARD_ALL_TOUCHES;
328 touch_ack_states_.clear(); 330 touch_ack_states_.clear();
331 absorbing_touch_moves_ = false;
329 } 332 }
330 333
331 // A synchronous ack will reset |dispatching_touch_|, in which case 334 // A synchronous ack will reset |dispatching_touch_|, in which case
332 // the touch timeout should not be started. 335 // the touch timeout should not be started.
333 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); 336 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true);
334 client_->SendTouchEventImmediately(touch); 337 client_->SendTouchEventImmediately(touch);
335 if (dispatching_touch_ && 338 if (dispatching_touch_ &&
336 touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT && 339 touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT &&
337 ShouldTouchTypeTriggerTimeout(touch.event.type)) { 340 ShouldTouchTypeTriggerTimeout(touch.event.type)) {
338 DCHECK(timeout_handler_); 341 DCHECK(timeout_handler_);
339 timeout_handler_->Start(touch); 342 timeout_handler_->Start(touch);
340 } 343 }
341 } 344 }
342 345
343 void TouchEventQueue::OnGestureScrollEvent( 346 void TouchEventQueue::OnGestureScrollEvent(
344 const GestureEventWithLatencyInfo& gesture_event) { 347 const GestureEventWithLatencyInfo& gesture_event) {
345 if (gesture_event.event.type != blink::WebInputEvent::GestureScrollBegin) 348 if (gesture_event.event.type != blink::WebInputEvent::GestureScrollBegin)
346 return; 349 return;
347 350
351 if (touch_scrolling_mode_ != TOUCH_SCROLLING_MODE_TOUCHCANCEL)
352 return;
353
348 // We assume that scroll events are generated synchronously from 354 // We assume that scroll events are generated synchronously from
349 // dispatching a touch event ack. This allows us to generate a synthetic 355 // dispatching a touch event ack. This allows us to generate a synthetic
350 // cancel event that has the same touch ids as the touch event that 356 // cancel event that has the same touch ids as the touch event that
351 // is being acked. Otherwise, we don't perform the touch-cancel optimization. 357 // is being acked. Otherwise, we don't perform the touch-cancel optimization.
352 if (!dispatching_touch_ack_) 358 if (!dispatching_touch_ack_)
353 return; 359 return;
354 360
355 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE) 361 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE)
356 return; 362 return;
357 363
358 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE; 364 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
359 365
360 // Fake a TouchCancel to cancel the touch points of the touch event 366 // Fake a TouchCancel to cancel the touch points of the touch event
361 // that is currently being acked. 367 // that is currently being acked.
362 // Note: |dispatching_touch_ack_| is non-null when we reach here, meaning we 368 // Note: |dispatching_touch_ack_| is non-null when we reach here, meaning we
363 // are in the scope of PopTouchEventToClient() and that no touch event 369 // are in the scope of PopTouchEventToClient() and that no touch event
364 // in the queue is waiting for ack from renderer. So we can just insert 370 // in the queue is waiting for ack from renderer. So we can just insert
365 // the touch cancel at the beginning of the queue. 371 // the touch cancel at the beginning of the queue.
366 touch_queue_.push_front(new CoalescedWebTouchEvent( 372 touch_queue_.push_front(new CoalescedWebTouchEvent(
367 ObtainCancelEventForTouchEvent( 373 ObtainCancelEventForTouchEvent(
368 dispatching_touch_ack_->coalesced_event()), true)); 374 dispatching_touch_ack_->coalesced_event()), true));
369 } 375 }
370 376
377 void TouchEventQueue::OnGestureEventAck(
378 const GestureEventWithLatencyInfo& event,
379 InputEventAckState ack_result) {
380 if (touch_scrolling_mode_ != TOUCH_SCROLLING_MODE_ABSORB_TOUCHMOVE)
jdduke (slow) 2014/01/31 20:01:16 Could this be racy? If the GSU ack is delayed? Or
Rick Byers 2014/02/01 23:09:34 Yes, this could be racy. I was thinking it was OK
381 return;
382
383 if (event.event.type != blink::WebInputEvent::GestureScrollUpdate)
384 return;
385
386 // Suspend sending touchmove events as long as the scroll events are handled.
387 absorbing_touch_moves_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED);
388 }
389
371 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { 390 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) {
372 DCHECK(!dispatching_touch_ack_); 391 DCHECK(!dispatching_touch_ack_);
373 DCHECK(!dispatching_touch_); 392 DCHECK(!dispatching_touch_);
374 393
375 if (has_handlers) { 394 if (has_handlers) {
376 if (touch_filtering_state_ == DROP_ALL_TOUCHES) { 395 if (touch_filtering_state_ == DROP_ALL_TOUCHES) {
377 // If no touch handler was previously registered, ensure that we don't 396 // If no touch handler was previously registered, ensure that we don't
378 // send a partial touch sequence to the renderer. 397 // send a partial touch sequence to the renderer.
379 DCHECK(touch_queue_.empty()); 398 DCHECK(touch_queue_.empty());
380 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE; 399 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 if (touch_filtering_state_ == DROP_ALL_TOUCHES) 490 if (touch_filtering_state_ == DROP_ALL_TOUCHES)
472 return false; 491 return false;
473 492
474 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE && 493 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE &&
475 event.type != WebInputEvent::TouchCancel) { 494 event.type != WebInputEvent::TouchCancel) {
476 if (IsNewTouchSequence(event)) 495 if (IsNewTouchSequence(event))
477 return true; 496 return true;
478 return false; 497 return false;
479 } 498 }
480 499
500 if (absorbing_touch_moves_ && event.type == WebInputEvent::TouchMove)
501 return false;
502
481 // Touch press events should always be forwarded to the renderer. 503 // Touch press events should always be forwarded to the renderer.
482 if (event.type == WebInputEvent::TouchStart) 504 if (event.type == WebInputEvent::TouchStart)
483 return true; 505 return true;
484 506
485 for (unsigned int i = 0; i < event.touchesLength; ++i) { 507 for (unsigned int i = 0; i < event.touchesLength; ++i) {
486 const WebTouchPoint& point = event.touches[i]; 508 const WebTouchPoint& point = event.touches[i];
487 // If a point has been stationary, then don't take it into account. 509 // If a point has been stationary, then don't take it into account.
488 if (point.state == WebTouchPoint::StateStationary) 510 if (point.state == WebTouchPoint::StateStationary)
489 continue; 511 continue;
490 512
(...skipping 25 matching lines...) Expand all
516 } 538 }
517 } else if (event.type == WebInputEvent::TouchStart) { 539 } else if (event.type == WebInputEvent::TouchStart) {
518 for (unsigned i = 0; i < event.touchesLength; ++i) { 540 for (unsigned i = 0; i < event.touchesLength; ++i) {
519 const WebTouchPoint& point = event.touches[i]; 541 const WebTouchPoint& point = event.touches[i];
520 if (point.state == WebTouchPoint::StatePressed) 542 if (point.state == WebTouchPoint::StatePressed)
521 touch_ack_states_[point.id] = ack_result; 543 touch_ack_states_[point.id] = ack_result;
522 } 544 }
523 } 545 }
524 } 546 }
525 547
548 // static
549 TouchEventQueue::TouchScrollingMode TouchEventQueue::GetTouchScrollingMode()
jdduke (slow) 2014/01/31 20:01:16 Any reason not to just put this in the anon namesp
Rick Byers 2014/02/01 23:09:34 Done.
550 {
551 std::string modeString = CommandLine::ForCurrentProcess()->
552 GetSwitchValueASCII(switches::kTouchScrollingMode);
553 if (modeString == switches::kTouchScrollingModeSyncTouchmove)
554 return TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE;
555 if (modeString == switches::kTouchScrollingModeAbsorbTouchmove)
556 return TOUCH_SCROLLING_MODE_ABSORB_TOUCHMOVE;
557 if (modeString != "" &&
558 modeString != switches::kTouchScrollingModeTouchcancel)
559 LOG(ERROR) << "Invalid --touch-scrolling-mode option: " << modeString;
560 return TOUCH_SCROLLING_MODE_TOUCHCANCEL;
561 }
562
563
526 } // namespace content 564 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/input/touch_event_queue.h ('k') | content/public/common/content_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698