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 |
(...skipping 19 matching lines...) Expand all Loading... | |
30 private: | 30 private: |
31 bool original_can_scroll_; | 31 bool original_can_scroll_; |
32 DISALLOW_COPY_AND_ASSIGN(QueuedWebMouseWheelEvent); | 32 DISALLOW_COPY_AND_ASSIGN(QueuedWebMouseWheelEvent); |
33 }; | 33 }; |
34 | 34 |
35 MouseWheelEventQueue::MouseWheelEventQueue(MouseWheelEventQueueClient* client, | 35 MouseWheelEventQueue::MouseWheelEventQueue(MouseWheelEventQueueClient* client, |
36 bool send_gestures, | 36 bool send_gestures, |
37 int64_t scroll_transaction_ms) | 37 int64_t scroll_transaction_ms) |
38 : client_(client), | 38 : client_(client), |
39 needs_scroll_begin_(true), | 39 needs_scroll_begin_(true), |
40 needs_scroll_end_(false), | |
40 send_gestures_(send_gestures), | 41 send_gestures_(send_gestures), |
41 scroll_transaction_ms_(scroll_transaction_ms), | 42 scroll_transaction_ms_(scroll_transaction_ms), |
42 scrolling_device_(blink::WebGestureDeviceUninitialized) { | 43 scrolling_device_(blink::WebGestureDeviceUninitialized) { |
43 DCHECK(client); | 44 DCHECK(client); |
44 } | 45 } |
45 | 46 |
46 MouseWheelEventQueue::~MouseWheelEventQueue() { | 47 MouseWheelEventQueue::~MouseWheelEventQueue() { |
47 if (!wheel_queue_.empty()) | 48 if (!wheel_queue_.empty()) |
48 STLDeleteElements(&wheel_queue_); | 49 STLDeleteElements(&wheel_queue_); |
49 } | 50 } |
(...skipping 28 matching lines...) Expand all Loading... | |
78 | 79 |
79 event_sent_for_gesture_ack_->latency.AddNewLatencyFrom(latency_info); | 80 event_sent_for_gesture_ack_->latency.AddNewLatencyFrom(latency_info); |
80 client_->OnMouseWheelEventAck(*event_sent_for_gesture_ack_, ack_result); | 81 client_->OnMouseWheelEventAck(*event_sent_for_gesture_ack_, ack_result); |
81 | 82 |
82 // 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. |
83 if (send_gestures_ && ack_result != INPUT_EVENT_ACK_STATE_CONSUMED && | 84 if (send_gestures_ && ack_result != INPUT_EVENT_ACK_STATE_CONSUMED && |
84 event_sent_for_gesture_ack_->event.canScroll && | 85 event_sent_for_gesture_ack_->event.canScroll && |
85 (scrolling_device_ == blink::WebGestureDeviceUninitialized || | 86 (scrolling_device_ == blink::WebGestureDeviceUninitialized || |
86 scrolling_device_ == blink::WebGestureDeviceTouchpad)) { | 87 scrolling_device_ == blink::WebGestureDeviceTouchpad)) { |
87 GestureEventWithLatencyInfo scroll_update; | 88 GestureEventWithLatencyInfo scroll_update; |
89 scroll_update.event.timeStampSeconds = | |
90 event_sent_for_gesture_ack_->event.timeStampSeconds; | |
91 | |
88 scroll_update.event.x = event_sent_for_gesture_ack_->event.x; | 92 scroll_update.event.x = event_sent_for_gesture_ack_->event.x; |
89 scroll_update.event.y = event_sent_for_gesture_ack_->event.y; | 93 scroll_update.event.y = event_sent_for_gesture_ack_->event.y; |
90 scroll_update.event.globalX = event_sent_for_gesture_ack_->event.globalX; | 94 scroll_update.event.globalX = event_sent_for_gesture_ack_->event.globalX; |
91 scroll_update.event.globalY = event_sent_for_gesture_ack_->event.globalY; | 95 scroll_update.event.globalY = event_sent_for_gesture_ack_->event.globalY; |
92 scroll_update.event.type = WebInputEvent::GestureScrollUpdate; | 96 scroll_update.event.type = WebInputEvent::GestureScrollUpdate; |
93 scroll_update.event.sourceDevice = blink::WebGestureDeviceTouchpad; | 97 scroll_update.event.sourceDevice = blink::WebGestureDeviceTouchpad; |
94 scroll_update.event.resendingPluginId = -1; | 98 scroll_update.event.resendingPluginId = -1; |
95 scroll_update.event.data.scrollUpdate.deltaX = | 99 scroll_update.event.data.scrollUpdate.deltaX = |
96 event_sent_for_gesture_ack_->event.deltaX; | 100 event_sent_for_gesture_ack_->event.deltaX; |
97 scroll_update.event.data.scrollUpdate.deltaY = | 101 scroll_update.event.data.scrollUpdate.deltaY = |
98 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 | |
104 // always be PhaseNone on all other platforms. | |
105 scroll_update.event.data.scrollUpdate.inertial = | |
106 event_sent_for_gesture_ack_->event.momentumPhase != | |
107 blink::WebMouseWheelEvent::PhaseNone; | |
99 if (event_sent_for_gesture_ack_->event.scrollByPage) { | 108 if (event_sent_for_gesture_ack_->event.scrollByPage) { |
100 scroll_update.event.data.scrollUpdate.deltaUnits = | 109 scroll_update.event.data.scrollUpdate.deltaUnits = |
101 blink::WebGestureEvent::Page; | 110 blink::WebGestureEvent::Page; |
102 | 111 |
103 // Turn page scrolls into a *single* page scroll because | 112 // Turn page scrolls into a *single* page scroll because |
104 // the magnitude the number of ticks is lost when coalescing. | 113 // the magnitude the number of ticks is lost when coalescing. |
105 if (scroll_update.event.data.scrollUpdate.deltaX) | 114 if (scroll_update.event.data.scrollUpdate.deltaX) |
106 scroll_update.event.data.scrollUpdate.deltaX = | 115 scroll_update.event.data.scrollUpdate.deltaX = |
107 scroll_update.event.data.scrollUpdate.deltaX > 0 ? 1 : -1; | 116 scroll_update.event.data.scrollUpdate.deltaX > 0 ? 1 : -1; |
108 if (scroll_update.event.data.scrollUpdate.deltaY) | 117 if (scroll_update.event.data.scrollUpdate.deltaY) |
109 scroll_update.event.data.scrollUpdate.deltaY = | 118 scroll_update.event.data.scrollUpdate.deltaY = |
110 scroll_update.event.data.scrollUpdate.deltaY > 0 ? 1 : -1; | 119 scroll_update.event.data.scrollUpdate.deltaY > 0 ? 1 : -1; |
111 } else { | 120 } else { |
112 scroll_update.event.data.scrollUpdate.deltaUnits = | 121 scroll_update.event.data.scrollUpdate.deltaUnits = |
113 event_sent_for_gesture_ack_->event.hasPreciseScrollingDeltas | 122 event_sent_for_gesture_ack_->event.hasPreciseScrollingDeltas |
114 ? blink::WebGestureEvent::PrecisePixels | 123 ? blink::WebGestureEvent::PrecisePixels |
115 : blink::WebGestureEvent::Pixels; | 124 : blink::WebGestureEvent::Pixels; |
116 } | 125 } |
117 SendGesture(scroll_update); | 126 |
127 bool current_phase_ended = false; | |
128 bool has_phase_info = false; | |
129 | |
130 if (event_sent_for_gesture_ack_->event.phase != | |
131 blink::WebMouseWheelEvent::PhaseNone || | |
132 event_sent_for_gesture_ack_->event.momentumPhase != | |
133 blink::WebMouseWheelEvent::PhaseNone) { | |
134 has_phase_info = true; | |
135 current_phase_ended = event_sent_for_gesture_ack_->event.phase == | |
136 blink::WebMouseWheelEvent::PhaseEnded || | |
137 event_sent_for_gesture_ack_->event.phase == | |
138 blink::WebMouseWheelEvent::PhaseCancelled || | |
139 event_sent_for_gesture_ack_->event.momentumPhase == | |
140 blink::WebMouseWheelEvent::PhaseEnded || | |
141 event_sent_for_gesture_ack_->event.momentumPhase == | |
142 blink::WebMouseWheelEvent::PhaseCancelled; | |
143 } | |
144 | |
145 bool needs_update = scroll_update.event.data.scrollUpdate.deltaX != 0 || | |
146 scroll_update.event.data.scrollUpdate.deltaY != 0; | |
147 | |
148 // If there is no update to send and the current phase is ended yet a GSB | |
149 // needs to be sent; this event sequence doesn't need to be generated | |
150 // because the events generated will be a GSB (non-sythetic) and GSE | |
tdresser
2016/03/09 14:30:05
sythetic -> synthetic
dtapuska
2016/03/09 16:12:29
Done.
| |
151 // (non-sythetic). This situation arrises when OSX generates double | |
152 // phase end information. | |
153 bool empty_sequence = | |
154 !needs_update && needs_scroll_begin_ && current_phase_ended; | |
155 | |
156 if (needs_update || !empty_sequence) { | |
157 if (needs_scroll_begin_) { | |
158 // If no GSB has been sent; it will be a non-syntehtic GSB. | |
tdresser
2016/03/09 14:30:05
syntehtic -> synthetic
dtapuska
2016/03/09 16:12:29
Done.
| |
159 SendScrollBegin(scroll_update, false); | |
160 } else if (has_phase_info) { | |
161 // If a GSB has been sent; generate a synthetic GSB if we have phase | |
162 // information. This should be removed once crbug.com/526463 is fully | |
163 // implemented. | |
164 SendScrollBegin(scroll_update, true); | |
165 } | |
166 | |
167 if (needs_update) | |
168 client_->SendGestureEvent(scroll_update); | |
169 | |
170 if (current_phase_ended) { | |
171 // Non-synthetic GSEs are sent when the current phase is canceled or | |
172 // ended. | |
173 SendScrollEnd(scroll_update.event, false); | |
174 } else if (has_phase_info) { | |
175 // Generate a synthetic GSE for every update to force hit testing so | |
tdresser
2016/03/09 14:30:05
Line wrapping is weird here. Also, the synthetic G
dtapuska
2016/03/09 16:12:29
Sorry; using xcode and git cl format caused the we
| |
176 // that | |
177 // the non-latching behavior is preserved. Remove once crbug.com/526463 | |
178 // is fully implemented. | |
179 SendScrollEnd(scroll_update.event, true); | |
180 } else { | |
181 scroll_end_timer_.Start( | |
182 FROM_HERE, | |
183 base::TimeDelta::FromMilliseconds(scroll_transaction_ms_), | |
184 base::Bind(&MouseWheelEventQueue::SendScrollEnd, | |
185 base::Unretained(this), scroll_update.event, false)); | |
186 } | |
187 } | |
118 } | 188 } |
119 | 189 |
120 event_sent_for_gesture_ack_.reset(); | 190 event_sent_for_gesture_ack_.reset(); |
121 TryForwardNextEventToRenderer(); | 191 TryForwardNextEventToRenderer(); |
122 } | 192 } |
123 | 193 |
124 void MouseWheelEventQueue::OnGestureScrollEvent( | 194 void MouseWheelEventQueue::OnGestureScrollEvent( |
125 const GestureEventWithLatencyInfo& gesture_event) { | 195 const GestureEventWithLatencyInfo& gesture_event) { |
126 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { | 196 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { |
127 // If there is a current scroll going on and a new scroll that isn't | 197 // If there is a current scroll going on and a new scroll that isn't |
(...skipping 23 matching lines...) Expand all Loading... | |
151 event_sent_for_gesture_ack_.reset(wheel_queue_.front()); | 221 event_sent_for_gesture_ack_.reset(wheel_queue_.front()); |
152 wheel_queue_.pop_front(); | 222 wheel_queue_.pop_front(); |
153 | 223 |
154 MouseWheelEventWithLatencyInfo send_event(*event_sent_for_gesture_ack_); | 224 MouseWheelEventWithLatencyInfo send_event(*event_sent_for_gesture_ack_); |
155 if (send_gestures_) | 225 if (send_gestures_) |
156 send_event.event.canScroll = false; | 226 send_event.event.canScroll = false; |
157 | 227 |
158 client_->SendMouseWheelEventImmediately(send_event); | 228 client_->SendMouseWheelEventImmediately(send_event); |
159 } | 229 } |
160 | 230 |
161 void MouseWheelEventQueue::SendScrollEnd(blink::WebGestureEvent update_event) { | 231 void MouseWheelEventQueue::SendScrollEnd(blink::WebGestureEvent update_event, |
162 GestureEventWithLatencyInfo scroll_end; | 232 bool synthetic) { |
233 DCHECK((synthetic && !needs_scroll_end_) || needs_scroll_end_); | |
234 | |
235 GestureEventWithLatencyInfo scroll_end(update_event); | |
236 scroll_end.event.timeStampSeconds = | |
237 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); | |
163 scroll_end.event.type = WebInputEvent::GestureScrollEnd; | 238 scroll_end.event.type = WebInputEvent::GestureScrollEnd; |
164 scroll_end.event.sourceDevice = blink::WebGestureDeviceTouchpad; | |
165 scroll_end.event.resendingPluginId = -1; | 239 scroll_end.event.resendingPluginId = -1; |
240 scroll_end.event.data.scrollEnd.synthetic = synthetic; | |
241 scroll_end.event.data.scrollEnd.inertial = | |
242 update_event.data.scrollUpdate.inertial; | |
166 scroll_end.event.data.scrollEnd.deltaUnits = | 243 scroll_end.event.data.scrollEnd.deltaUnits = |
167 update_event.data.scrollUpdate.deltaUnits; | 244 update_event.data.scrollUpdate.deltaUnits; |
168 scroll_end.event.x = update_event.x; | |
169 scroll_end.event.y = update_event.y; | |
170 scroll_end.event.globalX = update_event.globalX; | |
171 scroll_end.event.globalY = update_event.globalY; | |
172 | 245 |
173 SendGesture(scroll_end); | 246 if (!synthetic) { |
247 needs_scroll_begin_ = true; | |
248 needs_scroll_end_ = false; | |
249 | |
250 if (scroll_end_timer_.IsRunning()) | |
251 scroll_end_timer_.Reset(); | |
252 } | |
253 client_->SendGestureEvent(scroll_end); | |
174 } | 254 } |
175 | 255 |
176 void MouseWheelEventQueue::SendGesture( | 256 void MouseWheelEventQueue::SendScrollBegin( |
177 const GestureEventWithLatencyInfo& gesture) { | 257 const GestureEventWithLatencyInfo& gesture_update, |
178 switch (gesture.event.type) { | 258 bool synthetic) { |
179 case WebInputEvent::GestureScrollUpdate: | 259 DCHECK((synthetic && !needs_scroll_begin_) || needs_scroll_begin_); |
180 if (needs_scroll_begin_) { | |
181 GestureEventWithLatencyInfo scroll_begin(gesture); | |
182 scroll_begin.event.x = gesture.event.x; | |
183 scroll_begin.event.y = gesture.event.y; | |
184 scroll_begin.event.globalX = gesture.event.globalX; | |
185 scroll_begin.event.globalY = gesture.event.globalY; | |
186 scroll_begin.event.type = WebInputEvent::GestureScrollBegin; | |
187 scroll_begin.event.data.scrollBegin.deltaXHint = | |
188 gesture.event.data.scrollUpdate.deltaX; | |
189 scroll_begin.event.data.scrollBegin.deltaYHint = | |
190 gesture.event.data.scrollUpdate.deltaY; | |
191 scroll_begin.event.data.scrollBegin.targetViewport = false; | |
192 scroll_begin.event.data.scrollBegin.deltaHintUnits = | |
193 gesture.event.data.scrollUpdate.deltaUnits; | |
194 | 260 |
195 SendGesture(scroll_begin); | 261 GestureEventWithLatencyInfo scroll_begin(gesture_update); |
196 } | 262 scroll_begin.event.type = WebInputEvent::GestureScrollBegin; |
197 if (scroll_end_timer_.IsRunning()) { | 263 scroll_begin.event.data.scrollBegin.synthetic = synthetic; |
198 scroll_end_timer_.Reset(); | 264 scroll_begin.event.data.scrollBegin.inertial = |
199 } else { | 265 gesture_update.event.data.scrollUpdate.inertial; |
200 scroll_end_timer_.Start( | 266 scroll_begin.event.data.scrollBegin.deltaXHint = |
201 FROM_HERE, | 267 gesture_update.event.data.scrollUpdate.deltaX; |
202 base::TimeDelta::FromMilliseconds(scroll_transaction_ms_), | 268 scroll_begin.event.data.scrollBegin.deltaYHint = |
203 base::Bind(&MouseWheelEventQueue::SendScrollEnd, | 269 gesture_update.event.data.scrollUpdate.deltaY; |
204 base::Unretained(this), gesture.event)); | 270 scroll_begin.event.data.scrollBegin.targetViewport = false; |
205 } | 271 scroll_begin.event.data.scrollBegin.deltaHintUnits = |
206 break; | 272 gesture_update.event.data.scrollUpdate.deltaUnits; |
207 case WebInputEvent::GestureScrollEnd: | 273 |
208 needs_scroll_begin_ = true; | 274 needs_scroll_begin_ = false; |
209 break; | 275 needs_scroll_end_ = true; |
210 case WebInputEvent::GestureScrollBegin: | 276 client_->SendGestureEvent(scroll_begin); |
211 needs_scroll_begin_ = false; | |
212 break; | |
213 default: | |
214 return; | |
215 } | |
216 client_->SendGestureEvent(gesture); | |
217 } | 277 } |
218 | 278 |
219 } // namespace content | 279 } // namespace content |
OLD | NEW |