| 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" | |
| 20 | 19 |
| 21 namespace { | 20 namespace { |
| 22 | 21 |
| 23 void TransformEventTouchPositions(blink::WebTouchEvent* event, | 22 void TransformEventTouchPositions(blink::WebTouchEvent* event, |
| 24 const gfx::Vector2d& delta) { | 23 const gfx::Vector2d& delta) { |
| 25 for (unsigned i = 0; i < event->touchesLength; ++i) { | 24 for (unsigned i = 0; i < event->touchesLength; ++i) { |
| 26 event->touches[i].position.x += delta.x(); | 25 event->touches[i].position.x += delta.x(); |
| 27 event->touches[i].position.y += delta.y(); | 26 event->touches[i].position.y += delta.y(); |
| 28 } | 27 } |
| 29 } | 28 } |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 // it likely means the RenderWidgetHostView has been destroyed but its | 162 // it likely means the RenderWidgetHostView has been destroyed but its |
| 164 // parent frame has not sent a new compositor frame since that happened. | 163 // parent frame has not sent a new compositor frame since that happened. |
| 165 if (iter == owner_map_.end()) | 164 if (iter == owner_map_.end()) |
| 166 return root_view; | 165 return root_view; |
| 167 | 166 |
| 168 return iter->second; | 167 return iter->second; |
| 169 } | 168 } |
| 170 | 169 |
| 171 void RenderWidgetHostInputEventRouter::RouteMouseEvent( | 170 void RenderWidgetHostInputEventRouter::RouteMouseEvent( |
| 172 RenderWidgetHostViewBase* root_view, | 171 RenderWidgetHostViewBase* root_view, |
| 173 blink::WebMouseEvent* event, | 172 blink::WebMouseEvent* event) { |
| 174 const ui::LatencyInfo& latency) { | |
| 175 RenderWidgetHostViewBase* target; | 173 RenderWidgetHostViewBase* target; |
| 176 gfx::Point transformed_point; | 174 gfx::Point transformed_point; |
| 177 const int mouse_button_modifiers = blink::WebInputEvent::LeftButtonDown | | 175 const int mouse_button_modifiers = blink::WebInputEvent::LeftButtonDown | |
| 178 blink::WebInputEvent::MiddleButtonDown | | 176 blink::WebInputEvent::MiddleButtonDown | |
| 179 blink::WebInputEvent::RightButtonDown; | 177 blink::WebInputEvent::RightButtonDown; |
| 180 if (mouse_capture_target_.target && | 178 if (mouse_capture_target_.target && |
| 181 event->type != blink::WebInputEvent::MouseDown && | 179 event->type != blink::WebInputEvent::MouseDown && |
| 182 (event->type == blink::WebInputEvent::MouseUp || | 180 (event->type == blink::WebInputEvent::MouseUp || |
| 183 event->modifiers & mouse_button_modifiers)) { | 181 event->modifiers & mouse_button_modifiers)) { |
| 184 target = mouse_capture_target_.target; | 182 target = mouse_capture_target_.target; |
| 185 transformed_point = root_view->TransformPointToCoordSpaceForView( | 183 transformed_point = root_view->TransformPointToCoordSpaceForView( |
| 186 gfx::Point(event->x, event->y), target); | 184 gfx::Point(event->x, event->y), target); |
| 187 if (event->type == blink::WebInputEvent::MouseUp) | 185 if (event->type == blink::WebInputEvent::MouseUp) |
| 188 mouse_capture_target_.target = nullptr; | 186 mouse_capture_target_.target = nullptr; |
| 189 } else { | 187 } else { |
| 190 target = FindEventTarget(root_view, gfx::Point(event->x, event->y), | 188 target = FindEventTarget(root_view, gfx::Point(event->x, event->y), |
| 191 &transformed_point); | 189 &transformed_point); |
| 192 } | 190 } |
| 193 | 191 |
| 194 // RenderWidgetHostViewGuest does not properly handle direct routing of mouse | 192 // RenderWidgetHostViewGuest does not properly handle direct routing of mouse |
| 195 // events, so they have to go by the double-hop forwarding path through | 193 // events, so they have to go by the double-hop forwarding path through |
| 196 // the embedding renderer and then BrowserPluginGuest. | 194 // the embedding renderer and then BrowserPluginGuest. |
| 197 if (target && target->IsRenderWidgetHostViewGuest()) { | 195 if (target && target->IsRenderWidgetHostViewGuest()) { |
| 198 root_view->ProcessMouseEvent(*event, latency); | 196 ui::LatencyInfo latency_info; |
| 197 root_view->ProcessMouseEvent(*event, latency_info); |
| 199 return; | 198 return; |
| 200 } | 199 } |
| 201 | 200 |
| 202 if (event->type == blink::WebInputEvent::MouseDown) | 201 if (event->type == blink::WebInputEvent::MouseDown) |
| 203 mouse_capture_target_.target = target; | 202 mouse_capture_target_.target = target; |
| 204 | 203 |
| 205 if (!target) | 204 if (!target) |
| 206 return; | 205 return; |
| 207 | 206 |
| 208 // SendMouseEnterOrLeaveEvents is called with the original event | 207 // SendMouseEnterOrLeaveEvents is called with the original event |
| 209 // coordinates, which are transformed independently for each view that will | 208 // coordinates, which are transformed independently for each view that will |
| 210 // receive an event. | 209 // receive an event. |
| 211 if ((event->type == blink::WebInputEvent::MouseLeave || | 210 if ((event->type == blink::WebInputEvent::MouseLeave || |
| 212 event->type == blink::WebInputEvent::MouseMove) && | 211 event->type == blink::WebInputEvent::MouseMove) && |
| 213 target != last_mouse_move_target_) | 212 target != last_mouse_move_target_) |
| 214 SendMouseEnterOrLeaveEvents(event, target, root_view); | 213 SendMouseEnterOrLeaveEvents(event, target, root_view); |
| 215 | 214 |
| 216 event->x = transformed_point.x(); | 215 event->x = transformed_point.x(); |
| 217 event->y = transformed_point.y(); | 216 event->y = transformed_point.y(); |
| 218 target->ProcessMouseEvent(*event, latency); | 217 // TODO(wjmaclean): Initialize latency info correctly for OOPIFs. |
| 218 // https://crbug.com/613628 |
| 219 ui::LatencyInfo latency_info; |
| 220 target->ProcessMouseEvent(*event, latency_info); |
| 219 } | 221 } |
| 220 | 222 |
| 221 void RenderWidgetHostInputEventRouter::RouteMouseWheelEvent( | 223 void RenderWidgetHostInputEventRouter::RouteMouseWheelEvent( |
| 222 RenderWidgetHostViewBase* root_view, | 224 RenderWidgetHostViewBase* root_view, |
| 223 blink::WebMouseWheelEvent* event, | 225 blink::WebMouseWheelEvent* event) { |
| 224 const ui::LatencyInfo& latency) { | |
| 225 gfx::Point transformed_point; | 226 gfx::Point transformed_point; |
| 226 RenderWidgetHostViewBase* target = FindEventTarget( | 227 RenderWidgetHostViewBase* target = FindEventTarget( |
| 227 root_view, gfx::Point(event->x, event->y), &transformed_point); | 228 root_view, gfx::Point(event->x, event->y), &transformed_point); |
| 228 if (!target) | 229 if (!target) |
| 229 return; | 230 return; |
| 230 | 231 |
| 231 event->x = transformed_point.x(); | 232 event->x = transformed_point.x(); |
| 232 event->y = transformed_point.y(); | 233 event->y = transformed_point.y(); |
| 233 target->ProcessMouseWheelEvent(*event, latency); | 234 // TODO(wjmaclean): Initialize latency info correctly for OOPIFs. |
| 235 // https://crbug.com/613628 |
| 236 ui::LatencyInfo latency_info; |
| 237 target->ProcessMouseWheelEvent(*event, latency_info); |
| 234 } | 238 } |
| 235 | 239 |
| 236 void RenderWidgetHostInputEventRouter::RouteGestureEvent( | 240 void RenderWidgetHostInputEventRouter::RouteGestureEvent( |
| 237 RenderWidgetHostViewBase* root_view, | 241 RenderWidgetHostViewBase* root_view, |
| 238 blink::WebGestureEvent* event, | 242 blink::WebGestureEvent* event, |
| 239 const ui::LatencyInfo& latency) { | 243 const ui::LatencyInfo& latency) { |
| 240 switch (event->sourceDevice) { | 244 switch (event->sourceDevice) { |
| 241 case blink::WebGestureDeviceUninitialized: | 245 case blink::WebGestureDeviceUninitialized: |
| 242 NOTREACHED() << "Uninitialized device type is not allowed"; | 246 NOTREACHED() << "Uninitialized device type is not allowed"; |
| 243 break; | 247 break; |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 // difficult to resolve until this is changed to do all scroll targeting, | 467 // difficult to resolve until this is changed to do all scroll targeting, |
| 464 // including bubbling, based on GestureScrollBegin. | 468 // including bubbling, based on GestureScrollBegin. |
| 465 DCHECK(target_view); | 469 DCHECK(target_view); |
| 466 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || | 470 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || |
| 467 event.type == blink::WebInputEvent::GestureScrollEnd); | 471 event.type == blink::WebInputEvent::GestureScrollEnd); |
| 468 // DCHECK_XNOR the current and original bubble targets. Both should be set | 472 // DCHECK_XNOR the current and original bubble targets. Both should be set |
| 469 // if a bubbling gesture scroll is in progress. | 473 // if a bubbling gesture scroll is in progress. |
| 470 DCHECK(!first_bubbling_scroll_target_.target == | 474 DCHECK(!first_bubbling_scroll_target_.target == |
| 471 !bubbling_gesture_scroll_target_.target); | 475 !bubbling_gesture_scroll_target_.target); |
| 472 | 476 |
| 473 ui::LatencyInfo latency_info = | |
| 474 ui::WebInputEventTraits::CreateLatencyInfoForWebGestureEvent(event); | |
| 475 | |
| 476 // If target_view is already set up for bubbled scrolls, we forward | 477 // If target_view is already set up for bubbled scrolls, we forward |
| 477 // the event to the current scroll target without further consideration. | 478 // the event to the current scroll target without further consideration. |
| 478 if (target_view == first_bubbling_scroll_target_.target) { | 479 if (target_view == first_bubbling_scroll_target_.target) { |
| 479 bubbling_gesture_scroll_target_.target->ProcessGestureEvent(event, | 480 bubbling_gesture_scroll_target_.target->ProcessGestureEvent( |
| 480 latency_info); | 481 event, ui::LatencyInfo()); |
| 481 if (event.type == blink::WebInputEvent::GestureScrollEnd) { | 482 if (event.type == blink::WebInputEvent::GestureScrollEnd) { |
| 482 first_bubbling_scroll_target_.target = nullptr; | 483 first_bubbling_scroll_target_.target = nullptr; |
| 483 bubbling_gesture_scroll_target_.target = nullptr; | 484 bubbling_gesture_scroll_target_.target = nullptr; |
| 484 } | 485 } |
| 485 return; | 486 return; |
| 486 } | 487 } |
| 487 | 488 |
| 488 // Disregard GestureScrollEnd events going to non-current targets. | 489 // Disregard GestureScrollEnd events going to non-current targets. |
| 489 // These should only happen on ACKs of synthesized GSE events that are | 490 // These should only happen on ACKs of synthesized GSE events that are |
| 490 // sent from SendGestureScrollEnd calls, and are not relevant here. | 491 // sent from SendGestureScrollEnd calls, and are not relevant here. |
| 491 if (event.type == blink::WebInputEvent::GestureScrollEnd) | 492 if (event.type == blink::WebInputEvent::GestureScrollEnd) |
| 492 return; | 493 return; |
| 493 | 494 |
| 494 // This is a special case to catch races where multiple GestureScrollUpdates | 495 // This is a special case to catch races where multiple GestureScrollUpdates |
| 495 // have been sent to a renderer before the first one was ACKed, and the ACK | 496 // have been sent to a renderer before the first one was ACKed, and the ACK |
| 496 // caused a bubble retarget. In this case they all get forwarded. | 497 // caused a bubble retarget. In this case they all get forwarded. |
| 497 if (target_view == bubbling_gesture_scroll_target_.target) { | 498 if (target_view == bubbling_gesture_scroll_target_.target) { |
| 498 bubbling_gesture_scroll_target_.target->ProcessGestureEvent(event, | 499 bubbling_gesture_scroll_target_.target->ProcessGestureEvent( |
| 499 latency_info); | 500 event, ui::LatencyInfo()); |
| 500 return; | 501 return; |
| 501 } | 502 } |
| 502 | 503 |
| 503 // If target_view has unrelated gesture events in progress, do | 504 // If target_view has unrelated gesture events in progress, do |
| 504 // not proceed. This could cause confusion between independent | 505 // not proceed. This could cause confusion between independent |
| 505 // scrolls. | 506 // scrolls. |
| 506 if (target_view == touchscreen_gesture_target_.target || | 507 if (target_view == touchscreen_gesture_target_.target || |
| 507 target_view == touchpad_gesture_target_.target || | 508 target_view == touchpad_gesture_target_.target || |
| 508 target_view == touch_target_.target) | 509 target_view == touch_target_.target) |
| 509 return; | 510 return; |
| 510 | 511 |
| 511 // This accounts for bubbling through nested OOPIFs. A gesture scroll has | 512 // This accounts for bubbling through nested OOPIFs. A gesture scroll has |
| 512 // been bubbled but the target has sent back a gesture scroll event ack with | 513 // been bubbled but the target has sent back a gesture scroll event ack with |
| 513 // unused scroll delta, and so another level of bubbling is needed. This | 514 // unused scroll delta, and so another level of bubbling is needed. This |
| 514 // requires a GestureScrollEnd be sent to the last view, which will no | 515 // requires a GestureScrollEnd be sent to the last view, which will no |
| 515 // longer be the scroll target. | 516 // longer be the scroll target. |
| 516 if (bubbling_gesture_scroll_target_.target) | 517 if (bubbling_gesture_scroll_target_.target) |
| 517 SendGestureScrollEnd(bubbling_gesture_scroll_target_.target, event); | 518 SendGestureScrollEnd(bubbling_gesture_scroll_target_.target, event); |
| 518 else | 519 else |
| 519 first_bubbling_scroll_target_.target = target_view; | 520 first_bubbling_scroll_target_.target = target_view; |
| 520 | 521 |
| 521 bubbling_gesture_scroll_target_.target = target_view; | 522 bubbling_gesture_scroll_target_.target = target_view; |
| 522 | 523 |
| 523 SendGestureScrollBegin(target_view, event); | 524 SendGestureScrollBegin(target_view, event); |
| 524 target_view->ProcessGestureEvent(event, latency_info); | 525 target_view->ProcessGestureEvent(event, ui::LatencyInfo()); |
| 525 } | 526 } |
| 526 | 527 |
| 527 void RenderWidgetHostInputEventRouter::SendGestureScrollBegin( | 528 void RenderWidgetHostInputEventRouter::SendGestureScrollBegin( |
| 528 RenderWidgetHostViewBase* view, | 529 RenderWidgetHostViewBase* view, |
| 529 const blink::WebGestureEvent& event) { | 530 const blink::WebGestureEvent& event) { |
| 530 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || | 531 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || |
| 531 event.type == blink::WebInputEvent::GesturePinchBegin); | 532 event.type == blink::WebInputEvent::GesturePinchBegin); |
| 532 blink::WebGestureEvent scroll_begin(event); | 533 blink::WebGestureEvent scroll_begin(event); |
| 533 scroll_begin.type = blink::WebInputEvent::GestureScrollBegin; | 534 scroll_begin.type = blink::WebInputEvent::GestureScrollBegin; |
| 534 scroll_begin.data.scrollBegin.deltaXHint = event.data.scrollUpdate.deltaX; | 535 scroll_begin.data.scrollBegin.deltaXHint = event.data.scrollUpdate.deltaX; |
| 535 scroll_begin.data.scrollBegin.deltaYHint = event.data.scrollUpdate.deltaY; | 536 scroll_begin.data.scrollBegin.deltaYHint = event.data.scrollUpdate.deltaY; |
| 536 scroll_begin.data.scrollBegin.deltaHintUnits = | 537 scroll_begin.data.scrollBegin.deltaHintUnits = |
| 537 event.data.scrollUpdate.deltaUnits; | 538 event.data.scrollUpdate.deltaUnits; |
| 538 view->ProcessGestureEvent( | 539 view->ProcessGestureEvent(scroll_begin, ui::LatencyInfo()); |
| 539 scroll_begin, | |
| 540 ui::WebInputEventTraits::CreateLatencyInfoForWebGestureEvent(event)); | |
| 541 } | 540 } |
| 542 | 541 |
| 543 void RenderWidgetHostInputEventRouter::SendGestureScrollEnd( | 542 void RenderWidgetHostInputEventRouter::SendGestureScrollEnd( |
| 544 RenderWidgetHostViewBase* view, | 543 RenderWidgetHostViewBase* view, |
| 545 const blink::WebGestureEvent& event) { | 544 const blink::WebGestureEvent& event) { |
| 546 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || | 545 DCHECK(event.type == blink::WebInputEvent::GestureScrollUpdate || |
| 547 event.type == blink::WebInputEvent::GesturePinchEnd); | 546 event.type == blink::WebInputEvent::GesturePinchEnd); |
| 548 blink::WebGestureEvent scroll_end(event); | 547 blink::WebGestureEvent scroll_end(event); |
| 549 scroll_end.type = blink::WebInputEvent::GestureScrollEnd; | 548 scroll_end.type = blink::WebInputEvent::GestureScrollEnd; |
| 550 scroll_end.timeStampSeconds = | 549 scroll_end.timeStampSeconds = |
| 551 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); | 550 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); |
| 552 scroll_end.data.scrollEnd.inertialPhase = | 551 scroll_end.data.scrollEnd.inertialPhase = |
| 553 event.data.scrollUpdate.inertialPhase; | 552 event.data.scrollUpdate.inertialPhase; |
| 554 scroll_end.data.scrollEnd.deltaUnits = event.data.scrollUpdate.deltaUnits; | 553 scroll_end.data.scrollEnd.deltaUnits = event.data.scrollUpdate.deltaUnits; |
| 555 view->ProcessGestureEvent( | 554 view->ProcessGestureEvent(scroll_end, ui::LatencyInfo()); |
| 556 scroll_end, | |
| 557 ui::WebInputEventTraits::CreateLatencyInfoForWebGestureEvent(event)); | |
| 558 } | 555 } |
| 559 | 556 |
| 560 void RenderWidgetHostInputEventRouter::CancelScrollBubbling( | 557 void RenderWidgetHostInputEventRouter::CancelScrollBubbling( |
| 561 RenderWidgetHostViewBase* target_view) { | 558 RenderWidgetHostViewBase* target_view) { |
| 562 DCHECK(target_view); | 559 DCHECK(target_view); |
| 563 if (target_view == first_bubbling_scroll_target_.target) { | 560 if (target_view == first_bubbling_scroll_target_.target) { |
| 564 first_bubbling_scroll_target_.target = nullptr; | 561 first_bubbling_scroll_target_.target = nullptr; |
| 565 bubbling_gesture_scroll_target_.target = nullptr; | 562 bubbling_gesture_scroll_target_.target = nullptr; |
| 566 } | 563 } |
| 567 } | 564 } |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 if (!touchpad_gesture_target_.target) | 726 if (!touchpad_gesture_target_.target) |
| 730 return; | 727 return; |
| 731 | 728 |
| 732 // TODO(mohsen): Add tests to check event location. | 729 // TODO(mohsen): Add tests to check event location. |
| 733 event->x += touchpad_gesture_target_.delta.x(); | 730 event->x += touchpad_gesture_target_.delta.x(); |
| 734 event->y += touchpad_gesture_target_.delta.y(); | 731 event->y += touchpad_gesture_target_.delta.y(); |
| 735 touchpad_gesture_target_.target->ProcessGestureEvent(*event, latency); | 732 touchpad_gesture_target_.target->ProcessGestureEvent(*event, latency); |
| 736 } | 733 } |
| 737 | 734 |
| 738 } // namespace content | 735 } // namespace content |
| OLD | NEW |