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/metrics/histogram_macros.h" | 7 #include "base/metrics/histogram_macros.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/trace_event/trace_event.h" | 9 #include "base/trace_event/trace_event.h" |
| 10 | 10 |
| 11 using blink::WebInputEvent; | 11 using blink::WebInputEvent; |
| 12 using blink::WebMouseWheelEvent; | 12 using blink::WebMouseWheelEvent; |
| 13 using ui::LatencyInfo; | 13 using ui::LatencyInfo; |
|
tdresser
2016/04/01 19:28:56
Feel free to add WebGestureEvent here if you want.
dtapuska
2016/04/01 19:33:22
Done.
| |
| 14 | 14 |
| 15 namespace content { | 15 namespace content { |
| 16 | 16 |
| 17 // This class represents a single queued mouse wheel event. Its main use | 17 // This class represents a single queued mouse wheel event. Its main use |
| 18 // is that it is reported via trace events. | 18 // is that it is reported via trace events. |
| 19 class QueuedWebMouseWheelEvent : public MouseWheelEventWithLatencyInfo { | 19 class QueuedWebMouseWheelEvent : public MouseWheelEventWithLatencyInfo { |
| 20 public: | 20 public: |
| 21 QueuedWebMouseWheelEvent(const MouseWheelEventWithLatencyInfo& original_event) | 21 QueuedWebMouseWheelEvent(const MouseWheelEventWithLatencyInfo& original_event) |
| 22 : MouseWheelEventWithLatencyInfo(original_event) { | 22 : MouseWheelEventWithLatencyInfo(original_event) { |
| 23 TRACE_EVENT_ASYNC_BEGIN0("input", "MouseWheelEventQueue::QueueEvent", this); | 23 TRACE_EVENT_ASYNC_BEGIN0("input", "MouseWheelEventQueue::QueueEvent", this); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 return; | 78 return; |
| 79 | 79 |
| 80 event_sent_for_gesture_ack_->latency.AddNewLatencyFrom(latency_info); | 80 event_sent_for_gesture_ack_->latency.AddNewLatencyFrom(latency_info); |
| 81 client_->OnMouseWheelEventAck(*event_sent_for_gesture_ack_, ack_result); | 81 client_->OnMouseWheelEventAck(*event_sent_for_gesture_ack_, ack_result); |
| 82 | 82 |
| 83 // If event wasn't consumed then generate a gesture scroll for it. | 83 // If event wasn't consumed then generate a gesture scroll for it. |
| 84 if (send_gestures_ && ack_result != INPUT_EVENT_ACK_STATE_CONSUMED && | 84 if (send_gestures_ && ack_result != INPUT_EVENT_ACK_STATE_CONSUMED && |
| 85 event_sent_for_gesture_ack_->event.canScroll && | 85 event_sent_for_gesture_ack_->event.canScroll && |
| 86 (scrolling_device_ == blink::WebGestureDeviceUninitialized || | 86 (scrolling_device_ == blink::WebGestureDeviceUninitialized || |
| 87 scrolling_device_ == blink::WebGestureDeviceTouchpad)) { | 87 scrolling_device_ == blink::WebGestureDeviceTouchpad)) { |
| 88 GestureEventWithLatencyInfo scroll_update; | 88 blink::WebGestureEvent scroll_update; |
| 89 scroll_update.event.timeStampSeconds = | 89 scroll_update.timeStampSeconds = |
| 90 event_sent_for_gesture_ack_->event.timeStampSeconds; | 90 event_sent_for_gesture_ack_->event.timeStampSeconds; |
| 91 | 91 |
| 92 scroll_update.event.x = event_sent_for_gesture_ack_->event.x; | 92 scroll_update.x = event_sent_for_gesture_ack_->event.x; |
| 93 scroll_update.event.y = event_sent_for_gesture_ack_->event.y; | 93 scroll_update.y = event_sent_for_gesture_ack_->event.y; |
| 94 scroll_update.event.globalX = event_sent_for_gesture_ack_->event.globalX; | 94 scroll_update.globalX = event_sent_for_gesture_ack_->event.globalX; |
| 95 scroll_update.event.globalY = event_sent_for_gesture_ack_->event.globalY; | 95 scroll_update.globalY = event_sent_for_gesture_ack_->event.globalY; |
| 96 scroll_update.event.type = WebInputEvent::GestureScrollUpdate; | 96 scroll_update.type = WebInputEvent::GestureScrollUpdate; |
| 97 scroll_update.event.sourceDevice = blink::WebGestureDeviceTouchpad; | 97 scroll_update.sourceDevice = blink::WebGestureDeviceTouchpad; |
| 98 scroll_update.event.resendingPluginId = -1; | 98 scroll_update.resendingPluginId = -1; |
| 99 scroll_update.event.data.scrollUpdate.deltaX = | 99 scroll_update.data.scrollUpdate.deltaX = |
| 100 event_sent_for_gesture_ack_->event.deltaX; | 100 event_sent_for_gesture_ack_->event.deltaX; |
| 101 scroll_update.event.data.scrollUpdate.deltaY = | 101 scroll_update.data.scrollUpdate.deltaY = |
| 102 event_sent_for_gesture_ack_->event.deltaY; | 102 event_sent_for_gesture_ack_->event.deltaY; |
| 103 // Only OSX populates the momentumPhase; so expect this to | 103 // Only OSX populates the momentumPhase; so expect this to |
| 104 // always be PhaseNone on all other platforms. | 104 // always be PhaseNone on all other platforms. |
| 105 scroll_update.event.data.scrollUpdate.inertial = | 105 scroll_update.data.scrollUpdate.inertial = |
| 106 event_sent_for_gesture_ack_->event.momentumPhase != | 106 event_sent_for_gesture_ack_->event.momentumPhase != |
| 107 blink::WebMouseWheelEvent::PhaseNone; | 107 blink::WebMouseWheelEvent::PhaseNone; |
| 108 if (event_sent_for_gesture_ack_->event.scrollByPage) { | 108 if (event_sent_for_gesture_ack_->event.scrollByPage) { |
| 109 scroll_update.event.data.scrollUpdate.deltaUnits = | 109 scroll_update.data.scrollUpdate.deltaUnits = blink::WebGestureEvent::Page; |
| 110 blink::WebGestureEvent::Page; | |
| 111 | 110 |
| 112 // Turn page scrolls into a *single* page scroll because | 111 // Turn page scrolls into a *single* page scroll because |
| 113 // the magnitude the number of ticks is lost when coalescing. | 112 // the magnitude the number of ticks is lost when coalescing. |
| 114 if (scroll_update.event.data.scrollUpdate.deltaX) | 113 if (scroll_update.data.scrollUpdate.deltaX) |
| 115 scroll_update.event.data.scrollUpdate.deltaX = | 114 scroll_update.data.scrollUpdate.deltaX = |
| 116 scroll_update.event.data.scrollUpdate.deltaX > 0 ? 1 : -1; | 115 scroll_update.data.scrollUpdate.deltaX > 0 ? 1 : -1; |
| 117 if (scroll_update.event.data.scrollUpdate.deltaY) | 116 if (scroll_update.data.scrollUpdate.deltaY) |
| 118 scroll_update.event.data.scrollUpdate.deltaY = | 117 scroll_update.data.scrollUpdate.deltaY = |
| 119 scroll_update.event.data.scrollUpdate.deltaY > 0 ? 1 : -1; | 118 scroll_update.data.scrollUpdate.deltaY > 0 ? 1 : -1; |
| 120 } else { | 119 } else { |
| 121 scroll_update.event.data.scrollUpdate.deltaUnits = | 120 scroll_update.data.scrollUpdate.deltaUnits = |
| 122 event_sent_for_gesture_ack_->event.hasPreciseScrollingDeltas | 121 event_sent_for_gesture_ack_->event.hasPreciseScrollingDeltas |
| 123 ? blink::WebGestureEvent::PrecisePixels | 122 ? blink::WebGestureEvent::PrecisePixels |
| 124 : blink::WebGestureEvent::Pixels; | 123 : blink::WebGestureEvent::Pixels; |
| 125 | 124 |
| 126 if (event_sent_for_gesture_ack_->event.railsMode == | 125 if (event_sent_for_gesture_ack_->event.railsMode == |
| 127 WebInputEvent::RailsModeVertical) | 126 WebInputEvent::RailsModeVertical) |
| 128 scroll_update.event.data.scrollUpdate.deltaX = 0; | 127 scroll_update.data.scrollUpdate.deltaX = 0; |
| 129 if (event_sent_for_gesture_ack_->event.railsMode == | 128 if (event_sent_for_gesture_ack_->event.railsMode == |
| 130 WebInputEvent::RailsModeHorizontal) | 129 WebInputEvent::RailsModeHorizontal) |
| 131 scroll_update.event.data.scrollUpdate.deltaY = 0; | 130 scroll_update.data.scrollUpdate.deltaY = 0; |
| 132 } | 131 } |
| 133 | 132 |
| 134 bool current_phase_ended = false; | 133 bool current_phase_ended = false; |
| 135 bool has_phase_info = false; | 134 bool has_phase_info = false; |
| 136 | 135 |
| 137 if (event_sent_for_gesture_ack_->event.phase != | 136 if (event_sent_for_gesture_ack_->event.phase != |
| 138 blink::WebMouseWheelEvent::PhaseNone || | 137 blink::WebMouseWheelEvent::PhaseNone || |
| 139 event_sent_for_gesture_ack_->event.momentumPhase != | 138 event_sent_for_gesture_ack_->event.momentumPhase != |
| 140 blink::WebMouseWheelEvent::PhaseNone) { | 139 blink::WebMouseWheelEvent::PhaseNone) { |
| 141 has_phase_info = true; | 140 has_phase_info = true; |
| 142 current_phase_ended = event_sent_for_gesture_ack_->event.phase == | 141 current_phase_ended = event_sent_for_gesture_ack_->event.phase == |
| 143 blink::WebMouseWheelEvent::PhaseEnded || | 142 blink::WebMouseWheelEvent::PhaseEnded || |
| 144 event_sent_for_gesture_ack_->event.phase == | 143 event_sent_for_gesture_ack_->event.phase == |
| 145 blink::WebMouseWheelEvent::PhaseCancelled || | 144 blink::WebMouseWheelEvent::PhaseCancelled || |
| 146 event_sent_for_gesture_ack_->event.momentumPhase == | 145 event_sent_for_gesture_ack_->event.momentumPhase == |
| 147 blink::WebMouseWheelEvent::PhaseEnded || | 146 blink::WebMouseWheelEvent::PhaseEnded || |
| 148 event_sent_for_gesture_ack_->event.momentumPhase == | 147 event_sent_for_gesture_ack_->event.momentumPhase == |
| 149 blink::WebMouseWheelEvent::PhaseCancelled; | 148 blink::WebMouseWheelEvent::PhaseCancelled; |
| 150 } | 149 } |
| 151 | 150 |
| 152 bool needs_update = scroll_update.event.data.scrollUpdate.deltaX != 0 || | 151 bool needs_update = scroll_update.data.scrollUpdate.deltaX != 0 || |
| 153 scroll_update.event.data.scrollUpdate.deltaY != 0; | 152 scroll_update.data.scrollUpdate.deltaY != 0; |
| 154 | 153 |
| 155 // If there is no update to send and the current phase is ended yet a GSB | 154 // If there is no update to send and the current phase is ended yet a GSB |
| 156 // needs to be sent, this event sequence doesn't need to be generated | 155 // needs to be sent, this event sequence doesn't need to be generated |
| 157 // because the events generated will be a GSB (non-synthetic) and GSE | 156 // because the events generated will be a GSB (non-synthetic) and GSE |
| 158 // (non-synthetic). This situation arises when OSX generates double | 157 // (non-synthetic). This situation arises when OSX generates double |
| 159 // phase end information. | 158 // phase end information. |
| 160 bool empty_sequence = | 159 bool empty_sequence = |
| 161 !needs_update && needs_scroll_begin_ && current_phase_ended; | 160 !needs_update && needs_scroll_begin_ && current_phase_ended; |
| 162 | 161 |
| 163 if (needs_update || !empty_sequence) { | 162 if (needs_update || !empty_sequence) { |
| 164 if (needs_scroll_begin_) { | 163 if (needs_scroll_begin_) { |
| 165 // If no GSB has been sent, it will be a non-synthetic GSB. | 164 // If no GSB has been sent, it will be a non-synthetic GSB. |
| 166 SendScrollBegin(scroll_update, false); | 165 SendScrollBegin(scroll_update, false); |
| 167 } else if (has_phase_info) { | 166 } else if (has_phase_info) { |
| 168 // If a GSB has been sent, generate a synthetic GSB if we have phase | 167 // If a GSB has been sent, generate a synthetic GSB if we have phase |
| 169 // information. This should be removed once crbug.com/526463 is fully | 168 // information. This should be removed once crbug.com/526463 is fully |
| 170 // implemented. | 169 // implemented. |
| 171 SendScrollBegin(scroll_update, true); | 170 SendScrollBegin(scroll_update, true); |
| 172 } | 171 } |
| 173 | 172 |
| 174 if (needs_update) | 173 if (needs_update) |
| 175 client_->SendGestureEvent(scroll_update); | 174 client_->ForwardGestureEvent(scroll_update); |
| 176 | 175 |
| 177 if (current_phase_ended) { | 176 if (current_phase_ended) { |
| 178 // Non-synthetic GSEs are sent when the current phase is canceled or | 177 // Non-synthetic GSEs are sent when the current phase is canceled or |
| 179 // ended. | 178 // ended. |
| 180 SendScrollEnd(scroll_update.event, false); | 179 SendScrollEnd(scroll_update, false); |
| 181 } else if (has_phase_info) { | 180 } else if (has_phase_info) { |
| 182 // Generate a synthetic GSE for every update to force hit testing so | 181 // Generate a synthetic GSE for every update to force hit testing so |
| 183 // that the non-latching behavior is preserved. Remove once | 182 // that the non-latching behavior is preserved. Remove once |
| 184 // crbug.com/526463 is fully implemented. | 183 // crbug.com/526463 is fully implemented. |
| 185 SendScrollEnd(scroll_update.event, true); | 184 SendScrollEnd(scroll_update, true); |
| 186 } else { | 185 } else { |
| 187 scroll_end_timer_.Start( | 186 scroll_end_timer_.Start( |
| 188 FROM_HERE, | 187 FROM_HERE, |
| 189 base::TimeDelta::FromMilliseconds(scroll_transaction_ms_), | 188 base::TimeDelta::FromMilliseconds(scroll_transaction_ms_), |
| 190 base::Bind(&MouseWheelEventQueue::SendScrollEnd, | 189 base::Bind(&MouseWheelEventQueue::SendScrollEnd, |
| 191 base::Unretained(this), scroll_update.event, false)); | 190 base::Unretained(this), scroll_update, false)); |
| 192 } | 191 } |
| 193 } | 192 } |
| 194 } | 193 } |
| 195 | 194 |
| 196 event_sent_for_gesture_ack_.reset(); | 195 event_sent_for_gesture_ack_.reset(); |
| 197 TryForwardNextEventToRenderer(); | 196 TryForwardNextEventToRenderer(); |
| 198 } | 197 } |
| 199 | 198 |
| 200 void MouseWheelEventQueue::OnGestureScrollEvent( | 199 void MouseWheelEventQueue::OnGestureScrollEvent( |
| 201 const GestureEventWithLatencyInfo& gesture_event) { | 200 const GestureEventWithLatencyInfo& gesture_event) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 227 event_sent_for_gesture_ack_.reset(wheel_queue_.front()); | 226 event_sent_for_gesture_ack_.reset(wheel_queue_.front()); |
| 228 wheel_queue_.pop_front(); | 227 wheel_queue_.pop_front(); |
| 229 | 228 |
| 230 client_->SendMouseWheelEventImmediately(*event_sent_for_gesture_ack_); | 229 client_->SendMouseWheelEventImmediately(*event_sent_for_gesture_ack_); |
| 231 } | 230 } |
| 232 | 231 |
| 233 void MouseWheelEventQueue::SendScrollEnd(blink::WebGestureEvent update_event, | 232 void MouseWheelEventQueue::SendScrollEnd(blink::WebGestureEvent update_event, |
| 234 bool synthetic) { | 233 bool synthetic) { |
| 235 DCHECK((synthetic && !needs_scroll_end_) || needs_scroll_end_); | 234 DCHECK((synthetic && !needs_scroll_end_) || needs_scroll_end_); |
| 236 | 235 |
| 237 GestureEventWithLatencyInfo scroll_end(update_event); | 236 blink::WebGestureEvent scroll_end(update_event); |
| 238 scroll_end.event.timeStampSeconds = | 237 scroll_end.timeStampSeconds = |
| 239 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); | 238 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); |
| 240 scroll_end.event.type = WebInputEvent::GestureScrollEnd; | 239 scroll_end.type = WebInputEvent::GestureScrollEnd; |
| 241 scroll_end.event.resendingPluginId = -1; | 240 scroll_end.resendingPluginId = -1; |
| 242 scroll_end.event.data.scrollEnd.synthetic = synthetic; | 241 scroll_end.data.scrollEnd.synthetic = synthetic; |
| 243 scroll_end.event.data.scrollEnd.inertial = | 242 scroll_end.data.scrollEnd.inertial = update_event.data.scrollUpdate.inertial; |
| 244 update_event.data.scrollUpdate.inertial; | 243 scroll_end.data.scrollEnd.deltaUnits = |
| 245 scroll_end.event.data.scrollEnd.deltaUnits = | |
| 246 update_event.data.scrollUpdate.deltaUnits; | 244 update_event.data.scrollUpdate.deltaUnits; |
| 247 | 245 |
| 248 if (!synthetic) { | 246 if (!synthetic) { |
| 249 needs_scroll_begin_ = true; | 247 needs_scroll_begin_ = true; |
| 250 needs_scroll_end_ = false; | 248 needs_scroll_end_ = false; |
| 251 | 249 |
| 252 if (scroll_end_timer_.IsRunning()) | 250 if (scroll_end_timer_.IsRunning()) |
| 253 scroll_end_timer_.Reset(); | 251 scroll_end_timer_.Reset(); |
| 254 } | 252 } |
| 255 client_->SendGestureEvent(scroll_end); | 253 client_->ForwardGestureEvent(scroll_end); |
| 256 } | 254 } |
| 257 | 255 |
| 258 void MouseWheelEventQueue::SendScrollBegin( | 256 void MouseWheelEventQueue::SendScrollBegin( |
| 259 const GestureEventWithLatencyInfo& gesture_update, | 257 const blink::WebGestureEvent& gesture_update, |
| 260 bool synthetic) { | 258 bool synthetic) { |
| 261 DCHECK((synthetic && !needs_scroll_begin_) || needs_scroll_begin_); | 259 DCHECK((synthetic && !needs_scroll_begin_) || needs_scroll_begin_); |
| 262 | 260 |
| 263 GestureEventWithLatencyInfo scroll_begin(gesture_update); | 261 blink::WebGestureEvent scroll_begin(gesture_update); |
| 264 scroll_begin.event.type = WebInputEvent::GestureScrollBegin; | 262 scroll_begin.type = WebInputEvent::GestureScrollBegin; |
| 265 scroll_begin.event.data.scrollBegin.synthetic = synthetic; | 263 scroll_begin.data.scrollBegin.synthetic = synthetic; |
| 266 scroll_begin.event.data.scrollBegin.inertial = | 264 scroll_begin.data.scrollBegin.inertial = |
| 267 gesture_update.event.data.scrollUpdate.inertial; | 265 gesture_update.data.scrollUpdate.inertial; |
| 268 scroll_begin.event.data.scrollBegin.deltaXHint = | 266 scroll_begin.data.scrollBegin.deltaXHint = |
| 269 gesture_update.event.data.scrollUpdate.deltaX; | 267 gesture_update.data.scrollUpdate.deltaX; |
| 270 scroll_begin.event.data.scrollBegin.deltaYHint = | 268 scroll_begin.data.scrollBegin.deltaYHint = |
| 271 gesture_update.event.data.scrollUpdate.deltaY; | 269 gesture_update.data.scrollUpdate.deltaY; |
| 272 scroll_begin.event.data.scrollBegin.targetViewport = false; | 270 scroll_begin.data.scrollBegin.targetViewport = false; |
| 273 scroll_begin.event.data.scrollBegin.deltaHintUnits = | 271 scroll_begin.data.scrollBegin.deltaHintUnits = |
| 274 gesture_update.event.data.scrollUpdate.deltaUnits; | 272 gesture_update.data.scrollUpdate.deltaUnits; |
| 275 | 273 |
| 276 needs_scroll_begin_ = false; | 274 needs_scroll_begin_ = false; |
| 277 needs_scroll_end_ = true; | 275 needs_scroll_end_ = true; |
| 278 client_->SendGestureEvent(scroll_begin); | 276 client_->ForwardGestureEvent(scroll_begin); |
| 279 } | 277 } |
| 280 | 278 |
| 281 } // namespace content | 279 } // namespace content |
| OLD | NEW |