Chromium Code Reviews| 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); |
|
dtapuska
2017/04/12 19:24:46
It there any potential dangerous scenarios here? W
wjmaclean
2017/04/12 19:47:35
I suppose, but (1) it passes the tests, and (2) ap
wjmaclean
2017/04/12 19:48:42
Also, it does fix something we know is already bro
| |
| 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) { |
| 235 ui::LatencyInfo latency = ui::LatencyInfo(ui::SourceEventType::WHEEL); | 233 ui::LatencyInfo latency = ui::LatencyInfo(ui::SourceEventType::WHEEL); |
| 236 latency.AddLatencyNumber( | 234 latency.AddLatencyNumber( |
| (...skipping 40 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 |