| 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 24 matching lines...) Expand all Loading... |
| 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), | 40 needs_scroll_begin_(true), |
| 41 needs_scroll_end_(false), | 41 needs_scroll_end_(false), |
| 42 enable_scroll_latching_(enable_scroll_latching), | 42 enable_scroll_latching_(enable_scroll_latching), |
| 43 scrolling_device_(blink::kWebGestureDeviceUninitialized) { | 43 scrolling_device_(blink::kWebGestureDeviceUninitialized) { |
| 44 DCHECK(client); | 44 DCHECK(client); |
| 45 scroll_transaction_ms_ = | |
| 46 enable_scroll_latching_ ? kDefaultWheelScrollLatchingTransactionMs : 0; | |
| 47 } | 45 } |
| 48 | 46 |
| 49 MouseWheelEventQueue::~MouseWheelEventQueue() { | 47 MouseWheelEventQueue::~MouseWheelEventQueue() { |
| 50 } | 48 } |
| 51 | 49 |
| 52 void MouseWheelEventQueue::QueueEvent( | 50 void MouseWheelEventQueue::QueueEvent( |
| 53 const MouseWheelEventWithLatencyInfo& event) { | 51 const MouseWheelEventWithLatencyInfo& event) { |
| 54 TRACE_EVENT0("input", "MouseWheelEventQueue::QueueEvent"); | 52 TRACE_EVENT0("input", "MouseWheelEventQueue::QueueEvent"); |
| 55 | 53 |
| 56 if (event_sent_for_gesture_ack_ && !wheel_queue_.empty()) { | 54 if (event_sent_for_gesture_ack_ && !wheel_queue_.empty()) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 event_sent_for_gesture_ack_->event.momentum_phase == | 166 event_sent_for_gesture_ack_->event.momentum_phase == |
| 169 blink::WebMouseWheelEvent::kPhaseEnded || | 167 blink::WebMouseWheelEvent::kPhaseEnded || |
| 170 event_sent_for_gesture_ack_->event.momentum_phase == | 168 event_sent_for_gesture_ack_->event.momentum_phase == |
| 171 blink::WebMouseWheelEvent::kPhaseCancelled; | 169 blink::WebMouseWheelEvent::kPhaseCancelled; |
| 172 current_phase_ended = scroll_phase_ended || momentum_phase_ended; | 170 current_phase_ended = scroll_phase_ended || momentum_phase_ended; |
| 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 | |
| 179 // 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 | |
| 181 // (non-synthetic). This situation arises when OSX generates double | |
| 182 // phase end information. | |
| 183 bool empty_sequence = | |
| 184 !needs_update && needs_scroll_begin_ && current_phase_ended; | |
| 185 | |
| 186 if (enable_scroll_latching_) { | 176 if (enable_scroll_latching_) { |
| 187 if (event_sent_for_gesture_ack_->event.momentum_phase == | 177 if (event_sent_for_gesture_ack_->event.phase == |
| 188 blink::WebMouseWheelEvent::kPhaseBegan) { | 178 blink::WebMouseWheelEvent::kPhaseBegan) { |
| 189 // Don't send the pending scrollEnd if a fling starts. | 179 SendScrollBegin(scroll_update, false); |
| 190 if (scroll_end_timer_.IsRunning()) | |
| 191 scroll_end_timer_.Stop(); | |
| 192 } | 180 } |
| 193 | 181 |
| 194 if (needs_update || !empty_sequence) { | 182 if (needs_update) { |
| 195 if (needs_scroll_begin_) { | 183 ui::LatencyInfo latency = ui::LatencyInfo(ui::SourceEventType::WHEEL); |
| 196 SendScrollBegin(scroll_update, false); | 184 latency.AddLatencyNumber( |
| 197 } | 185 ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, 0, |
| 198 | 186 0); |
| 199 if (needs_update) { | 187 client_->ForwardGestureEventWithLatencyInfo(scroll_update, latency); |
| 200 ui::LatencyInfo latency = ui::LatencyInfo(ui::SourceEventType::WHEEL); | |
| 201 latency.AddLatencyNumber( | |
| 202 ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, | |
| 203 0, 0); | |
| 204 client_->ForwardGestureEventWithLatencyInfo(scroll_update, latency); | |
| 205 } | |
| 206 | |
| 207 if (momentum_phase_ended) { | |
| 208 // Send GSE with if scroll latching is enabled and no fling is going | |
| 209 // to happen next. | |
| 210 SendScrollEnd(scroll_update, false); | |
| 211 } else if (scroll_phase_ended || !has_phase_info) { | |
| 212 // If scroll latching is enabled and a fling might happen next, or | |
| 213 // no phase info exists, start the scroll_end_timer_. | |
| 214 scroll_end_timer_.Start( | |
| 215 FROM_HERE, | |
| 216 base::TimeDelta::FromMilliseconds(scroll_transaction_ms_), | |
| 217 base::Bind(&MouseWheelEventQueue::SendScrollEnd, | |
| 218 base::Unretained(this), scroll_update, false)); | |
| 219 } | |
| 220 } | 188 } |
| 221 | 189 |
| 190 if (current_phase_ended) { |
| 191 // Send GSE with if scroll latching is enabled and no fling is going |
| 192 // to happen next. |
| 193 SendScrollEnd(scroll_update, false); |
| 194 } |
| 222 } else { // !enable_scroll_latching_ | 195 } else { // !enable_scroll_latching_ |
| 196 |
| 197 // If there is no update to send and the current phase is ended yet a GSB |
| 198 // needs to be sent, this event sequence doesn't need to be generated |
| 199 // because the events generated will be a GSB (non-synthetic) and GSE |
| 200 // (non-synthetic). This situation arises when OSX generates double |
| 201 // phase end information. |
| 202 bool empty_sequence = |
| 203 !needs_update && needs_scroll_begin_ && current_phase_ended; |
| 223 if (needs_update || !empty_sequence) { | 204 if (needs_update || !empty_sequence) { |
| 224 if (needs_scroll_begin_) { | 205 if (needs_scroll_begin_) { |
| 225 // If no GSB has been sent, it will be a non-synthetic GSB. | 206 // If no GSB has been sent, it will be a non-synthetic GSB. |
| 226 SendScrollBegin(scroll_update, false); | 207 SendScrollBegin(scroll_update, false); |
| 227 } else if (has_phase_info) { | 208 } else if (has_phase_info) { |
| 228 // If a GSB has been sent, generate a synthetic GSB if we have phase | 209 // 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 | 210 // information. This should be removed once crbug.com/526463 is |
| 230 // fully implemented. | 211 // fully implemented. |
| 231 SendScrollBegin(scroll_update, true); | 212 SendScrollBegin(scroll_update, true); |
| 232 } | 213 } |
| 233 | 214 |
| 234 if (needs_update) { | 215 if (needs_update) { |
| 235 ui::LatencyInfo latency = ui::LatencyInfo(ui::SourceEventType::WHEEL); | 216 ui::LatencyInfo latency = ui::LatencyInfo(ui::SourceEventType::WHEEL); |
| 236 latency.AddLatencyNumber( | 217 latency.AddLatencyNumber( |
| 237 ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, | 218 ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, |
| 238 0, 0); | 219 0, 0); |
| 239 client_->ForwardGestureEventWithLatencyInfo(scroll_update, latency); | 220 client_->ForwardGestureEventWithLatencyInfo(scroll_update, latency); |
| 240 } | 221 } |
| 241 | 222 |
| 242 if (current_phase_ended) { | 223 if (current_phase_ended) { |
| 243 // Non-synthetic GSEs are sent when the current phase is canceled or | 224 // Non-synthetic GSEs are sent when the current phase is canceled or |
| 244 // ended. | 225 // ended. |
| 245 SendScrollEnd(scroll_update, false); | 226 SendScrollEnd(scroll_update, false); |
| 246 } else if (has_phase_info) { | 227 } else if (has_phase_info) { |
| 247 // Generate a synthetic GSE for every update to force hit testing so | 228 // Generate a synthetic GSE for every update to force hit testing so |
| 248 // that the non-latching behavior is preserved. Remove once | 229 // that the non-latching behavior is preserved. Remove once |
| 249 // crbug.com/526463 is fully implemented. | 230 // crbug.com/526463 is fully implemented. |
| 250 SendScrollEnd(scroll_update, true); | 231 SendScrollEnd(scroll_update, true); |
| 251 } else if (!has_phase_info) { | 232 } else if (!has_phase_info) { |
| 252 DCHECK_EQ(0, scroll_transaction_ms_); | |
| 253 SendScrollEnd(scroll_update, false); | 233 SendScrollEnd(scroll_update, false); |
| 254 } | 234 } |
| 255 } | 235 } |
| 256 } | 236 } |
| 257 } | 237 } |
| 258 | 238 |
| 259 event_sent_for_gesture_ack_.reset(); | 239 event_sent_for_gesture_ack_.reset(); |
| 260 TryForwardNextEventToRenderer(); | 240 TryForwardNextEventToRenderer(); |
| 261 } | 241 } |
| 262 | 242 |
| 263 void MouseWheelEventQueue::OnGestureScrollEvent( | 243 void MouseWheelEventQueue::OnGestureScrollEvent( |
| 264 const GestureEventWithLatencyInfo& gesture_event) { | 244 const GestureEventWithLatencyInfo& gesture_event) { |
| 265 if (gesture_event.event.GetType() == | 245 if (gesture_event.event.GetType() == |
| 266 blink::WebInputEvent::kGestureScrollBegin) { | 246 blink::WebInputEvent::kGestureScrollBegin) { |
| 267 // If there is a current scroll going on and a new scroll that isn't | |
| 268 // wheel based cancel current one by sending a ScrollEnd. | |
| 269 if (scroll_end_timer_.IsRunning() && | |
| 270 gesture_event.event.source_device != blink::kWebGestureDeviceTouchpad) { | |
| 271 base::Closure task = scroll_end_timer_.user_task(); | |
| 272 scroll_end_timer_.Reset(); | |
| 273 task.Run(); | |
| 274 } | |
| 275 scrolling_device_ = gesture_event.event.source_device; | 247 scrolling_device_ = gesture_event.event.source_device; |
| 276 } else if (scrolling_device_ == gesture_event.event.source_device && | 248 } else if (scrolling_device_ == gesture_event.event.source_device && |
| 277 (gesture_event.event.GetType() == | 249 (gesture_event.event.GetType() == |
| 278 blink::WebInputEvent::kGestureScrollEnd || | 250 blink::WebInputEvent::kGestureScrollEnd || |
| 279 gesture_event.event.GetType() == | 251 gesture_event.event.GetType() == |
| 280 blink::WebInputEvent::kGestureFlingStart)) { | 252 blink::WebInputEvent::kGestureFlingStart)) { |
| 281 scrolling_device_ = blink::kWebGestureDeviceUninitialized; | 253 scrolling_device_ = blink::kWebGestureDeviceUninitialized; |
| 282 if (scroll_end_timer_.IsRunning()) { | 254 if (enable_scroll_latching_) { |
| 283 if (enable_scroll_latching_) { | 255 needs_scroll_begin_ = true; |
| 284 // Don't send the pending ScrollEnd if a fling is happening. | 256 needs_scroll_end_ = false; |
| 285 // The next wheel event will still need a ScrollBegin. | |
| 286 scroll_end_timer_.Stop(); | |
| 287 needs_scroll_begin_ = true; | |
| 288 needs_scroll_end_ = false; | |
| 289 } else { | |
| 290 scroll_end_timer_.Reset(); | |
| 291 } | |
| 292 } | 257 } |
| 293 } | 258 } |
| 294 } | 259 } |
| 295 | 260 |
| 296 void MouseWheelEventQueue::TryForwardNextEventToRenderer() { | 261 void MouseWheelEventQueue::TryForwardNextEventToRenderer() { |
| 297 TRACE_EVENT0("input", "MouseWheelEventQueue::TryForwardNextEventToRenderer"); | 262 TRACE_EVENT0("input", "MouseWheelEventQueue::TryForwardNextEventToRenderer"); |
| 298 | 263 |
| 299 if (wheel_queue_.empty() || event_sent_for_gesture_ack_) | 264 if (wheel_queue_.empty() || event_sent_for_gesture_ack_) |
| 300 return; | 265 return; |
| 301 | 266 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 316 scroll_end.resending_plugin_id = -1; | 281 scroll_end.resending_plugin_id = -1; |
| 317 scroll_end.data.scroll_end.synthetic = synthetic; | 282 scroll_end.data.scroll_end.synthetic = synthetic; |
| 318 scroll_end.data.scroll_end.inertial_phase = | 283 scroll_end.data.scroll_end.inertial_phase = |
| 319 update_event.data.scroll_update.inertial_phase; | 284 update_event.data.scroll_update.inertial_phase; |
| 320 scroll_end.data.scroll_end.delta_units = | 285 scroll_end.data.scroll_end.delta_units = |
| 321 update_event.data.scroll_update.delta_units; | 286 update_event.data.scroll_update.delta_units; |
| 322 | 287 |
| 323 if (!synthetic) { | 288 if (!synthetic) { |
| 324 needs_scroll_begin_ = true; | 289 needs_scroll_begin_ = true; |
| 325 needs_scroll_end_ = false; | 290 needs_scroll_end_ = false; |
| 326 | |
| 327 if (scroll_end_timer_.IsRunning()) | |
| 328 scroll_end_timer_.Reset(); | |
| 329 } | 291 } |
| 330 client_->ForwardGestureEventWithLatencyInfo( | 292 client_->ForwardGestureEventWithLatencyInfo( |
| 331 scroll_end, ui::LatencyInfo(ui::SourceEventType::WHEEL)); | 293 scroll_end, ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
| 332 } | 294 } |
| 333 | 295 |
| 334 void MouseWheelEventQueue::SendScrollBegin( | 296 void MouseWheelEventQueue::SendScrollBegin( |
| 335 const WebGestureEvent& gesture_update, | 297 const WebGestureEvent& gesture_update, |
| 336 bool synthetic) { | 298 bool synthetic) { |
| 337 DCHECK((synthetic && !needs_scroll_begin_) || needs_scroll_begin_); | 299 DCHECK((synthetic && !needs_scroll_begin_) || needs_scroll_begin_); |
| 338 | 300 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 349 scroll_begin.data.scroll_begin.delta_hint_units = | 311 scroll_begin.data.scroll_begin.delta_hint_units = |
| 350 gesture_update.data.scroll_update.delta_units; | 312 gesture_update.data.scroll_update.delta_units; |
| 351 | 313 |
| 352 needs_scroll_begin_ = false; | 314 needs_scroll_begin_ = false; |
| 353 needs_scroll_end_ = true; | 315 needs_scroll_end_ = true; |
| 354 client_->ForwardGestureEventWithLatencyInfo( | 316 client_->ForwardGestureEventWithLatencyInfo( |
| 355 scroll_begin, ui::LatencyInfo(ui::SourceEventType::WHEEL)); | 317 scroll_begin, ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
| 356 } | 318 } |
| 357 | 319 |
| 358 } // namespace content | 320 } // namespace content |
| OLD | NEW |