OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/mouse_wheel_event_queue.h" | 5 #include "content/browser/renderer_host/input/mouse_wheel_event_queue.h" |
6 | 6 |
7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
8 #include "base/metrics/histogram_macros.h" | 8 #include "base/metrics/histogram_macros.h" |
9 #include "base/trace_event/trace_event.h" | 9 #include "base/trace_event/trace_event.h" |
10 #include "ui/events/base_event_utils.h" | 10 #include "ui/events/base_event_utils.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 TRACE_EVENT_ASYNC_END0("input", "MouseWheelEventQueue::QueueEvent", this); | 30 TRACE_EVENT_ASYNC_END0("input", "MouseWheelEventQueue::QueueEvent", this); |
31 } | 31 } |
32 | 32 |
33 private: | 33 private: |
34 DISALLOW_COPY_AND_ASSIGN(QueuedWebMouseWheelEvent); | 34 DISALLOW_COPY_AND_ASSIGN(QueuedWebMouseWheelEvent); |
35 }; | 35 }; |
36 | 36 |
37 MouseWheelEventQueue::MouseWheelEventQueue(MouseWheelEventQueueClient* client, | 37 MouseWheelEventQueue::MouseWheelEventQueue(MouseWheelEventQueueClient* client, |
38 bool enable_scroll_latching) | 38 bool enable_scroll_latching) |
39 : client_(client), | 39 : client_(client), |
40 needs_scroll_begin_(true), | |
41 needs_scroll_end_(false), | |
42 enable_scroll_latching_(enable_scroll_latching), | 40 enable_scroll_latching_(enable_scroll_latching), |
43 scrolling_device_(blink::kWebGestureDeviceUninitialized) { | 41 scrolling_device_(blink::kWebGestureDeviceUninitialized) { |
44 DCHECK(client); | 42 DCHECK(client); |
45 scroll_transaction_ms_ = | 43 scroll_transaction_ms_ = |
46 enable_scroll_latching_ ? kDefaultWheelScrollLatchingTransactionMs : 0; | 44 enable_scroll_latching_ ? kDefaultWheelScrollLatchingTransactionMs : 0; |
47 } | 45 } |
48 | 46 |
49 MouseWheelEventQueue::~MouseWheelEventQueue() { | 47 MouseWheelEventQueue::~MouseWheelEventQueue() { |
50 } | 48 } |
51 | 49 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 } | 171 } |
174 | 172 |
175 bool needs_update = scroll_update.data.scroll_update.delta_x != 0 || | 173 bool needs_update = scroll_update.data.scroll_update.delta_x != 0 || |
176 scroll_update.data.scroll_update.delta_y != 0; | 174 scroll_update.data.scroll_update.delta_y != 0; |
177 | 175 |
178 // If there is no update to send and the current phase is ended yet a GSB | 176 // If there is no update to send and the current phase is ended yet a GSB |
179 // needs to be sent, this event sequence doesn't need to be generated | 177 // needs to be sent, this event sequence doesn't need to be generated |
180 // because the events generated will be a GSB (non-synthetic) and GSE | 178 // because the events generated will be a GSB (non-synthetic) and GSE |
181 // (non-synthetic). This situation arises when OSX generates double | 179 // (non-synthetic). This situation arises when OSX generates double |
182 // phase end information. | 180 // phase end information. |
183 bool empty_sequence = | 181 bool empty_sequence = !needs_update && !client_->is_in_gesture_scroll() && |
184 !needs_update && needs_scroll_begin_ && current_phase_ended; | 182 current_phase_ended; |
185 | 183 |
186 if (enable_scroll_latching_) { | 184 if (enable_scroll_latching_) { |
187 if (event_sent_for_gesture_ack_->event.momentum_phase == | 185 if (event_sent_for_gesture_ack_->event.momentum_phase == |
188 blink::WebMouseWheelEvent::kPhaseBegan) { | 186 blink::WebMouseWheelEvent::kPhaseBegan) { |
189 // Don't send the pending scrollEnd if a fling starts. | 187 // Don't send the pending scrollEnd if a fling starts. |
190 if (scroll_end_timer_.IsRunning()) | 188 if (scroll_end_timer_.IsRunning()) |
191 scroll_end_timer_.Stop(); | 189 scroll_end_timer_.Stop(); |
192 } | 190 } |
193 | 191 |
194 if (needs_update || !empty_sequence) { | 192 if (needs_update || !empty_sequence) { |
195 if (needs_scroll_begin_) { | 193 if (!client_->is_in_gesture_scroll()) { |
196 SendScrollBegin(scroll_update, false); | 194 SendScrollBegin(scroll_update, false); |
197 } | 195 } |
198 | 196 |
199 if (needs_update) { | 197 if (needs_update) { |
200 ui::LatencyInfo latency = ui::LatencyInfo(ui::SourceEventType::WHEEL); | 198 ui::LatencyInfo latency = ui::LatencyInfo(ui::SourceEventType::WHEEL); |
201 latency.AddLatencyNumber( | 199 latency.AddLatencyNumber( |
202 ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, | 200 ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, |
203 0, 0); | 201 0, 0); |
204 client_->ForwardGestureEventWithLatencyInfo(scroll_update, latency); | 202 client_->ForwardGestureEventWithLatencyInfo(scroll_update, latency); |
205 } | 203 } |
206 | 204 |
207 if (momentum_phase_ended) { | 205 if (momentum_phase_ended) { |
208 // Send GSE with if scroll latching is enabled and no fling is going | 206 // Send GSE with if scroll latching is enabled and no fling is going |
209 // to happen next. | 207 // to happen next. |
210 SendScrollEnd(scroll_update, false); | 208 SendScrollEnd(scroll_update, false); |
211 } else if (scroll_phase_ended || !has_phase_info) { | 209 } else if (scroll_phase_ended || !has_phase_info) { |
212 // If scroll latching is enabled and a fling might happen next, or | 210 // If scroll latching is enabled and a fling might happen next, or |
213 // no phase info exists, start the scroll_end_timer_. | 211 // no phase info exists, start the scroll_end_timer_. |
214 scroll_end_timer_.Start( | 212 scroll_end_timer_.Start( |
215 FROM_HERE, | 213 FROM_HERE, |
216 base::TimeDelta::FromMilliseconds(scroll_transaction_ms_), | 214 base::TimeDelta::FromMilliseconds(scroll_transaction_ms_), |
217 base::Bind(&MouseWheelEventQueue::SendScrollEnd, | 215 base::Bind(&MouseWheelEventQueue::SendScrollEnd, |
218 base::Unretained(this), scroll_update, false)); | 216 base::Unretained(this), scroll_update, false)); |
219 } | 217 } |
220 } | 218 } |
221 | 219 |
222 } else { // !enable_scroll_latching_ | 220 } else { // !enable_scroll_latching_ |
223 if (needs_update || !empty_sequence) { | 221 if (needs_update || !empty_sequence) { |
224 if (needs_scroll_begin_) { | 222 if (!client_->is_in_gesture_scroll()) { |
225 // If no GSB has been sent, it will be a non-synthetic GSB. | 223 // If no GSB has been sent, it will be a non-synthetic GSB. |
226 SendScrollBegin(scroll_update, false); | 224 SendScrollBegin(scroll_update, false); |
227 } else if (has_phase_info) { | 225 } else if (has_phase_info) { |
228 // If a GSB has been sent, generate a synthetic GSB if we have phase | 226 // If a GSB has been sent, generate a synthetic GSB if we have phase |
229 // information. This should be removed once crbug.com/526463 is | 227 // information. This should be removed once crbug.com/526463 is |
230 // fully implemented. | 228 // fully implemented. |
231 SendScrollBegin(scroll_update, true); | 229 SendScrollBegin(scroll_update, true); |
232 } | 230 } |
233 | 231 |
234 if (needs_update) { | 232 if (needs_update) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 (gesture_event.event.GetType() == | 275 (gesture_event.event.GetType() == |
278 blink::WebInputEvent::kGestureScrollEnd || | 276 blink::WebInputEvent::kGestureScrollEnd || |
279 gesture_event.event.GetType() == | 277 gesture_event.event.GetType() == |
280 blink::WebInputEvent::kGestureFlingStart)) { | 278 blink::WebInputEvent::kGestureFlingStart)) { |
281 scrolling_device_ = blink::kWebGestureDeviceUninitialized; | 279 scrolling_device_ = blink::kWebGestureDeviceUninitialized; |
282 if (scroll_end_timer_.IsRunning()) { | 280 if (scroll_end_timer_.IsRunning()) { |
283 if (enable_scroll_latching_) { | 281 if (enable_scroll_latching_) { |
284 // Don't send the pending ScrollEnd if a fling is happening. | 282 // Don't send the pending ScrollEnd if a fling is happening. |
285 // The next wheel event will still need a ScrollBegin. | 283 // The next wheel event will still need a ScrollBegin. |
286 scroll_end_timer_.Stop(); | 284 scroll_end_timer_.Stop(); |
287 needs_scroll_begin_ = true; | |
288 needs_scroll_end_ = false; | |
289 } else { | 285 } else { |
290 scroll_end_timer_.Reset(); | 286 scroll_end_timer_.Reset(); |
291 } | 287 } |
292 } | 288 } |
293 } | 289 } |
294 } | 290 } |
295 | 291 |
296 void MouseWheelEventQueue::TryForwardNextEventToRenderer() { | 292 void MouseWheelEventQueue::TryForwardNextEventToRenderer() { |
297 TRACE_EVENT0("input", "MouseWheelEventQueue::TryForwardNextEventToRenderer"); | 293 TRACE_EVENT0("input", "MouseWheelEventQueue::TryForwardNextEventToRenderer"); |
298 | 294 |
299 if (wheel_queue_.empty() || event_sent_for_gesture_ack_) | 295 if (wheel_queue_.empty() || event_sent_for_gesture_ack_) |
300 return; | 296 return; |
301 | 297 |
302 event_sent_for_gesture_ack_ = std::move(wheel_queue_.front()); | 298 event_sent_for_gesture_ack_ = std::move(wheel_queue_.front()); |
303 wheel_queue_.pop_front(); | 299 wheel_queue_.pop_front(); |
304 | 300 |
305 client_->SendMouseWheelEventImmediately(*event_sent_for_gesture_ack_); | 301 client_->SendMouseWheelEventImmediately(*event_sent_for_gesture_ack_); |
306 } | 302 } |
307 | 303 |
308 void MouseWheelEventQueue::SendScrollEnd(WebGestureEvent update_event, | 304 void MouseWheelEventQueue::SendScrollEnd(WebGestureEvent update_event, |
309 bool synthetic) { | 305 bool synthetic) { |
310 DCHECK((synthetic && !needs_scroll_end_) || needs_scroll_end_); | 306 DCHECK((synthetic && !client_->is_in_gesture_scroll()) || |
| 307 client_->is_in_gesture_scroll()); |
311 | 308 |
312 WebGestureEvent scroll_end(update_event); | 309 WebGestureEvent scroll_end(update_event); |
313 scroll_end.SetTimeStampSeconds( | 310 scroll_end.SetTimeStampSeconds( |
314 ui::EventTimeStampToSeconds(ui::EventTimeForNow())); | 311 ui::EventTimeStampToSeconds(ui::EventTimeForNow())); |
315 scroll_end.SetType(WebInputEvent::kGestureScrollEnd); | 312 scroll_end.SetType(WebInputEvent::kGestureScrollEnd); |
316 scroll_end.resending_plugin_id = -1; | 313 scroll_end.resending_plugin_id = -1; |
317 scroll_end.data.scroll_end.synthetic = synthetic; | 314 scroll_end.data.scroll_end.synthetic = synthetic; |
318 scroll_end.data.scroll_end.inertial_phase = | 315 scroll_end.data.scroll_end.inertial_phase = |
319 update_event.data.scroll_update.inertial_phase; | 316 update_event.data.scroll_update.inertial_phase; |
320 scroll_end.data.scroll_end.delta_units = | 317 scroll_end.data.scroll_end.delta_units = |
321 update_event.data.scroll_update.delta_units; | 318 update_event.data.scroll_update.delta_units; |
322 | 319 |
323 if (!synthetic) { | 320 if (!synthetic && scroll_end_timer_.IsRunning()) |
324 needs_scroll_begin_ = true; | 321 scroll_end_timer_.Reset(); |
325 needs_scroll_end_ = false; | |
326 | 322 |
327 if (scroll_end_timer_.IsRunning()) | |
328 scroll_end_timer_.Reset(); | |
329 } | |
330 client_->ForwardGestureEventWithLatencyInfo( | 323 client_->ForwardGestureEventWithLatencyInfo( |
331 scroll_end, ui::LatencyInfo(ui::SourceEventType::WHEEL)); | 324 scroll_end, ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
332 } | 325 } |
333 | 326 |
334 void MouseWheelEventQueue::SendScrollBegin( | 327 void MouseWheelEventQueue::SendScrollBegin( |
335 const WebGestureEvent& gesture_update, | 328 const WebGestureEvent& gesture_update, |
336 bool synthetic) { | 329 bool synthetic) { |
337 DCHECK((synthetic && !needs_scroll_begin_) || needs_scroll_begin_); | 330 DCHECK((synthetic && client_->is_in_gesture_scroll()) || |
| 331 !client_->is_in_gesture_scroll()); |
338 | 332 |
339 WebGestureEvent scroll_begin(gesture_update); | 333 WebGestureEvent scroll_begin(gesture_update); |
340 scroll_begin.SetType(WebInputEvent::kGestureScrollBegin); | 334 scroll_begin.SetType(WebInputEvent::kGestureScrollBegin); |
341 scroll_begin.data.scroll_begin.synthetic = synthetic; | 335 scroll_begin.data.scroll_begin.synthetic = synthetic; |
342 scroll_begin.data.scroll_begin.inertial_phase = | 336 scroll_begin.data.scroll_begin.inertial_phase = |
343 gesture_update.data.scroll_update.inertial_phase; | 337 gesture_update.data.scroll_update.inertial_phase; |
344 scroll_begin.data.scroll_begin.delta_x_hint = | 338 scroll_begin.data.scroll_begin.delta_x_hint = |
345 gesture_update.data.scroll_update.delta_x; | 339 gesture_update.data.scroll_update.delta_x; |
346 scroll_begin.data.scroll_begin.delta_y_hint = | 340 scroll_begin.data.scroll_begin.delta_y_hint = |
347 gesture_update.data.scroll_update.delta_y; | 341 gesture_update.data.scroll_update.delta_y; |
348 scroll_begin.data.scroll_begin.target_viewport = false; | 342 scroll_begin.data.scroll_begin.target_viewport = false; |
349 scroll_begin.data.scroll_begin.delta_hint_units = | 343 scroll_begin.data.scroll_begin.delta_hint_units = |
350 gesture_update.data.scroll_update.delta_units; | 344 gesture_update.data.scroll_update.delta_units; |
351 | 345 |
352 needs_scroll_begin_ = false; | |
353 needs_scroll_end_ = true; | |
354 client_->ForwardGestureEventWithLatencyInfo( | 346 client_->ForwardGestureEventWithLatencyInfo( |
355 scroll_begin, ui::LatencyInfo(ui::SourceEventType::WHEEL)); | 347 scroll_begin, ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
356 } | 348 } |
357 | 349 |
358 } // namespace content | 350 } // namespace content |
OLD | NEW |