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 <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
10 | 10 |
11 #include "cc/quads/surface_draw_quad.h" | 11 #include "cc/quads/surface_draw_quad.h" |
12 #include "cc/surfaces/surface_id_allocator.h" | 12 #include "cc/surfaces/surface_id_allocator.h" |
13 #include "cc/surfaces/surface_manager.h" | 13 #include "cc/surfaces/surface_manager.h" |
14 #include "content/browser/frame_host/render_widget_host_view_child_frame.h" | 14 #include "content/browser/frame_host/render_widget_host_view_child_frame.h" |
15 #include "content/browser/renderer_host/render_widget_host_impl.h" | 15 #include "content/browser/renderer_host/render_widget_host_impl.h" |
16 #include "content/browser/renderer_host/render_widget_host_view_base.h" | 16 #include "content/browser/renderer_host/render_widget_host_view_base.h" |
17 #include "content/common/frame_messages.h" | 17 #include "content/common/frame_messages.h" |
18 #include "third_party/WebKit/public/web/WebInputEvent.h" | 18 #include "third_party/WebKit/public/web/WebInputEvent.h" |
| 19 #include "ui/events/blink/web_input_event_traits.h" |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
22 void TransformEventTouchPositions(blink::WebTouchEvent* event, | 23 void TransformEventTouchPositions(blink::WebTouchEvent* event, |
23 const gfx::Vector2d& delta) { | 24 const gfx::Vector2d& delta) { |
24 for (unsigned i = 0; i < event->touchesLength; ++i) { | 25 for (unsigned i = 0; i < event->touchesLength; ++i) { |
25 event->touches[i].position.x += delta.x(); | 26 event->touches[i].position.x += delta.x(); |
26 event->touches[i].position.y += delta.y(); | 27 event->touches[i].position.y += delta.y(); |
27 } | 28 } |
28 } | 29 } |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 // it likely means the RenderWidgetHostView has been destroyed but its | 161 // it likely means the RenderWidgetHostView has been destroyed but its |
161 // parent frame has not sent a new compositor frame since that happened. | 162 // parent frame has not sent a new compositor frame since that happened. |
162 if (iter == owner_map_.end()) | 163 if (iter == owner_map_.end()) |
163 return root_view; | 164 return root_view; |
164 | 165 |
165 return iter->second; | 166 return iter->second; |
166 } | 167 } |
167 | 168 |
168 void RenderWidgetHostInputEventRouter::RouteMouseEvent( | 169 void RenderWidgetHostInputEventRouter::RouteMouseEvent( |
169 RenderWidgetHostViewBase* root_view, | 170 RenderWidgetHostViewBase* root_view, |
170 blink::WebMouseEvent* event) { | 171 blink::WebMouseEvent* event, |
| 172 const ui::LatencyInfo& latency) { |
171 gfx::Point transformed_point; | 173 gfx::Point transformed_point; |
172 RenderWidgetHostViewBase* target = FindEventTarget( | 174 RenderWidgetHostViewBase* target = FindEventTarget( |
173 root_view, gfx::Point(event->x, event->y), &transformed_point); | 175 root_view, gfx::Point(event->x, event->y), &transformed_point); |
174 if (!target) | 176 if (!target) |
175 return; | 177 return; |
176 | 178 |
177 // SendMouseEnterOrLeaveEvents is called with the original event | 179 // SendMouseEnterOrLeaveEvents is called with the original event |
178 // coordinates, which are transformed independently for each view that will | 180 // coordinates, which are transformed independently for each view that will |
179 // receive an event. | 181 // receive an event. |
180 if ((event->type == blink::WebInputEvent::MouseLeave || | 182 if ((event->type == blink::WebInputEvent::MouseLeave || |
181 event->type == blink::WebInputEvent::MouseMove) && | 183 event->type == blink::WebInputEvent::MouseMove) && |
182 target != last_mouse_move_target_) | 184 target != last_mouse_move_target_) |
183 SendMouseEnterOrLeaveEvents(event, target, root_view); | 185 SendMouseEnterOrLeaveEvents(event, target, root_view); |
184 | 186 |
185 event->x = transformed_point.x(); | 187 event->x = transformed_point.x(); |
186 event->y = transformed_point.y(); | 188 event->y = transformed_point.y(); |
187 // TODO(wjmaclean): Initialize latency info correctly for OOPIFs. | 189 target->ProcessMouseEvent(*event, latency); |
188 // https://crbug.com/613628 | |
189 ui::LatencyInfo latency_info; | |
190 target->ProcessMouseEvent(*event, latency_info); | |
191 } | 190 } |
192 | 191 |
193 void RenderWidgetHostInputEventRouter::RouteMouseWheelEvent( | 192 void RenderWidgetHostInputEventRouter::RouteMouseWheelEvent( |
194 RenderWidgetHostViewBase* root_view, | 193 RenderWidgetHostViewBase* root_view, |
195 blink::WebMouseWheelEvent* event) { | 194 blink::WebMouseWheelEvent* event, |
| 195 const ui::LatencyInfo& latency) { |
196 gfx::Point transformed_point; | 196 gfx::Point transformed_point; |
197 RenderWidgetHostViewBase* target = FindEventTarget( | 197 RenderWidgetHostViewBase* target = FindEventTarget( |
198 root_view, gfx::Point(event->x, event->y), &transformed_point); | 198 root_view, gfx::Point(event->x, event->y), &transformed_point); |
199 if (!target) | 199 if (!target) |
200 return; | 200 return; |
201 | 201 |
202 event->x = transformed_point.x(); | 202 event->x = transformed_point.x(); |
203 event->y = transformed_point.y(); | 203 event->y = transformed_point.y(); |
204 // TODO(wjmaclean): Initialize latency info correctly for OOPIFs. | 204 target->ProcessMouseWheelEvent(*event, latency); |
205 // https://crbug.com/613628 | |
206 ui::LatencyInfo latency_info; | |
207 target->ProcessMouseWheelEvent(*event, latency_info); | |
208 } | 205 } |
209 | 206 |
210 void RenderWidgetHostInputEventRouter::RouteGestureEvent( | 207 void RenderWidgetHostInputEventRouter::RouteGestureEvent( |
211 RenderWidgetHostViewBase* root_view, | 208 RenderWidgetHostViewBase* root_view, |
212 blink::WebGestureEvent* event, | 209 blink::WebGestureEvent* event, |
213 const ui::LatencyInfo& latency) { | 210 const ui::LatencyInfo& latency) { |
214 switch (event->sourceDevice) { | 211 switch (event->sourceDevice) { |
215 case blink::WebGestureDeviceUninitialized: | 212 case blink::WebGestureDeviceUninitialized: |
216 NOTREACHED() << "Uninitialized device type is not allowed"; | 213 NOTREACHED() << "Uninitialized device type is not allowed"; |
217 break; | 214 break; |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 // difficult to resolve until this is changed to do all scroll targeting, | 434 // difficult to resolve until this is changed to do all scroll targeting, |
438 // including bubbling, based on GestureScrollBegin. | 435 // including bubbling, based on GestureScrollBegin. |
439 DCHECK(target_view); | 436 DCHECK(target_view); |
440 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || | 437 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || |
441 event.type == blink::WebInputEvent::GestureScrollEnd); | 438 event.type == blink::WebInputEvent::GestureScrollEnd); |
442 // DCHECK_XNOR the current and original bubble targets. Both should be set | 439 // DCHECK_XNOR the current and original bubble targets. Both should be set |
443 // if a bubbling gesture scroll is in progress. | 440 // if a bubbling gesture scroll is in progress. |
444 DCHECK(!first_bubbling_scroll_target_.target == | 441 DCHECK(!first_bubbling_scroll_target_.target == |
445 !bubbling_gesture_scroll_target_.target); | 442 !bubbling_gesture_scroll_target_.target); |
446 | 443 |
| 444 ui::LatencyInfo latency_info = |
| 445 ui::WebInputEventTraits::CreateLatencyInfoForWebGestureEvent(event); |
| 446 |
447 // If target_view is already set up for bubbled scrolls, we forward | 447 // If target_view is already set up for bubbled scrolls, we forward |
448 // the event to the current scroll target without further consideration. | 448 // the event to the current scroll target without further consideration. |
449 if (target_view == first_bubbling_scroll_target_.target) { | 449 if (target_view == first_bubbling_scroll_target_.target) { |
450 bubbling_gesture_scroll_target_.target->ProcessGestureEvent( | 450 bubbling_gesture_scroll_target_.target->ProcessGestureEvent(event, |
451 event, ui::LatencyInfo()); | 451 latency_info); |
452 if (event.type == blink::WebInputEvent::GestureScrollEnd) { | 452 if (event.type == blink::WebInputEvent::GestureScrollEnd) { |
453 first_bubbling_scroll_target_.target = nullptr; | 453 first_bubbling_scroll_target_.target = nullptr; |
454 bubbling_gesture_scroll_target_.target = nullptr; | 454 bubbling_gesture_scroll_target_.target = nullptr; |
455 } | 455 } |
456 return; | 456 return; |
457 } | 457 } |
458 | 458 |
459 // Disregard GestureScrollEnd events going to non-current targets. | 459 // Disregard GestureScrollEnd events going to non-current targets. |
460 // These should only happen on ACKs of synthesized GSE events that are | 460 // These should only happen on ACKs of synthesized GSE events that are |
461 // sent from SendGestureScrollEnd calls, and are not relevant here. | 461 // sent from SendGestureScrollEnd calls, and are not relevant here. |
462 if (event.type == blink::WebInputEvent::GestureScrollEnd) | 462 if (event.type == blink::WebInputEvent::GestureScrollEnd) |
463 return; | 463 return; |
464 | 464 |
465 // This is a special case to catch races where multiple GestureScrollUpdates | 465 // This is a special case to catch races where multiple GestureScrollUpdates |
466 // have been sent to a renderer before the first one was ACKed, and the ACK | 466 // have been sent to a renderer before the first one was ACKed, and the ACK |
467 // caused a bubble retarget. In this case they all get forwarded. | 467 // caused a bubble retarget. In this case they all get forwarded. |
468 if (target_view == bubbling_gesture_scroll_target_.target) { | 468 if (target_view == bubbling_gesture_scroll_target_.target) { |
469 bubbling_gesture_scroll_target_.target->ProcessGestureEvent( | 469 bubbling_gesture_scroll_target_.target->ProcessGestureEvent(event, |
470 event, ui::LatencyInfo()); | 470 latency_info); |
471 return; | 471 return; |
472 } | 472 } |
473 | 473 |
474 // If target_view has unrelated gesture events in progress, do | 474 // If target_view has unrelated gesture events in progress, do |
475 // not proceed. This could cause confusion between independent | 475 // not proceed. This could cause confusion between independent |
476 // scrolls. | 476 // scrolls. |
477 if (target_view == touchscreen_gesture_target_.target || | 477 if (target_view == touchscreen_gesture_target_.target || |
478 target_view == touchpad_gesture_target_.target || | 478 target_view == touchpad_gesture_target_.target || |
479 target_view == touch_target_.target) | 479 target_view == touch_target_.target) |
480 return; | 480 return; |
481 | 481 |
482 // This accounts for bubbling through nested OOPIFs. A gesture scroll has | 482 // This accounts for bubbling through nested OOPIFs. A gesture scroll has |
483 // been bubbled but the target has sent back a gesture scroll event ack with | 483 // been bubbled but the target has sent back a gesture scroll event ack with |
484 // unused scroll delta, and so another level of bubbling is needed. This | 484 // unused scroll delta, and so another level of bubbling is needed. This |
485 // requires a GestureScrollEnd be sent to the last view, which will no | 485 // requires a GestureScrollEnd be sent to the last view, which will no |
486 // longer be the scroll target. | 486 // longer be the scroll target. |
487 if (bubbling_gesture_scroll_target_.target) | 487 if (bubbling_gesture_scroll_target_.target) |
488 SendGestureScrollEnd(bubbling_gesture_scroll_target_.target, event); | 488 SendGestureScrollEnd(bubbling_gesture_scroll_target_.target, event); |
489 else | 489 else |
490 first_bubbling_scroll_target_.target = target_view; | 490 first_bubbling_scroll_target_.target = target_view; |
491 | 491 |
492 bubbling_gesture_scroll_target_.target = target_view; | 492 bubbling_gesture_scroll_target_.target = target_view; |
493 | 493 |
494 SendGestureScrollBegin(target_view, event); | 494 SendGestureScrollBegin(target_view, event); |
495 target_view->ProcessGestureEvent(event, ui::LatencyInfo()); | 495 target_view->ProcessGestureEvent(event, latency_info); |
496 } | 496 } |
497 | 497 |
498 void RenderWidgetHostInputEventRouter::SendGestureScrollBegin( | 498 void RenderWidgetHostInputEventRouter::SendGestureScrollBegin( |
499 RenderWidgetHostViewBase* view, | 499 RenderWidgetHostViewBase* view, |
500 const blink::WebGestureEvent& event) { | 500 const blink::WebGestureEvent& event) { |
501 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || | 501 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || |
502 event.type == blink::WebInputEvent::GesturePinchBegin); | 502 event.type == blink::WebInputEvent::GesturePinchBegin); |
503 blink::WebGestureEvent scroll_begin(event); | 503 blink::WebGestureEvent scroll_begin(event); |
504 scroll_begin.type = blink::WebInputEvent::GestureScrollBegin; | 504 scroll_begin.type = blink::WebInputEvent::GestureScrollBegin; |
505 scroll_begin.data.scrollBegin.deltaXHint = event.data.scrollUpdate.deltaX; | 505 scroll_begin.data.scrollBegin.deltaXHint = event.data.scrollUpdate.deltaX; |
506 scroll_begin.data.scrollBegin.deltaYHint = event.data.scrollUpdate.deltaY; | 506 scroll_begin.data.scrollBegin.deltaYHint = event.data.scrollUpdate.deltaY; |
507 scroll_begin.data.scrollBegin.deltaHintUnits = | 507 scroll_begin.data.scrollBegin.deltaHintUnits = |
508 event.data.scrollUpdate.deltaUnits; | 508 event.data.scrollUpdate.deltaUnits; |
509 view->ProcessGestureEvent(scroll_begin, ui::LatencyInfo()); | 509 view->ProcessGestureEvent( |
| 510 scroll_begin, |
| 511 ui::WebInputEventTraits::CreateLatencyInfoForWebGestureEvent(event)); |
510 } | 512 } |
511 | 513 |
512 void RenderWidgetHostInputEventRouter::SendGestureScrollEnd( | 514 void RenderWidgetHostInputEventRouter::SendGestureScrollEnd( |
513 RenderWidgetHostViewBase* view, | 515 RenderWidgetHostViewBase* view, |
514 const blink::WebGestureEvent& event) { | 516 const blink::WebGestureEvent& event) { |
515 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || | 517 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || |
516 event.type == blink::WebInputEvent::GesturePinchEnd); | 518 event.type == blink::WebInputEvent::GesturePinchEnd); |
517 blink::WebGestureEvent scroll_end(event); | 519 blink::WebGestureEvent scroll_end(event); |
518 scroll_end.type = blink::WebInputEvent::GestureScrollEnd; | 520 scroll_end.type = blink::WebInputEvent::GestureScrollEnd; |
519 scroll_end.timeStampSeconds = | 521 scroll_end.timeStampSeconds = |
520 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); | 522 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); |
521 scroll_end.data.scrollEnd.inertialPhase = | 523 scroll_end.data.scrollEnd.inertialPhase = |
522 event.data.scrollUpdate.inertialPhase; | 524 event.data.scrollUpdate.inertialPhase; |
523 scroll_end.data.scrollEnd.deltaUnits = event.data.scrollUpdate.deltaUnits; | 525 scroll_end.data.scrollEnd.deltaUnits = event.data.scrollUpdate.deltaUnits; |
524 view->ProcessGestureEvent(scroll_end, ui::LatencyInfo()); | 526 view->ProcessGestureEvent( |
| 527 scroll_end, |
| 528 ui::WebInputEventTraits::CreateLatencyInfoForWebGestureEvent(event)); |
525 } | 529 } |
526 | 530 |
527 void RenderWidgetHostInputEventRouter::CancelScrollBubbling( | 531 void RenderWidgetHostInputEventRouter::CancelScrollBubbling( |
528 RenderWidgetHostViewBase* target_view) { | 532 RenderWidgetHostViewBase* target_view) { |
529 DCHECK(target_view); | 533 DCHECK(target_view); |
530 if (target_view == first_bubbling_scroll_target_.target) { | 534 if (target_view == first_bubbling_scroll_target_.target) { |
531 first_bubbling_scroll_target_.target = nullptr; | 535 first_bubbling_scroll_target_.target = nullptr; |
532 bubbling_gesture_scroll_target_.target = nullptr; | 536 bubbling_gesture_scroll_target_.target = nullptr; |
533 } | 537 } |
534 } | 538 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 if (!touchpad_gesture_target_.target) | 689 if (!touchpad_gesture_target_.target) |
686 return; | 690 return; |
687 | 691 |
688 // TODO(mohsen): Add tests to check event location. | 692 // TODO(mohsen): Add tests to check event location. |
689 event->x += touchpad_gesture_target_.delta.x(); | 693 event->x += touchpad_gesture_target_.delta.x(); |
690 event->y += touchpad_gesture_target_.delta.y(); | 694 event->y += touchpad_gesture_target_.delta.y(); |
691 touchpad_gesture_target_.target->ProcessGestureEvent(*event, latency); | 695 touchpad_gesture_target_.target->ProcessGestureEvent(*event, latency); |
692 } | 696 } |
693 | 697 |
694 } // namespace content | 698 } // namespace content |
OLD | NEW |