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 |