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

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

Issue 1749343004: Implement Wheel Gesture Scrolling on OSX. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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
(...skipping 19 matching lines...) Expand all
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
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 send_end_now = 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 send_end_now = event_sent_for_gesture_ack_->event.phase ==
tdresser 2016/03/08 14:28:52 Add a comment describing the conditions in which w
dtapuska 2016/03/08 20:31:49 I'm hoping the renaming of the variable makes it c
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 (needs_update || !(needs_scroll_begin_ && send_end_now)) {
tdresser 2016/03/08 14:28:52 I'm a bit confused by this condition. It's probab
dtapuska 2016/03/08 20:31:49 Done.
149 if (needs_scroll_begin_ || has_phase_info)
150 SendScrollBegin(scroll_update, !needs_scroll_begin_);
tdresser 2016/03/08 14:28:52 This is a bit confusing. Why do we mark it synthet
dtapuska 2016/03/08 20:31:49 I've broken it apart to make it more clear.
151
152 if (needs_update)
153 client_->SendGestureEvent(scroll_update);
154
155 if (send_end_now) {
tdresser 2016/03/08 14:28:52 The naming of this variable is confusing. We send
dtapuska 2016/03/08 20:31:49 I've changed send_end_now to current_phase_ended..
156 SendScrollEnd(scroll_update.event, false);
157 } else if (has_phase_info) {
158 SendScrollEnd(scroll_update.event, true);
159 } else {
160 scroll_end_timer_.Start(
161 FROM_HERE,
162 base::TimeDelta::FromMilliseconds(scroll_transaction_ms_),
163 base::Bind(&MouseWheelEventQueue::SendScrollEnd,
164 base::Unretained(this), scroll_update.event, false));
165 }
166 }
118 } 167 }
119 168
120 event_sent_for_gesture_ack_.reset(); 169 event_sent_for_gesture_ack_.reset();
121 TryForwardNextEventToRenderer(); 170 TryForwardNextEventToRenderer();
122 } 171 }
123 172
124 void MouseWheelEventQueue::OnGestureScrollEvent( 173 void MouseWheelEventQueue::OnGestureScrollEvent(
125 const GestureEventWithLatencyInfo& gesture_event) { 174 const GestureEventWithLatencyInfo& gesture_event) {
126 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { 175 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) {
127 // If there is a current scroll going on and a new scroll that isn't 176 // If there is a current scroll going on and a new scroll that isn't
(...skipping 23 matching lines...) Expand all
151 event_sent_for_gesture_ack_.reset(wheel_queue_.front()); 200 event_sent_for_gesture_ack_.reset(wheel_queue_.front());
152 wheel_queue_.pop_front(); 201 wheel_queue_.pop_front();
153 202
154 MouseWheelEventWithLatencyInfo send_event(*event_sent_for_gesture_ack_); 203 MouseWheelEventWithLatencyInfo send_event(*event_sent_for_gesture_ack_);
155 if (send_gestures_) 204 if (send_gestures_)
156 send_event.event.canScroll = false; 205 send_event.event.canScroll = false;
157 206
158 client_->SendMouseWheelEventImmediately(send_event); 207 client_->SendMouseWheelEventImmediately(send_event);
159 } 208 }
160 209
161 void MouseWheelEventQueue::SendScrollEnd(blink::WebGestureEvent update_event) { 210 void MouseWheelEventQueue::SendScrollEnd(blink::WebGestureEvent update_event,
162 GestureEventWithLatencyInfo scroll_end; 211 bool synthetic) {
212 DCHECK((synthetic && !needs_scroll_end_) || needs_scroll_end_);
213
214 GestureEventWithLatencyInfo scroll_end(update_event);
215 scroll_end.event.timeStampSeconds =
216 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
163 scroll_end.event.type = WebInputEvent::GestureScrollEnd; 217 scroll_end.event.type = WebInputEvent::GestureScrollEnd;
164 scroll_end.event.sourceDevice = blink::WebGestureDeviceTouchpad;
165 scroll_end.event.resendingPluginId = -1; 218 scroll_end.event.resendingPluginId = -1;
219 scroll_end.event.data.scrollEnd.synthetic = synthetic;
220 scroll_end.event.data.scrollEnd.inertial =
221 update_event.data.scrollUpdate.inertial;
166 scroll_end.event.data.scrollEnd.deltaUnits = 222 scroll_end.event.data.scrollEnd.deltaUnits =
167 update_event.data.scrollUpdate.deltaUnits; 223 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 224
173 SendGesture(scroll_end); 225 if (!synthetic) {
226 needs_scroll_begin_ = true;
227 needs_scroll_end_ = false;
228
229 if (scroll_end_timer_.IsRunning())
230 scroll_end_timer_.Reset();
231 }
232 client_->SendGestureEvent(scroll_end);
174 } 233 }
175 234
176 void MouseWheelEventQueue::SendGesture( 235 void MouseWheelEventQueue::SendScrollBegin(
177 const GestureEventWithLatencyInfo& gesture) { 236 const GestureEventWithLatencyInfo& gesture_update,
178 switch (gesture.event.type) { 237 bool synthetic) {
179 case WebInputEvent::GestureScrollUpdate: 238 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 239
195 SendGesture(scroll_begin); 240 GestureEventWithLatencyInfo scroll_begin(gesture_update);
196 } 241 scroll_begin.event.type = WebInputEvent::GestureScrollBegin;
197 if (scroll_end_timer_.IsRunning()) { 242 scroll_begin.event.data.scrollBegin.synthetic = synthetic;
198 scroll_end_timer_.Reset(); 243 scroll_begin.event.data.scrollBegin.inertial =
199 } else { 244 gesture_update.event.data.scrollUpdate.inertial;
200 scroll_end_timer_.Start( 245 scroll_begin.event.data.scrollBegin.deltaXHint =
201 FROM_HERE, 246 gesture_update.event.data.scrollUpdate.deltaX;
202 base::TimeDelta::FromMilliseconds(scroll_transaction_ms_), 247 scroll_begin.event.data.scrollBegin.deltaYHint =
203 base::Bind(&MouseWheelEventQueue::SendScrollEnd, 248 gesture_update.event.data.scrollUpdate.deltaY;
204 base::Unretained(this), gesture.event)); 249 scroll_begin.event.data.scrollBegin.targetViewport = false;
205 } 250 scroll_begin.event.data.scrollBegin.deltaHintUnits =
206 break; 251 gesture_update.event.data.scrollUpdate.deltaUnits;
207 case WebInputEvent::GestureScrollEnd: 252
208 needs_scroll_begin_ = true; 253 needs_scroll_begin_ = false;
209 break; 254 needs_scroll_end_ = true;
210 case WebInputEvent::GestureScrollBegin: 255 client_->SendGestureEvent(scroll_begin);
211 needs_scroll_begin_ = false;
212 break;
213 default:
214 return;
215 }
216 client_->SendGestureEvent(gesture);
217 } 256 }
218 257
219 } // namespace content 258 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698