Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/render_widget_host_input_event_router.h" | 5 #include "content/browser/renderer_host/render_widget_host_input_event_router.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram_macros.h" | |
| 7 #include "cc/quads/surface_draw_quad.h" | 8 #include "cc/quads/surface_draw_quad.h" |
| 8 #include "cc/surfaces/surface_id_allocator.h" | 9 #include "cc/surfaces/surface_id_allocator.h" |
| 9 #include "cc/surfaces/surface_manager.h" | 10 #include "cc/surfaces/surface_manager.h" |
| 10 #include "content/browser/renderer_host/render_widget_host_impl.h" | 11 #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 11 #include "content/browser/renderer_host/render_widget_host_view_base.h" | 12 #include "content/browser/renderer_host/render_widget_host_view_base.h" |
| 12 #include "content/common/frame_messages.h" | 13 #include "content/common/frame_messages.h" |
| 13 #include "third_party/WebKit/public/web/WebInputEvent.h" | 14 #include "third_party/WebKit/public/web/WebInputEvent.h" |
| 14 | 15 |
| 15 namespace { | 16 namespace { |
| 16 | 17 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 break; | 182 break; |
| 182 case blink::WebGestureDeviceTouchpad: | 183 case blink::WebGestureDeviceTouchpad: |
| 183 RouteTouchpadGestureEvent(root_view, event, latency); | 184 RouteTouchpadGestureEvent(root_view, event, latency); |
| 184 break; | 185 break; |
| 185 case blink::WebGestureDeviceTouchscreen: | 186 case blink::WebGestureDeviceTouchscreen: |
| 186 RouteTouchscreenGestureEvent(root_view, event, latency); | 187 RouteTouchscreenGestureEvent(root_view, event, latency); |
| 187 break; | 188 break; |
| 188 }; | 189 }; |
| 189 } | 190 } |
| 190 | 191 |
| 192 namespace { | |
| 193 | |
| 194 unsigned CountChangedTouchPoints(const blink::WebTouchEvent& event) { | |
| 195 unsigned changed_count = 0; | |
| 196 | |
| 197 blink::WebTouchPoint::State required_state = | |
| 198 blink::WebTouchPoint::StateUndefined; | |
| 199 switch (event.type) { | |
| 200 case blink::WebInputEvent::TouchStart: | |
| 201 required_state = blink::WebTouchPoint::StatePressed; | |
| 202 break; | |
| 203 case blink::WebInputEvent::TouchEnd: | |
| 204 required_state = blink::WebTouchPoint::StateReleased; | |
| 205 break; | |
| 206 case blink::WebInputEvent::TouchCancel: | |
| 207 required_state = blink::WebTouchPoint::StateCancelled; | |
| 208 break; | |
| 209 default: | |
| 210 // We'll only ever call this method for TouchStart, TouchEnd | |
| 211 // and TounchCancel events, so mark the rest as not-reached. | |
| 212 NOTREACHED(); | |
| 213 } | |
| 214 for (unsigned i = 0; i < event.touchesLength; ++i) { | |
| 215 if (event.touches[i].state == required_state) | |
| 216 ++changed_count; | |
| 217 } | |
| 218 | |
|
tdresser
2016/08/29 15:52:46
If we aren't aware of any case where this shouldn'
| |
| 219 return changed_count; | |
| 220 } | |
| 221 | |
| 222 } // namespace | |
| 223 | |
| 191 void RenderWidgetHostInputEventRouter::RouteTouchEvent( | 224 void RenderWidgetHostInputEventRouter::RouteTouchEvent( |
| 192 RenderWidgetHostViewBase* root_view, | 225 RenderWidgetHostViewBase* root_view, |
| 193 blink::WebTouchEvent* event, | 226 blink::WebTouchEvent* event, |
| 194 const ui::LatencyInfo& latency) { | 227 const ui::LatencyInfo& latency) { |
| 195 switch (event->type) { | 228 switch (event->type) { |
| 196 case blink::WebInputEvent::TouchStart: { | 229 case blink::WebInputEvent::TouchStart: { |
| 197 if (!active_touches_) { | 230 active_touches_ += CountChangedTouchPoints(*event); |
| 231 if (active_touches_ == 1) { | |
| 198 // Since this is the first touch, it defines the target for the rest | 232 // Since this is the first touch, it defines the target for the rest |
| 199 // of this sequence. | 233 // of this sequence. |
| 200 DCHECK(!touch_target_.target); | 234 DCHECK(!touch_target_.target); |
| 201 gfx::Point transformed_point; | 235 gfx::Point transformed_point; |
| 202 gfx::Point original_point(event->touches[0].position.x, | 236 gfx::Point original_point(event->touches[0].position.x, |
| 203 event->touches[0].position.y); | 237 event->touches[0].position.y); |
| 204 touch_target_.target = | 238 touch_target_.target = |
| 205 FindEventTarget(root_view, original_point, &transformed_point); | 239 FindEventTarget(root_view, original_point, &transformed_point); |
| 206 | 240 |
| 207 // TODO(wjmaclean): Instead of just computing a delta, we should extract | 241 // TODO(wjmaclean): Instead of just computing a delta, we should extract |
| 208 // the complete transform. We assume it doesn't change for the duration | 242 // the complete transform. We assume it doesn't change for the duration |
| 209 // of the touch sequence, though this could be wrong; a better approach | 243 // of the touch sequence, though this could be wrong; a better approach |
| 210 // might be to always transform each point to the |touch_target_.target| | 244 // might be to always transform each point to the |touch_target_.target| |
| 211 // for the duration of the sequence. | 245 // for the duration of the sequence. |
| 212 touch_target_.delta = transformed_point - original_point; | 246 touch_target_.delta = transformed_point - original_point; |
| 213 touchscreen_gesture_target_queue_.push_back(touch_target_); | 247 touchscreen_gesture_target_queue_.push_back(touch_target_); |
| 214 | 248 |
| 215 if (!touch_target_.target) { | 249 if (!touch_target_.target) |
| 216 return; | 250 return; |
| 217 } else if (touch_target_.target == | 251 |
| 218 bubbling_gesture_scroll_target_.target) { | 252 if (touch_target_.target == bubbling_gesture_scroll_target_.target) { |
| 219 SendGestureScrollEnd(bubbling_gesture_scroll_target_.target, | 253 SendGestureScrollEnd(bubbling_gesture_scroll_target_.target, |
| 220 blink::WebGestureEvent()); | 254 blink::WebGestureEvent()); |
| 221 CancelScrollBubbling(bubbling_gesture_scroll_target_.target); | 255 CancelScrollBubbling(bubbling_gesture_scroll_target_.target); |
| 222 } | 256 } |
| 223 } | 257 } |
| 224 | 258 |
| 225 ++active_touches_; | |
| 226 if (touch_target_.target) { | 259 if (touch_target_.target) { |
| 227 TransformEventTouchPositions(event, touch_target_.delta); | 260 TransformEventTouchPositions(event, touch_target_.delta); |
| 228 touch_target_.target->ProcessTouchEvent(*event, latency); | 261 touch_target_.target->ProcessTouchEvent(*event, latency); |
| 229 } | 262 } |
| 230 break; | 263 break; |
| 231 } | 264 } |
| 232 case blink::WebInputEvent::TouchMove: | 265 case blink::WebInputEvent::TouchMove: |
| 233 if (touch_target_.target) { | 266 if (touch_target_.target) { |
| 234 TransformEventTouchPositions(event, touch_target_.delta); | 267 TransformEventTouchPositions(event, touch_target_.delta); |
| 235 touch_target_.target->ProcessTouchEvent(*event, latency); | 268 touch_target_.target->ProcessTouchEvent(*event, latency); |
| 236 } | 269 } |
| 237 break; | 270 break; |
| 238 case blink::WebInputEvent::TouchEnd: | 271 case blink::WebInputEvent::TouchEnd: |
| 239 case blink::WebInputEvent::TouchCancel: | 272 case blink::WebInputEvent::TouchCancel: |
| 273 DCHECK(active_touches_); | |
| 274 active_touches_ -= CountChangedTouchPoints(*event); | |
| 240 if (!touch_target_.target) | 275 if (!touch_target_.target) |
| 241 break; | 276 return; |
| 242 | 277 |
| 243 DCHECK(active_touches_); | |
| 244 TransformEventTouchPositions(event, touch_target_.delta); | 278 TransformEventTouchPositions(event, touch_target_.delta); |
| 245 touch_target_.target->ProcessTouchEvent(*event, latency); | 279 touch_target_.target->ProcessTouchEvent(*event, latency); |
| 246 --active_touches_; | |
| 247 if (!active_touches_) | 280 if (!active_touches_) |
| 248 touch_target_.target = nullptr; | 281 touch_target_.target = nullptr; |
| 249 break; | 282 break; |
| 250 default: | 283 default: |
| 251 NOTREACHED(); | 284 NOTREACHED(); |
| 252 } | 285 } |
| 253 } | 286 } |
| 254 | 287 |
| 255 void RenderWidgetHostInputEventRouter::BubbleScrollEvent( | 288 void RenderWidgetHostInputEventRouter::BubbleScrollEvent( |
| 256 RenderWidgetHostViewBase* target_view, | 289 RenderWidgetHostViewBase* target_view, |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 } | 467 } |
| 435 return; | 468 return; |
| 436 } | 469 } |
| 437 | 470 |
| 438 // We use GestureTapDown to detect the start of a gesture sequence since there | 471 // We use GestureTapDown to detect the start of a gesture sequence since there |
| 439 // is no WebGestureEvent equivalent for ET_GESTURE_BEGIN. Note that this | 472 // is no WebGestureEvent equivalent for ET_GESTURE_BEGIN. Note that this |
| 440 // means the GestureFlingCancel that always comes between ET_GESTURE_BEGIN and | 473 // means the GestureFlingCancel that always comes between ET_GESTURE_BEGIN and |
| 441 // GestureTapDown is sent to the previous target, in case it is still in a | 474 // GestureTapDown is sent to the previous target, in case it is still in a |
| 442 // fling. | 475 // fling. |
| 443 if (event->type == blink::WebInputEvent::GestureTapDown) { | 476 if (event->type == blink::WebInputEvent::GestureTapDown) { |
| 444 if (touchscreen_gesture_target_queue_.empty()) { | 477 bool no_target = touchscreen_gesture_target_queue_.empty(); |
| 478 UMA_HISTOGRAM_BOOLEAN("Event.FrameEventRouting.NoGestureTarget", no_target); | |
| 479 if (no_target) { | |
| 445 LOG(ERROR) << "Gesture sequence start detected with no target available."; | 480 LOG(ERROR) << "Gesture sequence start detected with no target available."; |
| 446 // Ignore this gesture sequence as no target is available. | 481 // Ignore this gesture sequence as no target is available. |
| 447 // TODO(wjmaclean): this only happens on Windows, and should not happen. | 482 // TODO(wjmaclean): this only happens on Windows, and should not happen. |
| 448 // https://crbug.com/595422 | 483 // https://crbug.com/595422 |
| 449 touchscreen_gesture_target_.target = nullptr; | 484 touchscreen_gesture_target_.target = nullptr; |
| 450 return; | 485 return; |
| 451 } | 486 } |
| 452 | 487 |
| 453 touchscreen_gesture_target_ = touchscreen_gesture_target_queue_.front(); | 488 touchscreen_gesture_target_ = touchscreen_gesture_target_queue_.front(); |
| 454 touchscreen_gesture_target_queue_.pop_front(); | 489 touchscreen_gesture_target_queue_.pop_front(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 504 if (!touchpad_gesture_target_.target) | 539 if (!touchpad_gesture_target_.target) |
| 505 return; | 540 return; |
| 506 | 541 |
| 507 // TODO(mohsen): Add tests to check event location. | 542 // TODO(mohsen): Add tests to check event location. |
| 508 event->x += touchpad_gesture_target_.delta.x(); | 543 event->x += touchpad_gesture_target_.delta.x(); |
| 509 event->y += touchpad_gesture_target_.delta.y(); | 544 event->y += touchpad_gesture_target_.delta.y(); |
| 510 touchpad_gesture_target_.target->ProcessGestureEvent(*event, latency); | 545 touchpad_gesture_target_.target->ProcessGestureEvent(*event, latency); |
| 511 } | 546 } |
| 512 | 547 |
| 513 } // namespace content | 548 } // namespace content |
| OLD | NEW |