| 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/overscroll_controller_delegate.h" | 7 #include "content/browser/renderer_host/overscroll_controller_delegate.h" |
| 8 #include "content/browser/renderer_host/render_widget_host_impl.h" | 8 #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 9 #include "content/public/browser/overscroll_configuration.h" | 9 #include "content/public/browser/overscroll_configuration.h" |
| 10 #include "content/public/browser/render_widget_host_view.h" | 10 #include "content/public/browser/render_widget_host_view.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 } | 57 } |
| 58 | 58 |
| 59 if (DispatchEventCompletesAction(event)) { | 59 if (DispatchEventCompletesAction(event)) { |
| 60 CompleteAction(); | 60 CompleteAction(); |
| 61 | 61 |
| 62 // If the overscroll was caused by touch-scrolling, then the gesture event | 62 // If the overscroll was caused by touch-scrolling, then the gesture event |
| 63 // that completes the action needs to be sent to the renderer, because the | 63 // that completes the action needs to be sent to the renderer, because the |
| 64 // touch-scrolls maintain state in the renderer side (in the compositor, for | 64 // touch-scrolls maintain state in the renderer side (in the compositor, for |
| 65 // example), and the event that completes this action needs to be sent to | 65 // example), and the event that completes this action needs to be sent to |
| 66 // the renderer so that those states can be updated/reset appropriately. | 66 // the renderer so that those states can be updated/reset appropriately. |
| 67 // Send the event through the host when appropriate. | 67 if (WebKit::WebInputEvent::isGestureEventType(event.type)) { |
| 68 if (ShouldForwardToHost(event)) { | 68 // A gesture-event isn't sent to the GestureEventFilter when overscroll is |
| 69 // in progress. So dispatch the event through the RenderWidgetHost so that |
| 70 // it can reach the GestureEventFilter. |
| 69 const WebKit::WebGestureEvent& gevent = | 71 const WebKit::WebGestureEvent& gevent = |
| 70 static_cast<const WebKit::WebGestureEvent&>(event); | 72 static_cast<const WebKit::WebGestureEvent&>(event); |
| 71 return render_widget_host_->ShouldForwardGestureEvent( | 73 return render_widget_host_->ShouldForwardGestureEvent( |
| 72 GestureEventWithLatencyInfo(gevent, latency_info)); | 74 GestureEventWithLatencyInfo(gevent, latency_info)); |
| 73 } | 75 } |
| 74 | 76 |
| 75 return false; | 77 return true; |
| 76 } | 78 } |
| 77 | 79 |
| 78 if (overscroll_mode_ != OVERSCROLL_NONE && DispatchEventResetsState(event)) { | 80 if (overscroll_mode_ != OVERSCROLL_NONE && DispatchEventResetsState(event)) { |
| 79 SetOverscrollMode(OVERSCROLL_NONE); | 81 SetOverscrollMode(OVERSCROLL_NONE); |
| 80 // The overscroll gesture status is being reset. If the event is a | 82 if (WebKit::WebInputEvent::isGestureEventType(event.type)) { |
| 81 // gesture event (from either touchscreen or trackpad), then make sure the | 83 // A gesture-event isn't sent to the GestureEventFilter when overscroll is |
| 82 // host gets the event first (if it didn't already process it). | 84 // in progress. So dispatch the event through the RenderWidgetHost so that |
| 83 if (ShouldForwardToHost(event)) { | 85 // it can reach the GestureEventFilter. |
| 84 const WebKit::WebGestureEvent& gevent = | 86 const WebKit::WebGestureEvent& gevent = |
| 85 static_cast<const WebKit::WebGestureEvent&>(event); | 87 static_cast<const WebKit::WebGestureEvent&>(event); |
| 86 return render_widget_host_->ShouldForwardGestureEvent( | 88 return render_widget_host_->ShouldForwardGestureEvent( |
| 87 GestureEventWithLatencyInfo(gevent, latency_info)); | 89 GestureEventWithLatencyInfo(gevent, latency_info)); |
| 88 } | 90 } |
| 89 | 91 |
| 90 // Let the event be dispatched to the renderer. | 92 // Let the event be dispatched to the renderer. |
| 91 return true; | 93 return true; |
| 92 } | 94 } |
| 93 | 95 |
| 94 if (overscroll_mode_ != OVERSCROLL_NONE) { | 96 if (overscroll_mode_ != OVERSCROLL_NONE) { |
| 95 // Consume the event and update overscroll state when in the middle of the | 97 // Consume the event only if it updates the overscroll state. |
| 96 // overscroll gesture. | 98 if (ProcessEventForOverscroll(event)) |
| 97 ProcessEventForOverscroll(event); | 99 return false; |
| 98 | |
| 99 if (event.type == WebKit::WebInputEvent::TouchEnd || | |
| 100 event.type == WebKit::WebInputEvent::TouchCancel || | |
| 101 event.type == WebKit::WebInputEvent::TouchMove) { | |
| 102 return true; | |
| 103 } | |
| 104 return false; | |
| 105 } | 100 } |
| 106 | 101 |
| 107 return true; | 102 return true; |
| 108 } | 103 } |
| 109 | 104 |
| 110 void OverscrollController::ReceivedEventACK(const WebKit::WebInputEvent& event, | 105 void OverscrollController::ReceivedEventACK(const WebKit::WebInputEvent& event, |
| 111 bool processed) { | 106 bool processed) { |
| 112 if (processed) { | 107 if (processed) { |
| 113 // If a scroll event is consumed by the page, i.e. some content on the page | 108 // If a scroll event is consumed by the page, i.e. some content on the page |
| 114 // has been scrolled, then there is not going to be an overscroll gesture, | 109 // has been scrolled, then there is not going to be an overscroll gesture, |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 case WebKit::WebInputEvent::GestureFlingCancel: | 214 case WebKit::WebInputEvent::GestureFlingCancel: |
| 220 return false; | 215 return false; |
| 221 | 216 |
| 222 default: | 217 default: |
| 223 // Touch events can arrive during an overscroll gesture initiated by | 218 // Touch events can arrive during an overscroll gesture initiated by |
| 224 // touch-scrolling. These events should not reset the overscroll state. | 219 // touch-scrolling. These events should not reset the overscroll state. |
| 225 return !WebKit::WebInputEvent::isTouchEventType(event.type); | 220 return !WebKit::WebInputEvent::isTouchEventType(event.type); |
| 226 } | 221 } |
| 227 } | 222 } |
| 228 | 223 |
| 229 void OverscrollController::ProcessEventForOverscroll( | 224 bool OverscrollController::ProcessEventForOverscroll( |
| 230 const WebKit::WebInputEvent& event) { | 225 const WebKit::WebInputEvent& event) { |
| 226 bool event_processed = false; |
| 231 switch (event.type) { | 227 switch (event.type) { |
| 232 case WebKit::WebInputEvent::MouseWheel: { | 228 case WebKit::WebInputEvent::MouseWheel: { |
| 233 const WebKit::WebMouseWheelEvent& wheel = | 229 const WebKit::WebMouseWheelEvent& wheel = |
| 234 static_cast<const WebKit::WebMouseWheelEvent&>(event); | 230 static_cast<const WebKit::WebMouseWheelEvent&>(event); |
| 235 if (!wheel.hasPreciseScrollingDeltas) | 231 if (!wheel.hasPreciseScrollingDeltas) |
| 236 return; | 232 break; |
| 237 | 233 |
| 238 ProcessOverscroll(wheel.deltaX * wheel.accelerationRatioX, | 234 ProcessOverscroll(wheel.deltaX * wheel.accelerationRatioX, |
| 239 wheel.deltaY * wheel.accelerationRatioY, | 235 wheel.deltaY * wheel.accelerationRatioY, |
| 240 wheel.type); | 236 wheel.type); |
| 237 event_processed = true; |
| 241 break; | 238 break; |
| 242 } | 239 } |
| 243 case WebKit::WebInputEvent::GestureScrollUpdate: { | 240 case WebKit::WebInputEvent::GestureScrollUpdate: { |
| 244 const WebKit::WebGestureEvent& gesture = | 241 const WebKit::WebGestureEvent& gesture = |
| 245 static_cast<const WebKit::WebGestureEvent&>(event); | 242 static_cast<const WebKit::WebGestureEvent&>(event); |
| 246 ProcessOverscroll(gesture.data.scrollUpdate.deltaX, | 243 ProcessOverscroll(gesture.data.scrollUpdate.deltaX, |
| 247 gesture.data.scrollUpdate.deltaY, | 244 gesture.data.scrollUpdate.deltaY, |
| 248 gesture.type); | 245 gesture.type); |
| 246 event_processed = true; |
| 249 break; | 247 break; |
| 250 } | 248 } |
| 251 case WebKit::WebInputEvent::GestureFlingStart: { | 249 case WebKit::WebInputEvent::GestureFlingStart: { |
| 252 const float kFlingVelocityThreshold = 1100.f; | 250 const float kFlingVelocityThreshold = 1100.f; |
| 253 const WebKit::WebGestureEvent& gesture = | 251 const WebKit::WebGestureEvent& gesture = |
| 254 static_cast<const WebKit::WebGestureEvent&>(event); | 252 static_cast<const WebKit::WebGestureEvent&>(event); |
| 255 float velocity_x = gesture.data.flingStart.velocityX; | 253 float velocity_x = gesture.data.flingStart.velocityX; |
| 256 float velocity_y = gesture.data.flingStart.velocityY; | 254 float velocity_y = gesture.data.flingStart.velocityY; |
| 257 if (fabs(velocity_x) > kFlingVelocityThreshold) { | 255 if (fabs(velocity_x) > kFlingVelocityThreshold) { |
| 258 if ((overscroll_mode_ == OVERSCROLL_WEST && velocity_x < 0) || | 256 if ((overscroll_mode_ == OVERSCROLL_WEST && velocity_x < 0) || |
| 259 (overscroll_mode_ == OVERSCROLL_EAST && velocity_x > 0)) { | 257 (overscroll_mode_ == OVERSCROLL_EAST && velocity_x > 0)) { |
| 260 CompleteAction(); | 258 CompleteAction(); |
| 259 event_processed = true; |
| 261 break; | 260 break; |
| 262 } | 261 } |
| 263 } else if (fabs(velocity_y) > kFlingVelocityThreshold) { | 262 } else if (fabs(velocity_y) > kFlingVelocityThreshold) { |
| 264 if ((overscroll_mode_ == OVERSCROLL_NORTH && velocity_y < 0) || | 263 if ((overscroll_mode_ == OVERSCROLL_NORTH && velocity_y < 0) || |
| 265 (overscroll_mode_ == OVERSCROLL_SOUTH && velocity_y > 0)) { | 264 (overscroll_mode_ == OVERSCROLL_SOUTH && velocity_y > 0)) { |
| 266 CompleteAction(); | 265 CompleteAction(); |
| 266 event_processed = true; |
| 267 break; | 267 break; |
| 268 } | 268 } |
| 269 } | 269 } |
| 270 | 270 |
| 271 // Reset overscroll state if fling didn't complete the overscroll gesture. | 271 // Reset overscroll state if fling didn't complete the overscroll gesture. |
| 272 SetOverscrollMode(OVERSCROLL_NONE); | 272 SetOverscrollMode(OVERSCROLL_NONE); |
| 273 break; | 273 break; |
| 274 } | 274 } |
| 275 | 275 |
| 276 default: | 276 default: |
| 277 DCHECK(WebKit::WebInputEvent::isGestureEventType(event.type) || | 277 DCHECK(WebKit::WebInputEvent::isGestureEventType(event.type) || |
| 278 WebKit::WebInputEvent::isTouchEventType(event.type)) | 278 WebKit::WebInputEvent::isTouchEventType(event.type)) |
| 279 << "Received unexpected event: " << event.type; | 279 << "Received unexpected event: " << event.type; |
| 280 } | 280 } |
| 281 return event_processed; |
| 281 } | 282 } |
| 282 | 283 |
| 283 void OverscrollController::ProcessOverscroll(float delta_x, | 284 void OverscrollController::ProcessOverscroll(float delta_x, |
| 284 float delta_y, | 285 float delta_y, |
| 285 WebKit::WebInputEvent::Type type) { | 286 WebKit::WebInputEvent::Type type) { |
| 286 if (scroll_state_ != STATE_CONTENT_SCROLLING) | 287 if (scroll_state_ != STATE_CONTENT_SCROLLING) |
| 287 overscroll_delta_x_ += delta_x; | 288 overscroll_delta_x_ += delta_x; |
| 288 overscroll_delta_y_ += delta_y; | 289 overscroll_delta_y_ += delta_y; |
| 289 | 290 |
| 290 float horiz_threshold = GetOverscrollConfig( | 291 float horiz_threshold = GetOverscrollConfig( |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 OverscrollMode old_mode = overscroll_mode_; | 361 OverscrollMode old_mode = overscroll_mode_; |
| 361 overscroll_mode_ = mode; | 362 overscroll_mode_ = mode; |
| 362 if (overscroll_mode_ == OVERSCROLL_NONE) | 363 if (overscroll_mode_ == OVERSCROLL_NONE) |
| 363 overscroll_delta_x_ = overscroll_delta_y_ = 0.f; | 364 overscroll_delta_x_ = overscroll_delta_y_ = 0.f; |
| 364 else | 365 else |
| 365 scroll_state_ = STATE_OVERSCROLLING; | 366 scroll_state_ = STATE_OVERSCROLLING; |
| 366 if (delegate_) | 367 if (delegate_) |
| 367 delegate_->OnOverscrollModeChange(old_mode, overscroll_mode_); | 368 delegate_->OnOverscrollModeChange(old_mode, overscroll_mode_); |
| 368 } | 369 } |
| 369 | 370 |
| 370 bool OverscrollController::ShouldForwardToHost( | |
| 371 const WebKit::WebInputEvent& event) const { | |
| 372 if (!WebKit::WebInputEvent::isGestureEventType(event.type)) | |
| 373 return false; | |
| 374 | |
| 375 // If the RenderWidgetHost already processed this event, then the event must | |
| 376 // not be sent again. | |
| 377 return !render_widget_host_->HasQueuedGestureEvents(); | |
| 378 } | |
| 379 | |
| 380 } // namespace content | 371 } // namespace content |
| OLD | NEW |