OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/overscroll_controller.h" | 5 #include "content/browser/renderer_host/overscroll_controller.h" |
6 | 6 |
7 #include "content/browser/renderer_host/gesture_event_filter.h" | 7 #include "content/browser/renderer_host/gesture_event_filter.h" |
8 #include "content/browser/renderer_host/overscroll_controller_delegate.h" | 8 #include "content/browser/renderer_host/overscroll_controller_delegate.h" |
9 #include "content/browser/renderer_host/render_widget_host_impl.h" | 9 #include "content/browser/renderer_host/render_widget_host_impl.h" |
10 #include "content/public/browser/overscroll_configuration.h" | 10 #include "content/public/browser/overscroll_configuration.h" |
11 #include "content/public/browser/render_widget_host_view.h" | 11 #include "content/public/browser/render_widget_host_view.h" |
12 | 12 |
13 namespace content { | 13 namespace content { |
14 | 14 |
15 OverscrollController::OverscrollController( | 15 OverscrollController::OverscrollController( |
16 RenderWidgetHostImpl* render_widget_host) | 16 RenderWidgetHostImpl* render_widget_host) |
17 : render_widget_host_(render_widget_host), | 17 : render_widget_host_(render_widget_host), |
18 overscroll_mode_(OVERSCROLL_NONE), | 18 overscroll_mode_(OVERSCROLL_NONE), |
| 19 scroll_state_(STATE_UNKNOWN), |
19 overscroll_delta_x_(0.f), | 20 overscroll_delta_x_(0.f), |
20 overscroll_delta_y_(0.f), | 21 overscroll_delta_y_(0.f), |
21 delegate_(NULL) { | 22 delegate_(NULL) { |
22 } | 23 } |
23 | 24 |
24 OverscrollController::~OverscrollController() { | 25 OverscrollController::~OverscrollController() { |
25 } | 26 } |
26 | 27 |
27 bool OverscrollController::WillDispatchEvent( | 28 bool OverscrollController::WillDispatchEvent( |
28 const WebKit::WebInputEvent& event, | 29 const WebKit::WebInputEvent& event, |
29 const cc::LatencyInfo& latency_info) { | 30 const cc::LatencyInfo& latency_info) { |
| 31 if (scroll_state_ != STATE_UNKNOWN) { |
| 32 if (event.type == WebKit::WebInputEvent::GestureScrollEnd) { |
| 33 scroll_state_ = STATE_UNKNOWN; |
| 34 } else if (event.type == WebKit::WebInputEvent::GestureFlingStart) { |
| 35 // Start of a fling indicates the end of a scroll, both from touchpad and |
| 36 // touchscreen. So it is not necessary to check |sourceDevice| of the |
| 37 // event. |
| 38 scroll_state_ = STATE_UNKNOWN; |
| 39 } else if (event.type == WebKit::WebInputEvent::MouseWheel) { |
| 40 const WebKit::WebMouseWheelEvent& wheel = |
| 41 static_cast<const WebKit::WebMouseWheelEvent&>(event); |
| 42 if (wheel.hasPreciseScrollingDeltas && |
| 43 (wheel.phase == WebKit::WebMouseWheelEvent::PhaseEnded || |
| 44 wheel.phase == WebKit::WebMouseWheelEvent::PhaseCancelled)) { |
| 45 scroll_state_ = STATE_UNKNOWN; |
| 46 } |
| 47 } |
| 48 } |
| 49 |
30 if (DispatchEventCompletesAction(event)) { | 50 if (DispatchEventCompletesAction(event)) { |
31 CompleteAction(); | 51 CompleteAction(); |
32 | 52 |
33 // If the overscroll was caused by touch-scrolling, then the gesture event | 53 // If the overscroll was caused by touch-scrolling, then the gesture event |
34 // that completes the action needs to be sent to the renderer, because the | 54 // that completes the action needs to be sent to the renderer, because the |
35 // touch-scrolls maintain state in the renderer side (in the compositor, for | 55 // touch-scrolls maintain state in the renderer side (in the compositor, for |
36 // example), and the event that completes this action needs to be sent to | 56 // example), and the event that completes this action needs to be sent to |
37 // the renderer so that those states can be updated/reset appropriately. | 57 // the renderer so that those states can be updated/reset appropriately. |
38 // Send the event through the gesture-event filter when appropriate. | 58 // Send the event through the gesture-event filter when appropriate. |
39 if (ShouldForwardToGestureFilter(event)) { | 59 if (ShouldForwardToGestureFilter(event)) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 event.type == WebKit::WebInputEvent::TouchCancel) | 92 event.type == WebKit::WebInputEvent::TouchCancel) |
73 return true; | 93 return true; |
74 return false; | 94 return false; |
75 } | 95 } |
76 | 96 |
77 return true; | 97 return true; |
78 } | 98 } |
79 | 99 |
80 void OverscrollController::ReceivedEventACK(const WebKit::WebInputEvent& event, | 100 void OverscrollController::ReceivedEventACK(const WebKit::WebInputEvent& event, |
81 bool processed) { | 101 bool processed) { |
82 if (processed) | 102 if (processed) { |
| 103 // If a scroll event is consumed by the page, i.e. some content on the page |
| 104 // has been scrolled, then there is not going to be an overscroll gesture, |
| 105 // until the current scroll ends, and a new scroll gesture starts. |
| 106 if (scroll_state_ == STATE_UNKNOWN && |
| 107 (event.type == WebKit::WebInputEvent::MouseWheel || |
| 108 event.type == WebKit::WebInputEvent::GestureScrollUpdate)) { |
| 109 scroll_state_ = STATE_CONTENT_SCROLLING; |
| 110 } |
83 return; | 111 return; |
| 112 } |
84 ProcessEventForOverscroll(event); | 113 ProcessEventForOverscroll(event); |
85 } | 114 } |
86 | 115 |
87 void OverscrollController::Reset() { | 116 void OverscrollController::Reset() { |
88 overscroll_mode_ = OVERSCROLL_NONE; | 117 overscroll_mode_ = OVERSCROLL_NONE; |
89 overscroll_delta_x_ = overscroll_delta_y_ = 0.f; | 118 overscroll_delta_x_ = overscroll_delta_y_ = 0.f; |
| 119 scroll_state_ = STATE_UNKNOWN; |
90 } | 120 } |
91 | 121 |
92 bool OverscrollController::DispatchEventCompletesAction ( | 122 bool OverscrollController::DispatchEventCompletesAction ( |
93 const WebKit::WebInputEvent& event) const { | 123 const WebKit::WebInputEvent& event) const { |
94 if (overscroll_mode_ == OVERSCROLL_NONE) | 124 if (overscroll_mode_ == OVERSCROLL_NONE) |
95 return false; | 125 return false; |
96 | 126 |
97 // Complete the overscroll gesture if there was a mouse move or a scroll-end | 127 // Complete the overscroll gesture if there was a mouse move or a scroll-end |
98 // after the threshold. | 128 // after the threshold. |
99 if (event.type != WebKit::WebInputEvent::MouseMove && | 129 if (event.type != WebKit::WebInputEvent::MouseMove && |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 return !WebKit::WebInputEvent::isTouchEventType(event.type); | 200 return !WebKit::WebInputEvent::isTouchEventType(event.type); |
171 } | 201 } |
172 } | 202 } |
173 | 203 |
174 void OverscrollController::ProcessEventForOverscroll( | 204 void OverscrollController::ProcessEventForOverscroll( |
175 const WebKit::WebInputEvent& event) { | 205 const WebKit::WebInputEvent& event) { |
176 switch (event.type) { | 206 switch (event.type) { |
177 case WebKit::WebInputEvent::MouseWheel: { | 207 case WebKit::WebInputEvent::MouseWheel: { |
178 const WebKit::WebMouseWheelEvent& wheel = | 208 const WebKit::WebMouseWheelEvent& wheel = |
179 static_cast<const WebKit::WebMouseWheelEvent&>(event); | 209 static_cast<const WebKit::WebMouseWheelEvent&>(event); |
180 if (wheel.hasPreciseScrollingDeltas) { | 210 if (!wheel.hasPreciseScrollingDeltas) |
181 ProcessOverscroll(wheel.deltaX * wheel.accelerationRatioX, | 211 return; |
182 wheel.deltaY * wheel.accelerationRatioY); | 212 |
183 } | 213 ProcessOverscroll(wheel.deltaX * wheel.accelerationRatioX, |
| 214 wheel.deltaY * wheel.accelerationRatioY); |
184 break; | 215 break; |
185 } | 216 } |
186 case WebKit::WebInputEvent::GestureScrollUpdate: { | 217 case WebKit::WebInputEvent::GestureScrollUpdate: { |
187 const WebKit::WebGestureEvent& gesture = | 218 const WebKit::WebGestureEvent& gesture = |
188 static_cast<const WebKit::WebGestureEvent&>(event); | 219 static_cast<const WebKit::WebGestureEvent&>(event); |
189 ProcessOverscroll(gesture.data.scrollUpdate.deltaX, | 220 ProcessOverscroll(gesture.data.scrollUpdate.deltaX, |
190 gesture.data.scrollUpdate.deltaY); | 221 gesture.data.scrollUpdate.deltaY); |
191 break; | 222 break; |
192 } | 223 } |
193 case WebKit::WebInputEvent::GestureFlingStart: { | 224 case WebKit::WebInputEvent::GestureFlingStart: { |
(...skipping 22 matching lines...) Expand all Loading... |
216 } | 247 } |
217 | 248 |
218 default: | 249 default: |
219 DCHECK(WebKit::WebInputEvent::isGestureEventType(event.type) || | 250 DCHECK(WebKit::WebInputEvent::isGestureEventType(event.type) || |
220 WebKit::WebInputEvent::isTouchEventType(event.type)) | 251 WebKit::WebInputEvent::isTouchEventType(event.type)) |
221 << "Received unexpected event: " << event.type; | 252 << "Received unexpected event: " << event.type; |
222 } | 253 } |
223 } | 254 } |
224 | 255 |
225 void OverscrollController::ProcessOverscroll(float delta_x, float delta_y) { | 256 void OverscrollController::ProcessOverscroll(float delta_x, float delta_y) { |
| 257 if (scroll_state_ == STATE_CONTENT_SCROLLING) |
| 258 return; |
226 overscroll_delta_x_ += delta_x; | 259 overscroll_delta_x_ += delta_x; |
227 overscroll_delta_y_ += delta_y; | 260 overscroll_delta_y_ += delta_y; |
228 | 261 |
229 float threshold = GetOverscrollConfig(OVERSCROLL_CONFIG_MIN_THRESHOLD_START); | 262 float threshold = GetOverscrollConfig(OVERSCROLL_CONFIG_MIN_THRESHOLD_START); |
230 if (fabs(overscroll_delta_x_) < threshold && | 263 if (fabs(overscroll_delta_x_) < threshold && |
231 fabs(overscroll_delta_y_) < threshold) { | 264 fabs(overscroll_delta_y_) < threshold) { |
232 SetOverscrollMode(OVERSCROLL_NONE); | 265 SetOverscrollMode(OVERSCROLL_NONE); |
233 return; | 266 return; |
234 } | 267 } |
235 | 268 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 overscroll_delta_x_ = overscroll_delta_y_ = 0.f; | 318 overscroll_delta_x_ = overscroll_delta_y_ = 0.f; |
286 } | 319 } |
287 | 320 |
288 void OverscrollController::SetOverscrollMode(OverscrollMode mode) { | 321 void OverscrollController::SetOverscrollMode(OverscrollMode mode) { |
289 if (overscroll_mode_ == mode) | 322 if (overscroll_mode_ == mode) |
290 return; | 323 return; |
291 OverscrollMode old_mode = overscroll_mode_; | 324 OverscrollMode old_mode = overscroll_mode_; |
292 overscroll_mode_ = mode; | 325 overscroll_mode_ = mode; |
293 if (overscroll_mode_ == OVERSCROLL_NONE) | 326 if (overscroll_mode_ == OVERSCROLL_NONE) |
294 overscroll_delta_x_ = overscroll_delta_y_ = 0.f; | 327 overscroll_delta_x_ = overscroll_delta_y_ = 0.f; |
| 328 else |
| 329 scroll_state_ = STATE_OVERSCROLLING; |
295 if (delegate_) | 330 if (delegate_) |
296 delegate_->OnOverscrollModeChange(old_mode, overscroll_mode_); | 331 delegate_->OnOverscrollModeChange(old_mode, overscroll_mode_); |
297 } | 332 } |
298 | 333 |
299 bool OverscrollController::ShouldForwardToGestureFilter( | 334 bool OverscrollController::ShouldForwardToGestureFilter( |
300 const WebKit::WebInputEvent& event) const { | 335 const WebKit::WebInputEvent& event) const { |
301 if (!WebKit::WebInputEvent::isGestureEventType(event.type)) | 336 if (!WebKit::WebInputEvent::isGestureEventType(event.type)) |
302 return false; | 337 return false; |
303 | 338 |
304 // If the GestureEventFilter already processed this event, then the event must | 339 // If the GestureEventFilter already processed this event, then the event must |
305 // not be sent to the filter again. | 340 // not be sent to the filter again. |
306 return !render_widget_host_->gesture_event_filter()->HasQueuedGestureEvents(); | 341 return !render_widget_host_->gesture_event_filter()->HasQueuedGestureEvents(); |
307 } | 342 } |
308 | 343 |
309 } // namespace content | 344 } // namespace content |
OLD | NEW |