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

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: Final cleanup pass 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 // Note that if the previous touch-action was TOUCH_ACTION_NONE, enabling
293 // the timeout here will not take effect until the *following* touch
294 // sequence. This is a desirable side-effect, giving the renderer a chance
295 // to send a touch-action response without racing against the ack timeout.
296 UpdateTouchAckTimeoutEnabled();
297 }
292 298
293 FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false); 299 FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false);
294 } 300 }
295 301
296 void InputRouterImpl::SendGestureEventImmediately( 302 void InputRouterImpl::SendGestureEventImmediately(
297 const GestureEventWithLatencyInfo& gesture_event) { 303 const GestureEventWithLatencyInfo& gesture_event) {
298 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); 304 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false);
299 } 305 }
300 306
301 const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const { 307 const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const {
302 if (key_queue_.empty()) 308 if (key_queue_.empty())
303 return NULL; 309 return NULL;
304 return &key_queue_.front(); 310 return &key_queue_.front();
305 } 311 }
306 312
307 bool InputRouterImpl::ShouldForwardTouchEvent() const { 313 bool InputRouterImpl::ShouldForwardTouchEvent() const {
308 // Always send a touch event if the renderer has a touch-event handler. 314 // Always send a touch event if the renderer has a touch-event handler.
309 return touch_event_queue_->has_handlers(); 315 return touch_event_queue_->has_handlers();
310 } 316 }
311 317
312 void InputRouterImpl::OnViewUpdated(int view_flags) { 318 void InputRouterImpl::OnViewUpdated(int view_flags) {
313 bool fixed_page_scale = (view_flags & FIXED_PAGE_SCALE) != 0; 319 current_view_flags_ = view_flags;
314 bool mobile_viewport = (view_flags & MOBILE_VIEWPORT) != 0; 320
315 touch_event_queue_->SetAckTimeoutEnabled( 321 // A fixed page scale or mobile viewport should disable the touch ack timeout.
316 touch_ack_timeout_enabled_ && !(fixed_page_scale || mobile_viewport), 322 UpdateTouchAckTimeoutEnabled();
317 touch_ack_timeout_delay_ms_);
318 } 323 }
319 324
320 bool InputRouterImpl::OnMessageReceived(const IPC::Message& message) { 325 bool InputRouterImpl::OnMessageReceived(const IPC::Message& message) {
321 bool handled = true; 326 bool handled = true;
322 bool message_is_ok = true; 327 bool message_is_ok = true;
323 IPC_BEGIN_MESSAGE_MAP_EX(InputRouterImpl, message, message_is_ok) 328 IPC_BEGIN_MESSAGE_MAP_EX(InputRouterImpl, message, message_is_ok)
324 IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck) 329 IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck)
325 IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck) 330 IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck)
326 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck) 331 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck)
327 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers, 332 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers,
328 OnHasTouchEventHandlers) 333 OnHasTouchEventHandlers)
329 IPC_MESSAGE_HANDLER(InputHostMsg_SetTouchAction, 334 IPC_MESSAGE_HANDLER(InputHostMsg_SetTouchAction,
330 OnSetTouchAction) 335 OnSetTouchAction)
331 IPC_MESSAGE_UNHANDLED(handled = false) 336 IPC_MESSAGE_UNHANDLED(handled = false)
332 IPC_END_MESSAGE_MAP() 337 IPC_END_MESSAGE_MAP()
333 338
334 if (!message_is_ok) 339 if (!message_is_ok)
335 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); 340 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE);
336 341
337 return handled; 342 return handled;
338 } 343 }
339 344
340 void InputRouterImpl::OnTouchEventAck(const TouchEventWithLatencyInfo& event, 345 void InputRouterImpl::OnTouchEventAck(const TouchEventWithLatencyInfo& event,
341 InputEventAckState ack_result) { 346 InputEventAckState ack_result) {
342 // Touchstart events sent to the renderer indicate a new touch sequence, but 347 // 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. 348 // in some cases we may filter out sending the touchstart - catch those here.
344 if (WebTouchEventTraits::IsTouchSequenceStart(event.event) && 349 if (WebTouchEventTraits::IsTouchSequenceStart(event.event) &&
345 ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) { 350 ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) {
346 touch_action_filter_.ResetTouchAction(); 351 touch_action_filter_.ResetTouchAction();
352 UpdateTouchAckTimeoutEnabled();
347 } 353 }
348 ack_handler_->OnTouchEventAck(event, ack_result); 354 ack_handler_->OnTouchEventAck(event, ack_result);
349 } 355 }
350 356
351 void InputRouterImpl::OnGestureEventAck( 357 void InputRouterImpl::OnGestureEventAck(
352 const GestureEventWithLatencyInfo& event, 358 const GestureEventWithLatencyInfo& event,
353 InputEventAckState ack_result) { 359 InputEventAckState ack_result) {
354 touch_event_queue_->OnGestureEventAck(event, ack_result); 360 touch_event_queue_->OnGestureEventAck(event, ack_result);
355 ProcessAckForOverscroll(event.event, ack_result); 361 ProcessAckForOverscroll(event.event, ack_result);
356 ack_handler_->OnGestureEventAck(event, ack_result); 362 ack_handler_->OnGestureEventAck(event, ack_result);
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 } 558 }
553 559
554 void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) { 560 void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) {
555 TRACE_EVENT1("input", "InputRouterImpl::OnHasTouchEventHandlers", 561 TRACE_EVENT1("input", "InputRouterImpl::OnHasTouchEventHandlers",
556 "has_handlers", has_handlers); 562 "has_handlers", has_handlers);
557 563
558 touch_event_queue_->OnHasTouchEventHandlers(has_handlers); 564 touch_event_queue_->OnHasTouchEventHandlers(has_handlers);
559 client_->OnHasTouchEventHandlers(has_handlers); 565 client_->OnHasTouchEventHandlers(has_handlers);
560 } 566 }
561 567
562 void InputRouterImpl::OnSetTouchAction( 568 void InputRouterImpl::OnSetTouchAction(TouchAction touch_action) {
563 content::TouchAction touch_action) {
564 // Synthetic touchstart events should get filtered out in RenderWidget. 569 // Synthetic touchstart events should get filtered out in RenderWidget.
565 DCHECK(touch_event_queue_->IsPendingAckTouchStart()); 570 DCHECK(touch_event_queue_->IsPendingAckTouchStart());
566 571
567 touch_action_filter_.OnSetTouchAction(touch_action); 572 touch_action_filter_.OnSetTouchAction(touch_action);
573
574 // TOUCH_ACTION_NONE should disable the touch ack timeout.
575 UpdateTouchAckTimeoutEnabled();
568 } 576 }
569 577
570 void InputRouterImpl::ProcessInputEventAck( 578 void InputRouterImpl::ProcessInputEventAck(
571 WebInputEvent::Type event_type, 579 WebInputEvent::Type event_type,
572 InputEventAckState ack_result, 580 InputEventAckState ack_result,
573 const ui::LatencyInfo& latency_info, 581 const ui::LatencyInfo& latency_info,
574 AckSource ack_source) { 582 AckSource ack_source) {
575 TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck", 583 TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck",
576 "type", WebInputEventTraits::GetName(event_type), 584 "type", WebInputEventTraits::GetName(event_type),
577 "ack", GetEventAckName(ack_result)); 585 "ack", GetEventAckName(ack_result));
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 SendGestureEvent(MakeGestureEvent( 775 SendGestureEvent(MakeGestureEvent(
768 WebInputEvent::GestureScrollEnd, mouse_event.timeStampSeconds, 776 WebInputEvent::GestureScrollEnd, mouse_event.timeStampSeconds,
769 x, y, 0, event.latency)); 777 x, y, 0, event.latency));
770 } 778 }
771 break; 779 break;
772 case WebMouseEvent::ButtonNone: 780 case WebMouseEvent::ButtonNone:
773 break; 781 break;
774 } 782 }
775 } 783 }
776 784
785 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() {
786 if (!touch_ack_timeout_supported_) {
787 touch_event_queue_->SetAckTimeoutEnabled(false, 0);
788 return;
789 }
790
791 // Mobile sites tend to be well-behaved with respect to touch handling, so
792 // they have less need for the touch timeout fallback.
793 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0;
794 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0;
795
796 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves
797 // little purpose. It's also a strong signal that touch handling is critical
798 // to page functionality, so the timeout could do more harm than good.
799 const bool touch_action_none =
800 touch_action_filter_.allowed_touch_action() == TOUCH_ACTION_NONE;
801
802 const bool touch_ack_timeout_enabled = !fixed_page_scale &&
803 !mobile_viewport &&
804 !touch_action_none;
805 touch_event_queue_->SetAckTimeoutEnabled(touch_ack_timeout_enabled,
806 touch_ack_timeout_delay_ms_);
807 }
808
777 bool InputRouterImpl::IsInOverscrollGesture() const { 809 bool InputRouterImpl::IsInOverscrollGesture() const {
778 OverscrollController* controller = client_->GetOverscrollController(); 810 OverscrollController* controller = client_->GetOverscrollController();
779 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; 811 return controller && controller->overscroll_mode() != OVERSCROLL_NONE;
780 } 812 }
781 813
782 } // namespace content 814 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698