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

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

Issue 183923034: Disable the touch ack timeout for touch-action:none (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Slight ordering tweak. Created 6 years, 9 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
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/input_router_impl.h" 5 #include "content/browser/renderer_host/input/input_router_impl.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/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 InputAckHandler* ack_handler, 135 InputAckHandler* ack_handler,
136 int routing_id) 136 int routing_id)
137 : sender_(sender), 137 : sender_(sender),
138 client_(client), 138 client_(client),
139 ack_handler_(ack_handler), 139 ack_handler_(ack_handler),
140 routing_id_(routing_id), 140 routing_id_(routing_id),
141 select_range_pending_(false), 141 select_range_pending_(false),
142 move_caret_pending_(false), 142 move_caret_pending_(false),
143 mouse_move_pending_(false), 143 mouse_move_pending_(false),
144 mouse_wheel_pending_(false), 144 mouse_wheel_pending_(false),
145 touch_ack_timeout_enabled_(false), 145 touch_ack_timeout_supported_(false),
146 touch_ack_timeout_delay_ms_(std::numeric_limits<size_t>::max()), 146 touch_ack_timeout_delay_ms_(std::numeric_limits<size_t>::max()),
147 current_view_flags_(0),
147 current_ack_source_(ACK_SOURCE_NONE), 148 current_ack_source_(ACK_SOURCE_NONE),
148 gesture_event_queue_(new GestureEventQueue(this, this)) { 149 gesture_event_queue_(new GestureEventQueue(this, this)) {
149 DCHECK(sender); 150 DCHECK(sender);
150 DCHECK(client); 151 DCHECK(client);
151 DCHECK(ack_handler); 152 DCHECK(ack_handler);
152 touch_event_queue_.reset(new TouchEventQueue( 153 touch_event_queue_.reset(new TouchEventQueue(
153 this, GetTouchScrollingMode(), GetTouchMoveSlopSuppressionLengthDips())); 154 this, GetTouchScrollingMode(), GetTouchMoveSlopSuppressionLengthDips()));
154 touch_ack_timeout_enabled_ = 155 touch_ack_timeout_supported_ =
155 GetTouchAckTimeoutDelayMs(&touch_ack_timeout_delay_ms_); 156 GetTouchAckTimeoutDelayMs(&touch_ack_timeout_delay_ms_);
156 touch_event_queue_->SetAckTimeoutEnabled(touch_ack_timeout_enabled_, 157 UpdateTouchAckTimeoutEnabled();
157 touch_ack_timeout_delay_ms_);
158 } 158 }
159 159
160 InputRouterImpl::~InputRouterImpl() {} 160 InputRouterImpl::~InputRouterImpl() {}
161 161
162 void InputRouterImpl::Flush() {} 162 void InputRouterImpl::Flush() {}
163 163
164 bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) { 164 bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) {
165 DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart); 165 DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart);
166 switch (message->type()) { 166 switch (message->type()) {
167 // Check for types that require an ACK. 167 // Check for types that require an ACK.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 return; 280 return;
281 } 281 }
282 mouse_move_pending_ = true; 282 mouse_move_pending_ = true;
283 } 283 }
284 284
285 FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false); 285 FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false);
286 } 286 }
287 287
288 void InputRouterImpl::SendTouchEventImmediately( 288 void InputRouterImpl::SendTouchEventImmediately(
289 const TouchEventWithLatencyInfo& touch_event) { 289 const TouchEventWithLatencyInfo& touch_event) {
290 if (WebTouchEventTraits::IsTouchSequenceStart(touch_event.event)) 290 if (WebTouchEventTraits::IsTouchSequenceStart(touch_event.event)) {
291 touch_action_filter_.ResetTouchAction(); 291 touch_action_filter_.ResetTouchAction();
292 UpdateTouchAckTimeoutEnabled();
293 }
292 294
293 FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false); 295 FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false);
294 } 296 }
295 297
296 void InputRouterImpl::SendGestureEventImmediately( 298 void InputRouterImpl::SendGestureEventImmediately(
297 const GestureEventWithLatencyInfo& gesture_event) { 299 const GestureEventWithLatencyInfo& gesture_event) {
298 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); 300 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false);
299 } 301 }
300 302
301 const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const { 303 const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const {
302 if (key_queue_.empty()) 304 if (key_queue_.empty())
303 return NULL; 305 return NULL;
304 return &key_queue_.front(); 306 return &key_queue_.front();
305 } 307 }
306 308
307 bool InputRouterImpl::ShouldForwardTouchEvent() const { 309 bool InputRouterImpl::ShouldForwardTouchEvent() const {
308 // Always send a touch event if the renderer has a touch-event handler. 310 // Always send a touch event if the renderer has a touch-event handler.
309 return touch_event_queue_->has_handlers(); 311 return touch_event_queue_->has_handlers();
310 } 312 }
311 313
312 void InputRouterImpl::OnViewUpdated(int view_flags) { 314 void InputRouterImpl::OnViewUpdated(int view_flags) {
313 bool fixed_page_scale = (view_flags & FIXED_PAGE_SCALE) != 0; 315 current_view_flags_ = view_flags;
314 bool mobile_viewport = (view_flags & MOBILE_VIEWPORT) != 0; 316
315 touch_event_queue_->SetAckTimeoutEnabled( 317 // A fixed page scale or mobile viewport should disable the touch ack timeout.
316 touch_ack_timeout_enabled_ && !(fixed_page_scale || mobile_viewport), 318 UpdateTouchAckTimeoutEnabled();
317 touch_ack_timeout_delay_ms_);
318 } 319 }
319 320
320 bool InputRouterImpl::OnMessageReceived(const IPC::Message& message) { 321 bool InputRouterImpl::OnMessageReceived(const IPC::Message& message) {
321 bool handled = true; 322 bool handled = true;
322 bool message_is_ok = true; 323 bool message_is_ok = true;
323 IPC_BEGIN_MESSAGE_MAP_EX(InputRouterImpl, message, message_is_ok) 324 IPC_BEGIN_MESSAGE_MAP_EX(InputRouterImpl, message, message_is_ok)
324 IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck) 325 IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck)
325 IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck) 326 IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck)
326 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck) 327 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck)
327 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers, 328 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers,
328 OnHasTouchEventHandlers) 329 OnHasTouchEventHandlers)
329 IPC_MESSAGE_HANDLER(InputHostMsg_SetTouchAction, 330 IPC_MESSAGE_HANDLER(InputHostMsg_SetTouchAction,
330 OnSetTouchAction) 331 OnSetTouchAction)
331 IPC_MESSAGE_UNHANDLED(handled = false) 332 IPC_MESSAGE_UNHANDLED(handled = false)
332 IPC_END_MESSAGE_MAP() 333 IPC_END_MESSAGE_MAP()
333 334
334 if (!message_is_ok) 335 if (!message_is_ok)
335 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); 336 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE);
336 337
337 return handled; 338 return handled;
338 } 339 }
339 340
340 void InputRouterImpl::OnTouchEventAck(const TouchEventWithLatencyInfo& event, 341 void InputRouterImpl::OnTouchEventAck(const TouchEventWithLatencyInfo& event,
341 InputEventAckState ack_result) { 342 InputEventAckState ack_result) {
342 // Touchstart events sent to the renderer indicate a new touch sequence, but 343 // Touchstart events sent to the renderer indicate a new touch sequence, but
343 // in some cases we may filter out sending the touchstart - catch those here. 344 // in some cases we may filter out sending the touchstart - catch those here.
344 if (WebTouchEventTraits::IsTouchSequenceStart(event.event) && 345 if (WebTouchEventTraits::IsTouchSequenceStart(event.event) &&
345 ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) { 346 ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) {
346 touch_action_filter_.ResetTouchAction(); 347 touch_action_filter_.ResetTouchAction();
348 UpdateTouchAckTimeoutEnabled();
347 } 349 }
348 ack_handler_->OnTouchEventAck(event, ack_result); 350 ack_handler_->OnTouchEventAck(event, ack_result);
349 } 351 }
350 352
351 void InputRouterImpl::OnGestureEventAck( 353 void InputRouterImpl::OnGestureEventAck(
352 const GestureEventWithLatencyInfo& event, 354 const GestureEventWithLatencyInfo& event,
353 InputEventAckState ack_result) { 355 InputEventAckState ack_result) {
354 touch_event_queue_->OnGestureEventAck(event, ack_result); 356 touch_event_queue_->OnGestureEventAck(event, ack_result);
355 ProcessAckForOverscroll(event.event, ack_result); 357 ProcessAckForOverscroll(event.event, ack_result);
356 ack_handler_->OnGestureEventAck(event, ack_result); 358 ack_handler_->OnGestureEventAck(event, ack_result);
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 } 554 }
553 555
554 void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) { 556 void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) {
555 TRACE_EVENT1("input", "InputRouterImpl::OnHasTouchEventHandlers", 557 TRACE_EVENT1("input", "InputRouterImpl::OnHasTouchEventHandlers",
556 "has_handlers", has_handlers); 558 "has_handlers", has_handlers);
557 559
558 touch_event_queue_->OnHasTouchEventHandlers(has_handlers); 560 touch_event_queue_->OnHasTouchEventHandlers(has_handlers);
559 client_->OnHasTouchEventHandlers(has_handlers); 561 client_->OnHasTouchEventHandlers(has_handlers);
560 } 562 }
561 563
562 void InputRouterImpl::OnSetTouchAction( 564 void InputRouterImpl::OnSetTouchAction(TouchAction touch_action) {
563 content::TouchAction touch_action) {
564 // Synthetic touchstart events should get filtered out in RenderWidget. 565 // Synthetic touchstart events should get filtered out in RenderWidget.
565 DCHECK(touch_event_queue_->IsPendingAckTouchStart()); 566 DCHECK(touch_event_queue_->IsPendingAckTouchStart());
566 567
567 touch_action_filter_.OnSetTouchAction(touch_action); 568 touch_action_filter_.OnSetTouchAction(touch_action);
569
570 // TOUCH_ACTION_NONE should disable the touch ack timeout.
571 UpdateTouchAckTimeoutEnabled();
568 } 572 }
569 573
570 void InputRouterImpl::ProcessInputEventAck( 574 void InputRouterImpl::ProcessInputEventAck(
571 WebInputEvent::Type event_type, 575 WebInputEvent::Type event_type,
572 InputEventAckState ack_result, 576 InputEventAckState ack_result,
573 const ui::LatencyInfo& latency_info, 577 const ui::LatencyInfo& latency_info,
574 AckSource ack_source) { 578 AckSource ack_source) {
575 TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck", 579 TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck",
576 "type", WebInputEventTraits::GetName(event_type), 580 "type", WebInputEventTraits::GetName(event_type),
577 "ack", GetEventAckName(ack_result)); 581 "ack", GetEventAckName(ack_result));
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 SendGestureEvent(MakeGestureEvent( 771 SendGestureEvent(MakeGestureEvent(
768 WebInputEvent::GestureScrollEnd, mouse_event.timeStampSeconds, 772 WebInputEvent::GestureScrollEnd, mouse_event.timeStampSeconds,
769 x, y, 0, event.latency)); 773 x, y, 0, event.latency));
770 } 774 }
771 break; 775 break;
772 case WebMouseEvent::ButtonNone: 776 case WebMouseEvent::ButtonNone:
773 break; 777 break;
774 } 778 }
775 } 779 }
776 780
781 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() {
782 if (!touch_ack_timeout_supported_) {
783 touch_event_queue_->SetAckTimeoutEnabled(false, 0);
784 return;
785 }
786
787 // Mobile sites tend to be well-behaved with respect to touch handling, so
788 // they have less need for the touch timeout fallback.
789 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0;
790 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0;
791
792 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves
793 // little purpose. It's also a strong signal that touch handling is critical
Rick Byers 2014/03/05 21:24:23 nit: I believe chromium checkstyle will complain a
jdduke (slow) 2014/03/06 00:15:25 Done.
794 // to page functionality, so the timeout could do more harm than good.
795 const bool touch_action_none =
796 touch_action_filter_.allowed_touch_action() == TOUCH_ACTION_NONE;
797
798 const bool touch_ack_timeout_enabled = !fixed_page_scale &&
799 !mobile_viewport &&
800 !touch_action_none;
801 touch_event_queue_->SetAckTimeoutEnabled(touch_ack_timeout_enabled,
802 touch_ack_timeout_delay_ms_);
803 }
804
777 bool InputRouterImpl::IsInOverscrollGesture() const { 805 bool InputRouterImpl::IsInOverscrollGesture() const {
778 OverscrollController* controller = client_->GetOverscrollController(); 806 OverscrollController* controller = client_->GetOverscrollController();
779 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; 807 return controller && controller->overscroll_mode() != OVERSCROLL_NONE;
780 } 808 }
781 809
782 } // namespace content 810 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698