Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(510)

Side by Side Diff: content/browser/renderer_host/input/mouse_wheel_event_queue.cc

Issue 1847823005: Fix Event Latency Info on generate gesture events. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix DCHECKS failing Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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::WebGestureEvent;
11 using blink::WebInputEvent; 12 using blink::WebInputEvent;
12 using blink::WebMouseWheelEvent; 13 using blink::WebMouseWheelEvent;
13 using ui::LatencyInfo; 14 using ui::LatencyInfo;
14 15
15 namespace content { 16 namespace content {
16 17
17 // This class represents a single queued mouse wheel event. Its main use 18 // This class represents a single queued mouse wheel event. Its main use
18 // is that it is reported via trace events. 19 // is that it is reported via trace events.
19 class QueuedWebMouseWheelEvent : public MouseWheelEventWithLatencyInfo { 20 class QueuedWebMouseWheelEvent : public MouseWheelEventWithLatencyInfo {
20 public: 21 public:
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 return; 79 return;
79 80
80 event_sent_for_gesture_ack_->latency.AddNewLatencyFrom(latency_info); 81 event_sent_for_gesture_ack_->latency.AddNewLatencyFrom(latency_info);
81 client_->OnMouseWheelEventAck(*event_sent_for_gesture_ack_, ack_result); 82 client_->OnMouseWheelEventAck(*event_sent_for_gesture_ack_, ack_result);
82 83
83 // If event wasn't consumed then generate a gesture scroll for it. 84 // If event wasn't consumed then generate a gesture scroll for it.
84 if (send_gestures_ && ack_result != INPUT_EVENT_ACK_STATE_CONSUMED && 85 if (send_gestures_ && ack_result != INPUT_EVENT_ACK_STATE_CONSUMED &&
85 event_sent_for_gesture_ack_->event.canScroll && 86 event_sent_for_gesture_ack_->event.canScroll &&
86 (scrolling_device_ == blink::WebGestureDeviceUninitialized || 87 (scrolling_device_ == blink::WebGestureDeviceUninitialized ||
87 scrolling_device_ == blink::WebGestureDeviceTouchpad)) { 88 scrolling_device_ == blink::WebGestureDeviceTouchpad)) {
88 GestureEventWithLatencyInfo scroll_update; 89 WebGestureEvent scroll_update;
89 scroll_update.event.timeStampSeconds = 90 scroll_update.timeStampSeconds =
90 event_sent_for_gesture_ack_->event.timeStampSeconds; 91 event_sent_for_gesture_ack_->event.timeStampSeconds;
91 92
92 scroll_update.event.x = event_sent_for_gesture_ack_->event.x; 93 scroll_update.x = event_sent_for_gesture_ack_->event.x;
93 scroll_update.event.y = event_sent_for_gesture_ack_->event.y; 94 scroll_update.y = event_sent_for_gesture_ack_->event.y;
94 scroll_update.event.globalX = event_sent_for_gesture_ack_->event.globalX; 95 scroll_update.globalX = event_sent_for_gesture_ack_->event.globalX;
95 scroll_update.event.globalY = event_sent_for_gesture_ack_->event.globalY; 96 scroll_update.globalY = event_sent_for_gesture_ack_->event.globalY;
96 scroll_update.event.type = WebInputEvent::GestureScrollUpdate; 97 scroll_update.type = WebInputEvent::GestureScrollUpdate;
97 scroll_update.event.sourceDevice = blink::WebGestureDeviceTouchpad; 98 scroll_update.sourceDevice = blink::WebGestureDeviceTouchpad;
98 scroll_update.event.resendingPluginId = -1; 99 scroll_update.resendingPluginId = -1;
99 scroll_update.event.data.scrollUpdate.deltaX = 100 scroll_update.data.scrollUpdate.deltaX =
100 event_sent_for_gesture_ack_->event.deltaX; 101 event_sent_for_gesture_ack_->event.deltaX;
101 scroll_update.event.data.scrollUpdate.deltaY = 102 scroll_update.data.scrollUpdate.deltaY =
102 event_sent_for_gesture_ack_->event.deltaY; 103 event_sent_for_gesture_ack_->event.deltaY;
103 // Only OSX populates the momentumPhase; so expect this to 104 // Only OSX populates the momentumPhase; so expect this to
104 // always be PhaseNone on all other platforms. 105 // always be PhaseNone on all other platforms.
105 scroll_update.event.data.scrollUpdate.inertial = 106 scroll_update.data.scrollUpdate.inertial =
106 event_sent_for_gesture_ack_->event.momentumPhase != 107 event_sent_for_gesture_ack_->event.momentumPhase !=
107 blink::WebMouseWheelEvent::PhaseNone; 108 blink::WebMouseWheelEvent::PhaseNone;
108 if (event_sent_for_gesture_ack_->event.scrollByPage) { 109 if (event_sent_for_gesture_ack_->event.scrollByPage) {
109 scroll_update.event.data.scrollUpdate.deltaUnits = 110 scroll_update.data.scrollUpdate.deltaUnits = WebGestureEvent::Page;
110 blink::WebGestureEvent::Page;
111 111
112 // Turn page scrolls into a *single* page scroll because 112 // Turn page scrolls into a *single* page scroll because
113 // the magnitude the number of ticks is lost when coalescing. 113 // the magnitude the number of ticks is lost when coalescing.
114 if (scroll_update.event.data.scrollUpdate.deltaX) 114 if (scroll_update.data.scrollUpdate.deltaX)
115 scroll_update.event.data.scrollUpdate.deltaX = 115 scroll_update.data.scrollUpdate.deltaX =
116 scroll_update.event.data.scrollUpdate.deltaX > 0 ? 1 : -1; 116 scroll_update.data.scrollUpdate.deltaX > 0 ? 1 : -1;
117 if (scroll_update.event.data.scrollUpdate.deltaY) 117 if (scroll_update.data.scrollUpdate.deltaY)
118 scroll_update.event.data.scrollUpdate.deltaY = 118 scroll_update.data.scrollUpdate.deltaY =
119 scroll_update.event.data.scrollUpdate.deltaY > 0 ? 1 : -1; 119 scroll_update.data.scrollUpdate.deltaY > 0 ? 1 : -1;
120 } else { 120 } else {
121 scroll_update.event.data.scrollUpdate.deltaUnits = 121 scroll_update.data.scrollUpdate.deltaUnits =
122 event_sent_for_gesture_ack_->event.hasPreciseScrollingDeltas 122 event_sent_for_gesture_ack_->event.hasPreciseScrollingDeltas
123 ? blink::WebGestureEvent::PrecisePixels 123 ? WebGestureEvent::PrecisePixels
124 : blink::WebGestureEvent::Pixels; 124 : WebGestureEvent::Pixels;
125 125
126 if (event_sent_for_gesture_ack_->event.railsMode == 126 if (event_sent_for_gesture_ack_->event.railsMode ==
127 WebInputEvent::RailsModeVertical) 127 WebInputEvent::RailsModeVertical)
128 scroll_update.event.data.scrollUpdate.deltaX = 0; 128 scroll_update.data.scrollUpdate.deltaX = 0;
129 if (event_sent_for_gesture_ack_->event.railsMode == 129 if (event_sent_for_gesture_ack_->event.railsMode ==
130 WebInputEvent::RailsModeHorizontal) 130 WebInputEvent::RailsModeHorizontal)
131 scroll_update.event.data.scrollUpdate.deltaY = 0; 131 scroll_update.data.scrollUpdate.deltaY = 0;
132 } 132 }
133 133
134 bool current_phase_ended = false; 134 bool current_phase_ended = false;
135 bool has_phase_info = false; 135 bool has_phase_info = false;
136 136
137 if (event_sent_for_gesture_ack_->event.phase != 137 if (event_sent_for_gesture_ack_->event.phase !=
138 blink::WebMouseWheelEvent::PhaseNone || 138 blink::WebMouseWheelEvent::PhaseNone ||
139 event_sent_for_gesture_ack_->event.momentumPhase != 139 event_sent_for_gesture_ack_->event.momentumPhase !=
140 blink::WebMouseWheelEvent::PhaseNone) { 140 blink::WebMouseWheelEvent::PhaseNone) {
141 has_phase_info = true; 141 has_phase_info = true;
142 current_phase_ended = event_sent_for_gesture_ack_->event.phase == 142 current_phase_ended = event_sent_for_gesture_ack_->event.phase ==
143 blink::WebMouseWheelEvent::PhaseEnded || 143 blink::WebMouseWheelEvent::PhaseEnded ||
144 event_sent_for_gesture_ack_->event.phase == 144 event_sent_for_gesture_ack_->event.phase ==
145 blink::WebMouseWheelEvent::PhaseCancelled || 145 blink::WebMouseWheelEvent::PhaseCancelled ||
146 event_sent_for_gesture_ack_->event.momentumPhase == 146 event_sent_for_gesture_ack_->event.momentumPhase ==
147 blink::WebMouseWheelEvent::PhaseEnded || 147 blink::WebMouseWheelEvent::PhaseEnded ||
148 event_sent_for_gesture_ack_->event.momentumPhase == 148 event_sent_for_gesture_ack_->event.momentumPhase ==
149 blink::WebMouseWheelEvent::PhaseCancelled; 149 blink::WebMouseWheelEvent::PhaseCancelled;
150 } 150 }
151 151
152 bool needs_update = scroll_update.event.data.scrollUpdate.deltaX != 0 || 152 bool needs_update = scroll_update.data.scrollUpdate.deltaX != 0 ||
153 scroll_update.event.data.scrollUpdate.deltaY != 0; 153 scroll_update.data.scrollUpdate.deltaY != 0;
154 154
155 // If there is no update to send and the current phase is ended yet a GSB 155 // 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 156 // 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 157 // because the events generated will be a GSB (non-synthetic) and GSE
158 // (non-synthetic). This situation arises when OSX generates double 158 // (non-synthetic). This situation arises when OSX generates double
159 // phase end information. 159 // phase end information.
160 bool empty_sequence = 160 bool empty_sequence =
161 !needs_update && needs_scroll_begin_ && current_phase_ended; 161 !needs_update && needs_scroll_begin_ && current_phase_ended;
162 162
163 if (needs_update || !empty_sequence) { 163 if (needs_update || !empty_sequence) {
164 if (needs_scroll_begin_) { 164 if (needs_scroll_begin_) {
165 // If no GSB has been sent, it will be a non-synthetic GSB. 165 // If no GSB has been sent, it will be a non-synthetic GSB.
166 SendScrollBegin(scroll_update, false); 166 SendScrollBegin(scroll_update, false);
167 } else if (has_phase_info) { 167 } else if (has_phase_info) {
168 // If a GSB has been sent, generate a synthetic GSB if we have phase 168 // 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 169 // information. This should be removed once crbug.com/526463 is fully
170 // implemented. 170 // implemented.
171 SendScrollBegin(scroll_update, true); 171 SendScrollBegin(scroll_update, true);
172 } 172 }
173 173
174 if (needs_update) 174 if (needs_update)
175 client_->SendGestureEvent(scroll_update); 175 client_->ForwardGestureEvent(scroll_update);
176 176
177 if (current_phase_ended) { 177 if (current_phase_ended) {
178 // Non-synthetic GSEs are sent when the current phase is canceled or 178 // Non-synthetic GSEs are sent when the current phase is canceled or
179 // ended. 179 // ended.
180 SendScrollEnd(scroll_update.event, false); 180 SendScrollEnd(scroll_update, false);
181 } else if (has_phase_info) { 181 } else if (has_phase_info) {
182 // Generate a synthetic GSE for every update to force hit testing so 182 // Generate a synthetic GSE for every update to force hit testing so
183 // that the non-latching behavior is preserved. Remove once 183 // that the non-latching behavior is preserved. Remove once
184 // crbug.com/526463 is fully implemented. 184 // crbug.com/526463 is fully implemented.
185 SendScrollEnd(scroll_update.event, true); 185 SendScrollEnd(scroll_update, true);
186 } else { 186 } else {
187 scroll_end_timer_.Start( 187 scroll_end_timer_.Start(
188 FROM_HERE, 188 FROM_HERE,
189 base::TimeDelta::FromMilliseconds(scroll_transaction_ms_), 189 base::TimeDelta::FromMilliseconds(scroll_transaction_ms_),
190 base::Bind(&MouseWheelEventQueue::SendScrollEnd, 190 base::Bind(&MouseWheelEventQueue::SendScrollEnd,
191 base::Unretained(this), scroll_update.event, false)); 191 base::Unretained(this), scroll_update, false));
192 } 192 }
193 } 193 }
194 } 194 }
195 195
196 event_sent_for_gesture_ack_.reset(); 196 event_sent_for_gesture_ack_.reset();
197 TryForwardNextEventToRenderer(); 197 TryForwardNextEventToRenderer();
198 } 198 }
199 199
200 void MouseWheelEventQueue::OnGestureScrollEvent( 200 void MouseWheelEventQueue::OnGestureScrollEvent(
201 const GestureEventWithLatencyInfo& gesture_event) { 201 const GestureEventWithLatencyInfo& gesture_event) {
202 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { 202 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) {
203 // If there is a current scroll going on and a new scroll that isn't 203 // If there is a current scroll going on and a new scroll that isn't
204 // wheel based cancel current one by sending a ScrollEnd. 204 // wheel based cancel current one by sending a ScrollEnd.
205 if (scroll_end_timer_.IsRunning() && 205 if (scroll_end_timer_.IsRunning() &&
206 gesture_event.event.sourceDevice != blink::WebGestureDeviceTouchpad) { 206 gesture_event.event.sourceDevice != blink::WebGestureDeviceTouchpad) {
207 base::Closure task = scroll_end_timer_.user_task(); 207 base::Closure task = scroll_end_timer_.user_task();
208 scroll_end_timer_.Reset(); 208 scroll_end_timer_.Reset();
209 task.Run(); 209 task.Run();
210 } 210 }
211 scrolling_device_ = gesture_event.event.sourceDevice; 211 scrolling_device_ = gesture_event.event.sourceDevice;
212 } else if (scrolling_device_ == gesture_event.event.sourceDevice && 212 } else if (scrolling_device_ == gesture_event.event.sourceDevice &&
213 (gesture_event.event.type == 213 (gesture_event.event.type ==
214 blink::WebInputEvent::GestureScrollEnd || 214 blink::WebInputEvent::GestureScrollEnd ||
215 gesture_event.event.type == 215 gesture_event.event.type ==
216 blink::WebInputEvent::GestureFlingStart)) { 216 blink::WebInputEvent::GestureFlingStart)) {
217 scrolling_device_ = blink::WebGestureDeviceUninitialized; 217 scrolling_device_ = blink::WebGestureDeviceUninitialized;
218 if (scroll_end_timer_.IsRunning())
219 scroll_end_timer_.Reset();
dtapuska 2016/04/04 14:53:15 Although this typically wouldn't get hit. The one
218 } 220 }
219 } 221 }
220 222
221 void MouseWheelEventQueue::TryForwardNextEventToRenderer() { 223 void MouseWheelEventQueue::TryForwardNextEventToRenderer() {
222 TRACE_EVENT0("input", "MouseWheelEventQueue::TryForwardNextEventToRenderer"); 224 TRACE_EVENT0("input", "MouseWheelEventQueue::TryForwardNextEventToRenderer");
223 225
224 if (wheel_queue_.empty() || event_sent_for_gesture_ack_) 226 if (wheel_queue_.empty() || event_sent_for_gesture_ack_)
225 return; 227 return;
226 228
227 event_sent_for_gesture_ack_.reset(wheel_queue_.front()); 229 event_sent_for_gesture_ack_.reset(wheel_queue_.front());
228 wheel_queue_.pop_front(); 230 wheel_queue_.pop_front();
229 231
230 client_->SendMouseWheelEventImmediately(*event_sent_for_gesture_ack_); 232 client_->SendMouseWheelEventImmediately(*event_sent_for_gesture_ack_);
231 } 233 }
232 234
233 void MouseWheelEventQueue::SendScrollEnd(blink::WebGestureEvent update_event, 235 void MouseWheelEventQueue::SendScrollEnd(WebGestureEvent update_event,
234 bool synthetic) { 236 bool synthetic) {
235 DCHECK((synthetic && !needs_scroll_end_) || needs_scroll_end_); 237 DCHECK((synthetic && !needs_scroll_end_) || needs_scroll_end_);
236 238
237 GestureEventWithLatencyInfo scroll_end(update_event); 239 WebGestureEvent scroll_end(update_event);
238 scroll_end.event.timeStampSeconds = 240 scroll_end.timeStampSeconds =
239 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); 241 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
240 scroll_end.event.type = WebInputEvent::GestureScrollEnd; 242 scroll_end.type = WebInputEvent::GestureScrollEnd;
241 scroll_end.event.resendingPluginId = -1; 243 scroll_end.resendingPluginId = -1;
242 scroll_end.event.data.scrollEnd.synthetic = synthetic; 244 scroll_end.data.scrollEnd.synthetic = synthetic;
243 scroll_end.event.data.scrollEnd.inertial = 245 scroll_end.data.scrollEnd.inertial = update_event.data.scrollUpdate.inertial;
244 update_event.data.scrollUpdate.inertial; 246 scroll_end.data.scrollEnd.deltaUnits =
245 scroll_end.event.data.scrollEnd.deltaUnits =
246 update_event.data.scrollUpdate.deltaUnits; 247 update_event.data.scrollUpdate.deltaUnits;
247 248
248 if (!synthetic) { 249 if (!synthetic) {
249 needs_scroll_begin_ = true; 250 needs_scroll_begin_ = true;
250 needs_scroll_end_ = false; 251 needs_scroll_end_ = false;
251 252
252 if (scroll_end_timer_.IsRunning()) 253 if (scroll_end_timer_.IsRunning())
253 scroll_end_timer_.Reset(); 254 scroll_end_timer_.Reset();
254 } 255 }
255 client_->SendGestureEvent(scroll_end); 256 client_->ForwardGestureEvent(scroll_end);
256 } 257 }
257 258
258 void MouseWheelEventQueue::SendScrollBegin( 259 void MouseWheelEventQueue::SendScrollBegin(
259 const GestureEventWithLatencyInfo& gesture_update, 260 const WebGestureEvent& gesture_update,
260 bool synthetic) { 261 bool synthetic) {
261 DCHECK((synthetic && !needs_scroll_begin_) || needs_scroll_begin_); 262 DCHECK((synthetic && !needs_scroll_begin_) || needs_scroll_begin_);
262 263
263 GestureEventWithLatencyInfo scroll_begin(gesture_update); 264 WebGestureEvent scroll_begin(gesture_update);
264 scroll_begin.event.type = WebInputEvent::GestureScrollBegin; 265 scroll_begin.type = WebInputEvent::GestureScrollBegin;
265 scroll_begin.event.data.scrollBegin.synthetic = synthetic; 266 scroll_begin.data.scrollBegin.synthetic = synthetic;
266 scroll_begin.event.data.scrollBegin.inertial = 267 scroll_begin.data.scrollBegin.inertial =
267 gesture_update.event.data.scrollUpdate.inertial; 268 gesture_update.data.scrollUpdate.inertial;
268 scroll_begin.event.data.scrollBegin.deltaXHint = 269 scroll_begin.data.scrollBegin.deltaXHint =
269 gesture_update.event.data.scrollUpdate.deltaX; 270 gesture_update.data.scrollUpdate.deltaX;
270 scroll_begin.event.data.scrollBegin.deltaYHint = 271 scroll_begin.data.scrollBegin.deltaYHint =
271 gesture_update.event.data.scrollUpdate.deltaY; 272 gesture_update.data.scrollUpdate.deltaY;
272 scroll_begin.event.data.scrollBegin.targetViewport = false; 273 scroll_begin.data.scrollBegin.targetViewport = false;
273 scroll_begin.event.data.scrollBegin.deltaHintUnits = 274 scroll_begin.data.scrollBegin.deltaHintUnits =
274 gesture_update.event.data.scrollUpdate.deltaUnits; 275 gesture_update.data.scrollUpdate.deltaUnits;
275 276
276 needs_scroll_begin_ = false; 277 needs_scroll_begin_ = false;
277 needs_scroll_end_ = true; 278 needs_scroll_end_ = true;
278 client_->SendGestureEvent(scroll_begin); 279 client_->ForwardGestureEvent(scroll_begin);
279 } 280 }
280 281
281 } // namespace content 282 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698