OLD | NEW |
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 <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
13 #include "content/browser/renderer_host/input/gesture_event_queue.h" | 13 #include "content/browser/renderer_host/input/gesture_event_queue.h" |
14 #include "content/browser/renderer_host/input/input_ack_handler.h" | 14 #include "content/browser/renderer_host/input/input_ack_handler.h" |
15 #include "content/browser/renderer_host/input/input_router_client.h" | 15 #include "content/browser/renderer_host/input/input_router_client.h" |
16 #include "content/browser/renderer_host/input/touch_event_queue.h" | 16 #include "content/browser/renderer_host/input/touch_event_queue.h" |
17 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
r.h" | 17 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
r.h" |
18 #include "content/common/content_constants_internal.h" | 18 #include "content/common/content_constants_internal.h" |
19 #include "content/common/edit_command.h" | 19 #include "content/common/edit_command.h" |
20 #include "content/common/input/input_event_ack_state.h" | 20 #include "content/common/input/input_event_ack_state.h" |
| 21 #include "content/common/input/input_event_stream_validator.h" |
21 #include "content/common/input/touch_action.h" | 22 #include "content/common/input/touch_action.h" |
22 #include "content/common/input/web_touch_event_traits.h" | 23 #include "content/common/input/web_touch_event_traits.h" |
23 #include "content/common/input_messages.h" | 24 #include "content/common/input_messages.h" |
24 #include "content/common/view_messages.h" | 25 #include "content/common/view_messages.h" |
25 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
26 #include "content/public/browser/notification_types.h" | 27 #include "content/public/browser/notification_types.h" |
27 #include "content/public/browser/user_metrics.h" | 28 #include "content/public/browser/user_metrics.h" |
28 #include "content/public/common/content_switches.h" | 29 #include "content/public/common/content_switches.h" |
29 #include "ipc/ipc_sender.h" | 30 #include "ipc/ipc_sender.h" |
30 #include "ui/events/event.h" | 31 #include "ui/events/event.h" |
(...skipping 18 matching lines...) Expand all Loading... |
49 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED"; | 50 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED"; |
50 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS"; | 51 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS"; |
51 case INPUT_EVENT_ACK_STATE_IGNORED: return "IGNORED"; | 52 case INPUT_EVENT_ACK_STATE_IGNORED: return "IGNORED"; |
52 } | 53 } |
53 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName."; | 54 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName."; |
54 return ""; | 55 return ""; |
55 } | 56 } |
56 | 57 |
57 } // namespace | 58 } // namespace |
58 | 59 |
59 InputRouterImpl::Config::Config() { | 60 InputRouterImpl::Config::Config() : validate_event_stream(false) { |
60 } | 61 } |
61 | 62 |
62 InputRouterImpl::InputRouterImpl(IPC::Sender* sender, | 63 InputRouterImpl::InputRouterImpl(IPC::Sender* sender, |
63 InputRouterClient* client, | 64 InputRouterClient* client, |
64 InputAckHandler* ack_handler, | 65 InputAckHandler* ack_handler, |
65 int routing_id, | 66 int routing_id, |
66 const Config& config) | 67 const Config& config) |
67 : sender_(sender), | 68 : sender_(sender), |
68 client_(client), | 69 client_(client), |
69 ack_handler_(ack_handler), | 70 ack_handler_(ack_handler), |
70 routing_id_(routing_id), | 71 routing_id_(routing_id), |
71 select_range_pending_(false), | 72 select_range_pending_(false), |
72 move_caret_pending_(false), | 73 move_caret_pending_(false), |
73 mouse_move_pending_(false), | 74 mouse_move_pending_(false), |
74 mouse_wheel_pending_(false), | 75 mouse_wheel_pending_(false), |
75 current_view_flags_(0), | 76 current_view_flags_(0), |
76 current_ack_source_(ACK_SOURCE_NONE), | 77 current_ack_source_(ACK_SOURCE_NONE), |
77 flush_requested_(false), | 78 flush_requested_(false), |
| 79 in_recycle_(false), |
78 touch_event_queue_(this, config.touch_config), | 80 touch_event_queue_(this, config.touch_config), |
79 gesture_event_queue_(this, this, config.gesture_config) { | 81 gesture_event_queue_(this, this, config.gesture_config) { |
80 DCHECK(sender); | 82 DCHECK(sender); |
81 DCHECK(client); | 83 DCHECK(client); |
82 DCHECK(ack_handler); | 84 DCHECK(ack_handler); |
83 UpdateTouchAckTimeoutEnabled(); | 85 UpdateTouchAckTimeoutEnabled(); |
| 86 if (config.validate_event_stream) { |
| 87 optional_input_stream_validator_.reset(new InputEventStreamValidator()); |
| 88 optional_output_stream_validator_.reset(new InputEventStreamValidator()); |
| 89 } |
84 } | 90 } |
85 | 91 |
86 InputRouterImpl::~InputRouterImpl() {} | 92 InputRouterImpl::~InputRouterImpl() {} |
87 | 93 |
88 void InputRouterImpl::Flush() { | |
89 flush_requested_ = true; | |
90 SignalFlushedIfNecessary(); | |
91 } | |
92 | |
93 bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) { | 94 bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) { |
94 DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart); | 95 DCHECK(!in_recycle_); |
| 96 DCHECK_EQ(IPC_MESSAGE_ID_CLASS(message->type()), InputMsgStart); |
95 switch (message->type()) { | 97 switch (message->type()) { |
96 // Check for types that require an ACK. | 98 // Check for types that require an ACK. |
97 case InputMsg_SelectRange::ID: | 99 case InputMsg_SelectRange::ID: |
98 return SendSelectRange(message.Pass()); | 100 return SendSelectRange(message.Pass()); |
99 case InputMsg_MoveCaret::ID: | 101 case InputMsg_MoveCaret::ID: |
100 return SendMoveCaret(message.Pass()); | 102 return SendMoveCaret(message.Pass()); |
101 case InputMsg_HandleInputEvent::ID: | 103 case InputMsg_HandleInputEvent::ID: |
102 NOTREACHED() << "WebInputEvents should never be sent via SendInput."; | 104 NOTREACHED() << "WebInputEvents should never be sent via SendInput."; |
103 return false; | 105 return false; |
104 default: | 106 default: |
105 return Send(message.release()); | 107 return Send(message.release()); |
106 } | 108 } |
107 } | 109 } |
108 | 110 |
109 void InputRouterImpl::SendMouseEvent( | 111 void InputRouterImpl::SendMouseEvent( |
110 const MouseEventWithLatencyInfo& mouse_event) { | 112 const MouseEventWithLatencyInfo& mouse_event) { |
| 113 DCHECK(!in_recycle_); |
111 if (mouse_event.event.type == WebInputEvent::MouseDown && | 114 if (mouse_event.event.type == WebInputEvent::MouseDown && |
112 gesture_event_queue_.GetTouchpadTapSuppressionController()-> | 115 gesture_event_queue_.GetTouchpadTapSuppressionController()-> |
113 ShouldDeferMouseDown(mouse_event)) | 116 ShouldDeferMouseDown(mouse_event)) |
114 return; | 117 return; |
115 if (mouse_event.event.type == WebInputEvent::MouseUp && | 118 if (mouse_event.event.type == WebInputEvent::MouseUp && |
116 gesture_event_queue_.GetTouchpadTapSuppressionController()-> | 119 gesture_event_queue_.GetTouchpadTapSuppressionController()-> |
117 ShouldSuppressMouseUp()) | 120 ShouldSuppressMouseUp()) |
118 return; | 121 return; |
119 | 122 |
120 SendMouseEventImmediately(mouse_event); | 123 SendMouseEventImmediately(mouse_event); |
121 } | 124 } |
122 | 125 |
123 void InputRouterImpl::SendWheelEvent( | 126 void InputRouterImpl::SendWheelEvent( |
124 const MouseWheelEventWithLatencyInfo& wheel_event) { | 127 const MouseWheelEventWithLatencyInfo& wheel_event) { |
| 128 DCHECK(!in_recycle_); |
125 SendWheelEvent(QueuedWheelEvent(wheel_event, false)); | 129 SendWheelEvent(QueuedWheelEvent(wheel_event, false)); |
126 } | 130 } |
127 | 131 |
128 void InputRouterImpl::SendWheelEvent(const QueuedWheelEvent& wheel_event) { | 132 void InputRouterImpl::SendWheelEvent(const QueuedWheelEvent& wheel_event) { |
| 133 DCHECK(!in_recycle_); |
129 if (mouse_wheel_pending_) { | 134 if (mouse_wheel_pending_) { |
130 // If there's already a mouse wheel event waiting to be sent to the | 135 // If there's already a mouse wheel event waiting to be sent to the |
131 // renderer, add the new deltas to that event. Not doing so (e.g., by | 136 // renderer, add the new deltas to that event. Not doing so (e.g., by |
132 // dropping the old event, as for mouse moves) results in very slow | 137 // dropping the old event, as for mouse moves) results in very slow |
133 // scrolling on the Mac (on which many, very small wheel events are sent). | 138 // scrolling on the Mac (on which many, very small wheel events are sent). |
134 // Note that we can't coalesce wheel events for pinches because the GEQ | 139 // Note that we can't coalesce wheel events for pinches because the GEQ |
135 // expects one ACK for each (but it's fine to coalesce non-pinch wheels | 140 // expects one ACK for each (but it's fine to coalesce non-pinch wheels |
136 // into a pinch one). Note that the GestureEventQueue ensures we only | 141 // into a pinch one). Note that the GestureEventQueue ensures we only |
137 // ever have a single pinch event queued here. | 142 // ever have a single pinch event queued here. |
138 if (coalesced_mouse_wheel_events_.empty() || | 143 if (coalesced_mouse_wheel_events_.empty() || |
(...skipping 14 matching lines...) Expand all Loading... |
153 LOCAL_HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", | 158 LOCAL_HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", |
154 coalesced_mouse_wheel_events_.size()); | 159 coalesced_mouse_wheel_events_.size()); |
155 | 160 |
156 FilterAndSendWebInputEvent( | 161 FilterAndSendWebInputEvent( |
157 wheel_event.event.event, wheel_event.event.latency, false); | 162 wheel_event.event.event, wheel_event.event.latency, false); |
158 } | 163 } |
159 | 164 |
160 void InputRouterImpl::SendKeyboardEvent(const NativeWebKeyboardEvent& key_event, | 165 void InputRouterImpl::SendKeyboardEvent(const NativeWebKeyboardEvent& key_event, |
161 const ui::LatencyInfo& latency_info, | 166 const ui::LatencyInfo& latency_info, |
162 bool is_keyboard_shortcut) { | 167 bool is_keyboard_shortcut) { |
| 168 DCHECK(!in_recycle_); |
163 // Put all WebKeyboardEvent objects in a queue since we can't trust the | 169 // Put all WebKeyboardEvent objects in a queue since we can't trust the |
164 // renderer and we need to give something to the HandleKeyboardEvent | 170 // renderer and we need to give something to the HandleKeyboardEvent |
165 // handler. | 171 // handler. |
166 key_queue_.push_back(key_event); | 172 key_queue_.push_back(key_event); |
167 LOCAL_HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); | 173 LOCAL_HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); |
168 | 174 |
169 gesture_event_queue_.FlingHasBeenHalted(); | 175 gesture_event_queue_.FlingHasBeenHalted(); |
170 | 176 |
171 // Only forward the non-native portions of our event. | 177 // Only forward the non-native portions of our event. |
172 FilterAndSendWebInputEvent(key_event, latency_info, is_keyboard_shortcut); | 178 FilterAndSendWebInputEvent(key_event, latency_info, is_keyboard_shortcut); |
173 } | 179 } |
174 | 180 |
175 void InputRouterImpl::SendGestureEvent( | 181 void InputRouterImpl::SendGestureEvent( |
176 const GestureEventWithLatencyInfo& original_gesture_event) { | 182 const GestureEventWithLatencyInfo& original_gesture_event) { |
177 input_stream_validator_.Validate(original_gesture_event.event); | 183 if (in_recycle_) |
| 184 return; |
| 185 |
| 186 if (optional_input_stream_validator_) |
| 187 optional_input_stream_validator_->Validate(original_gesture_event.event); |
178 | 188 |
179 GestureEventWithLatencyInfo gesture_event(original_gesture_event); | 189 GestureEventWithLatencyInfo gesture_event(original_gesture_event); |
180 | 190 |
181 if (touch_action_filter_.FilterGestureEvent(&gesture_event.event)) | 191 if (touch_action_filter_.FilterGestureEvent(&gesture_event.event)) |
182 return; | 192 return; |
183 | 193 |
184 if (gesture_event.event.sourceDevice == blink::WebGestureDeviceTouchscreen) | 194 if (gesture_event.event.sourceDevice == blink::WebGestureDeviceTouchscreen) |
185 touch_event_queue_.OnGestureScrollEvent(gesture_event); | 195 touch_event_queue_.OnGestureScrollEvent(gesture_event); |
186 | 196 |
187 if (!gesture_event_queue_.ShouldForward(gesture_event)) | 197 if (!gesture_event_queue_.ShouldForward(gesture_event)) |
188 return; | 198 return; |
189 | 199 |
190 SendGestureEventImmediately(gesture_event); | 200 SendGestureEventImmediately(gesture_event); |
191 } | 201 } |
192 | 202 |
193 void InputRouterImpl::SendTouchEvent( | 203 void InputRouterImpl::SendTouchEvent( |
194 const TouchEventWithLatencyInfo& touch_event) { | 204 const TouchEventWithLatencyInfo& touch_event) { |
195 input_stream_validator_.Validate(touch_event.event); | 205 DCHECK(!in_recycle_); |
| 206 if (optional_input_stream_validator_) |
| 207 optional_input_stream_validator_->Validate(touch_event.event); |
196 touch_event_queue_.QueueEvent(touch_event); | 208 touch_event_queue_.QueueEvent(touch_event); |
197 } | 209 } |
198 | 210 |
| 211 void InputRouterImpl::Recycle() { |
| 212 DCHECK(!in_recycle_); |
| 213 DCHECK_EQ(current_ack_source_, ACK_SOURCE_NONE); |
| 214 base::AutoReset<bool> auto_reset_in_recycle(&in_recycle_, true); |
| 215 |
| 216 key_queue_.clear(); |
| 217 coalesced_mouse_wheel_events_.clear(); |
| 218 next_mouse_move_.reset(); |
| 219 next_selection_range_.reset(); |
| 220 next_move_caret_.reset(); |
| 221 |
| 222 // It's *extremely* important that all touches currently queued be ack'ed to |
| 223 // the view. Though all (potentially) derived gestures will be ignored, the |
| 224 // touches must be ack'ed to the client, ensuring upstream gesture detection |
| 225 // is properly flushed. |
| 226 touch_event_queue_.Flush(INPUT_EVENT_ACK_STATE_CONSUMED); |
| 227 gesture_event_queue_.Recycle(); |
| 228 touch_action_filter_.ResetTouchAction(); |
| 229 |
| 230 if (optional_input_stream_validator_) |
| 231 optional_input_stream_validator_.reset(new InputEventStreamValidator()); |
| 232 if (optional_output_stream_validator_) |
| 233 optional_output_stream_validator_.reset(new InputEventStreamValidator()); |
| 234 |
| 235 DCHECK(!HasPendingEvents()); |
| 236 SignalFlushedIfNecessary(); |
| 237 } |
| 238 |
| 239 void InputRouterImpl::RequestFlushedNotification() { |
| 240 flush_requested_ = true; |
| 241 SignalFlushedIfNecessary(); |
| 242 } |
| 243 |
199 // Forwards MouseEvent without passing it through | 244 // Forwards MouseEvent without passing it through |
200 // TouchpadTapSuppressionController. | 245 // TouchpadTapSuppressionController. |
201 void InputRouterImpl::SendMouseEventImmediately( | 246 void InputRouterImpl::SendMouseEventImmediately( |
202 const MouseEventWithLatencyInfo& mouse_event) { | 247 const MouseEventWithLatencyInfo& mouse_event) { |
203 // Avoid spamming the renderer with mouse move events. It is important | 248 // Avoid spamming the renderer with mouse move events. It is important |
204 // to note that WM_MOUSEMOVE events are anyways synthetic, but since our | 249 // to note that WM_MOUSEMOVE events are anyways synthetic, but since our |
205 // thread is able to rapidly consume WM_MOUSEMOVE events, we may get way | 250 // thread is able to rapidly consume WM_MOUSEMOVE events, we may get way |
206 // more WM_MOUSEMOVE events than we wish to send to the renderer. | 251 // more WM_MOUSEMOVE events than we wish to send to the renderer. |
207 if (mouse_event.event.type == WebInputEvent::MouseMove) { | 252 if (mouse_event.event.type == WebInputEvent::MouseMove) { |
208 if (mouse_move_pending_) { | 253 if (mouse_move_pending_) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 if (select_range_pending_) { | 348 if (select_range_pending_) { |
304 next_selection_range_ = message.Pass(); | 349 next_selection_range_ = message.Pass(); |
305 return true; | 350 return true; |
306 } | 351 } |
307 | 352 |
308 select_range_pending_ = true; | 353 select_range_pending_ = true; |
309 return Send(message.release()); | 354 return Send(message.release()); |
310 } | 355 } |
311 | 356 |
312 bool InputRouterImpl::SendMoveCaret(scoped_ptr<IPC::Message> message) { | 357 bool InputRouterImpl::SendMoveCaret(scoped_ptr<IPC::Message> message) { |
313 DCHECK(message->type() == InputMsg_MoveCaret::ID); | 358 DCHECK_EQ(message->type(), InputMsg_MoveCaret::ID); |
314 if (move_caret_pending_) { | 359 if (move_caret_pending_) { |
315 next_move_caret_ = message.Pass(); | 360 next_move_caret_ = message.Pass(); |
316 return true; | 361 return true; |
317 } | 362 } |
318 | 363 |
319 move_caret_pending_ = true; | 364 move_caret_pending_ = true; |
320 return Send(message.release()); | 365 return Send(message.release()); |
321 } | 366 } |
322 | 367 |
323 bool InputRouterImpl::Send(IPC::Message* message) { | 368 bool InputRouterImpl::Send(IPC::Message* message) { |
(...skipping 11 matching lines...) Expand all Loading... |
335 | 380 |
336 // Any input event cancels a pending mouse move event. | 381 // Any input event cancels a pending mouse move event. |
337 next_mouse_move_.reset(); | 382 next_mouse_move_.reset(); |
338 | 383 |
339 OfferToHandlers(input_event, latency_info, is_keyboard_shortcut); | 384 OfferToHandlers(input_event, latency_info, is_keyboard_shortcut); |
340 } | 385 } |
341 | 386 |
342 void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, | 387 void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, |
343 const ui::LatencyInfo& latency_info, | 388 const ui::LatencyInfo& latency_info, |
344 bool is_keyboard_shortcut) { | 389 bool is_keyboard_shortcut) { |
345 output_stream_validator_.Validate(input_event); | 390 DCHECK(!in_recycle_); |
| 391 if (optional_output_stream_validator_) |
| 392 optional_output_stream_validator_->Validate(input_event); |
346 | 393 |
347 if (OfferToClient(input_event, latency_info)) | 394 if (OfferToClient(input_event, latency_info)) |
348 return; | 395 return; |
349 | 396 |
350 OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); | 397 OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); |
351 | 398 |
352 // Touch events should always indicate in the event whether they are | 399 // Touch events should always indicate in the event whether they are |
353 // cancelable (respect ACK disposition) or not. | 400 // cancelable (respect ACK disposition) or not. |
354 bool ignores_ack = WebInputEventTraits::IgnoresAckDisposition(input_event); | 401 bool ignores_ack = WebInputEventTraits::IgnoresAckDisposition(input_event); |
355 if (WebInputEvent::isTouchEventType(input_event.type)) { | 402 if (WebInputEvent::isTouchEventType(input_event.type)) { |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 // Lack of a touch handler indicates that the page either has no touch-action | 547 // Lack of a touch handler indicates that the page either has no touch-action |
501 // modifiers or that all its touch-action modifiers are auto. Resetting the | 548 // modifiers or that all its touch-action modifiers are auto. Resetting the |
502 // touch-action here allows forwarding of subsequent gestures even if the | 549 // touch-action here allows forwarding of subsequent gestures even if the |
503 // underlying touches never reach the router. | 550 // underlying touches never reach the router. |
504 // TODO(jdduke): Reset touch-action only at the end of a touch sequence to | 551 // TODO(jdduke): Reset touch-action only at the end of a touch sequence to |
505 // prevent potentially strange mid-sequence behavior, crbug.com/375940. | 552 // prevent potentially strange mid-sequence behavior, crbug.com/375940. |
506 if (!has_handlers) | 553 if (!has_handlers) |
507 touch_action_filter_.ResetTouchAction(); | 554 touch_action_filter_.ResetTouchAction(); |
508 | 555 |
509 touch_event_queue_.OnHasTouchEventHandlers(has_handlers); | 556 touch_event_queue_.OnHasTouchEventHandlers(has_handlers); |
510 client_->OnHasTouchEventHandlers(has_handlers); | |
511 } | 557 } |
512 | 558 |
513 void InputRouterImpl::OnSetTouchAction(TouchAction touch_action) { | 559 void InputRouterImpl::OnSetTouchAction(TouchAction touch_action) { |
514 // Synthetic touchstart events should get filtered out in RenderWidget. | 560 // Synthetic touchstart events should get filtered out in RenderWidget. |
515 DCHECK(touch_event_queue_.IsPendingAckTouchStart()); | 561 DCHECK(touch_event_queue_.IsPendingAckTouchStart()); |
516 TRACE_EVENT1("input", "InputRouterImpl::OnSetTouchAction", | 562 TRACE_EVENT1("input", "InputRouterImpl::OnSetTouchAction", |
517 "action", touch_action); | 563 "action", touch_action); |
518 | 564 |
519 touch_action_filter_.OnSetTouchAction(touch_action); | 565 touch_action_filter_.OnSetTouchAction(touch_action); |
520 | 566 |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent( | 736 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent( |
691 const MouseWheelEventWithLatencyInfo& event, | 737 const MouseWheelEventWithLatencyInfo& event, |
692 bool synthesized_from_pinch) | 738 bool synthesized_from_pinch) |
693 : event(event), synthesized_from_pinch(synthesized_from_pinch) { | 739 : event(event), synthesized_from_pinch(synthesized_from_pinch) { |
694 } | 740 } |
695 | 741 |
696 InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() { | 742 InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() { |
697 } | 743 } |
698 | 744 |
699 } // namespace content | 745 } // namespace content |
OLD | NEW |