Chromium Code Reviews| Index: content/browser/renderer_host/render_widget_host_view_aura.cc |
| diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc |
| index 5b865e88dcf78a692cd651c0d7fd3920ace0b533..f575c14c7df9fb61ff36833906ed76a4d8abd49d 100644 |
| --- a/content/browser/renderer_host/render_widget_host_view_aura.cc |
| +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc |
| @@ -41,6 +41,7 @@ |
| #include "content/browser/renderer_host/render_widget_host_delegate.h" |
| #include "content/browser/renderer_host/render_widget_host_impl.h" |
| #include "content/browser/renderer_host/render_widget_host_input_event_router.h" |
| +#include "content/browser/renderer_host/render_widget_host_view_event_handler.h" |
| #include "content/browser/renderer_host/ui_events_helper.h" |
| #include "content/common/content_switches_internal.h" |
| #include "content/common/input_messages.h" |
| @@ -122,15 +123,6 @@ namespace content { |
| namespace { |
| -// In mouse lock mode, we need to prevent the (invisible) cursor from hitting |
| -// the border of the view, in order to get valid movement information. However, |
| -// forcing the cursor back to the center of the view after each mouse move |
| -// doesn't work well. It reduces the frequency of useful mouse move messages |
| -// significantly. Therefore, we move the cursor to the center of the view only |
| -// if it approaches the border. |kMouseLockBorderPercentage| specifies the width |
| -// of the border area, in percentage of the corresponding dimension. |
| -const int kMouseLockBorderPercentage = 15; |
| - |
| // When accelerated compositing is enabled and a widget resize is pending, |
| // we delay further resizes of the UI. The following constant is the maximum |
| // length of time that we should delay further UI resizes while waiting for a |
| @@ -138,67 +130,7 @@ const int kMouseLockBorderPercentage = 15; |
| const int kResizeLockTimeoutMs = 67; |
| #if defined(OS_WIN) |
| -// A callback function for EnumThreadWindows to enumerate and dismiss |
| -// any owned popup windows. |
| -BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) { |
| - const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg); |
| - |
| - if (::IsWindowVisible(window)) { |
| - const HWND owner = ::GetWindow(window, GW_OWNER); |
| - if (toplevel_hwnd == owner) { |
| - ::PostMessage(window, WM_CANCELMODE, 0, 0); |
| - } |
| - } |
| - |
| - return TRUE; |
| -} |
| -#endif |
| -// We don't mark these as handled so that they're sent back to the |
| -// DefWindowProc so it can generate WM_APPCOMMAND as necessary. |
| -bool IsXButtonUpEvent(const ui::MouseEvent* event) { |
| -#if defined(OS_WIN) |
| - switch (event->native_event().message) { |
| - case WM_XBUTTONUP: |
| - case WM_NCXBUTTONUP: |
| - return true; |
| - } |
| -#endif |
| - return false; |
| -} |
| - |
| -bool IsFractionalScaleFactor(float scale_factor) { |
| - return (scale_factor - static_cast<int>(scale_factor)) > 0; |
| -} |
| - |
| -// Reset unchanged touch point to StateStationary for touchmove and |
| -// touchcancel. |
| -void MarkUnchangedTouchPointsAsStationary( |
| - blink::WebTouchEvent* event, |
| - int changed_touch_id) { |
| - if (event->type == blink::WebInputEvent::TouchMove || |
| - event->type == blink::WebInputEvent::TouchCancel) { |
| - for (size_t i = 0; i < event->touchesLength; ++i) { |
| - if (event->touches[i].id != changed_touch_id) |
| - event->touches[i].state = blink::WebTouchPoint::StateStationary; |
| - } |
| - } |
| -} |
| - |
| -gfx::Point GetScreenLocationFromEvent(const ui::LocatedEvent& event) { |
| - aura::Window* root = |
| - static_cast<aura::Window*>(event.target())->GetRootWindow(); |
| - aura::client::ScreenPositionClient* spc = |
| - aura::client::GetScreenPositionClient(root); |
| - if (!spc) |
| - return event.root_location(); |
| - |
| - gfx::Point screen_location(event.root_location()); |
| - spc->ConvertPointToScreen(root, &screen_location); |
| - return screen_location; |
| -} |
| - |
| -#if defined(OS_WIN) |
| // This class implements the ui::OnScreenKeyboardObserver interface |
| // which provides notifications about the on screen keyboard on Windows getting |
| // displayed or hidden in response to taps on editable fields. |
| @@ -277,7 +209,7 @@ class WinScreenKeyboardObserver : public ui::OnScreenKeyboardObserver { |
| DISALLOW_COPY_AND_ASSIGN(WinScreenKeyboardObserver); |
| }; |
| -#endif |
| +#endif // defined(OS_WIN) |
| } // namespace |
| @@ -331,7 +263,8 @@ void RenderWidgetHostViewAura::ApplyEventFilterForPopupExit( |
| // notification. We also set a flag in the view indicating that we need |
| // to force a Focus notification on the next mouse down. |
| if (popup_parent_host_view_ && popup_parent_host_view_->host_) { |
| - popup_parent_host_view_->set_focus_on_mouse_down_or_key_event_ = true; |
| + popup_parent_host_view_->event_handler() |
| + ->set_focus_on_mouse_down_or_key_event(true); |
| popup_parent_host_view_->host_->Blur(); |
| } |
| // Note: popup_parent_host_view_ may be NULL when there are multiple |
| @@ -438,9 +371,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host, |
| popup_child_host_view_(nullptr), |
| is_loading_(false), |
| has_composition_text_(false), |
| - accept_return_character_(false), |
| begin_frame_source_(nullptr), |
| - synthetic_move_sent_(false), |
| cursor_visibility_state_in_renderer_(UNKNOWN), |
| #if defined(OS_WIN) |
| legacy_render_widget_host_HWND_(nullptr), |
| @@ -449,11 +380,10 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host, |
| #endif |
| has_snapped_to_boundary_(false), |
| is_guest_view_hack_(is_guest_view_hack), |
| - set_focus_on_mouse_down_or_key_event_(false), |
| device_scale_factor_(0.0f), |
| - disable_input_event_router_for_testing_(false), |
| last_active_widget_process_id_(ChildProcessHost::kInvalidUniqueID), |
| last_active_widget_routing_id_(MSG_ROUTING_NONE), |
| + event_handler_(new RenderWidgetHostViewEventHandler(host_, this)), |
| weak_ptr_factory_(this) { |
| if (!is_guest_view_hack_) |
| host_->SetView(this); |
| @@ -528,7 +458,7 @@ void RenderWidgetHostViewAura::InitAsPopup( |
| } |
| old_child->popup_parent_host_view_ = NULL; |
| } |
| - popup_parent_host_view_->popup_child_host_view_ = this; |
| + popup_parent_host_view_->SetPopupChildHostView(this); |
| window_->SetType(ui::wm::WINDOW_TYPE_MENU); |
| window_->Init(ui::LAYER_SOLID_COLOR); |
| window_->SetName("RenderWidgetHostViewAura"); |
| @@ -573,10 +503,7 @@ void RenderWidgetHostViewAura::InitAsFullscreen( |
| if (reference_host_view) { |
| aura::Window* reference_window = |
| static_cast<RenderWidgetHostViewAura*>(reference_host_view)->window_; |
| - if (reference_window) { |
| - host_tracker_.reset(new aura::WindowTracker); |
| - host_tracker_->Add(reference_window); |
| - } |
| + event_handler_->TrackHost(reference_window); |
| display::Display display = |
| display::Screen::GetScreen()->GetDisplayNearestWindow(reference_window); |
| parent = reference_window->GetRootWindow(); |
| @@ -736,24 +663,6 @@ void RenderWidgetHostViewAura::OnBeginFrameSourcePausedChanged(bool paused) { |
| // Only used on Android WebView. |
| } |
| -void RenderWidgetHostViewAura::SetKeyboardFocus() { |
| -#if defined(OS_WIN) |
| - if (CanFocus()) { |
| - aura::WindowTreeHost* host = window_->GetHost(); |
| - if (host) { |
| - gfx::AcceleratedWidget hwnd = host->GetAcceleratedWidget(); |
| - if (!(::GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_NOACTIVATE)) |
| - ::SetFocus(hwnd); |
| - } |
| - } |
| -#endif |
| - // TODO(wjmaclean): can host_ ever be null? |
| - if (host_ && set_focus_on_mouse_down_or_key_event_) { |
| - set_focus_on_mouse_down_or_key_event_ = false; |
| - host_->Focus(); |
| - } |
| -} |
| - |
| RenderFrameHostImpl* RenderWidgetHostViewAura::GetFocusedFrame() { |
| RenderViewHost* rvh = RenderViewHost::From(host_); |
| if (!rvh) |
| @@ -766,88 +675,6 @@ RenderFrameHostImpl* RenderWidgetHostViewAura::GetFocusedFrame() { |
| return focused_frame->current_frame_host(); |
| } |
| -bool RenderWidgetHostViewAura::CanRendererHandleEvent( |
| - const ui::MouseEvent* event, |
| - bool mouse_locked, |
| - bool selection_popup) const { |
| - if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) |
| - return false; |
| - |
| - if (event->type() == ui::ET_MOUSE_EXITED) { |
| - if (mouse_locked || selection_popup) |
| - return false; |
| -#if defined(OS_WIN) |
| - // Don't forward the mouse leave message which is received when the context |
| - // menu is displayed by the page. This confuses the page and causes state |
| - // changes. |
| - if (IsShowingContextMenu()) |
| - return false; |
| -#endif |
| - return true; |
| - } |
| - |
| -#if defined(OS_WIN) |
| - // Renderer cannot handle WM_XBUTTON or NC events. |
| - switch (event->native_event().message) { |
| - case WM_XBUTTONDOWN: |
| - case WM_XBUTTONUP: |
| - case WM_XBUTTONDBLCLK: |
| - case WM_NCMOUSELEAVE: |
| - case WM_NCMOUSEMOVE: |
| - case WM_NCLBUTTONDOWN: |
| - case WM_NCLBUTTONUP: |
| - case WM_NCLBUTTONDBLCLK: |
| - case WM_NCRBUTTONDOWN: |
| - case WM_NCRBUTTONUP: |
| - case WM_NCRBUTTONDBLCLK: |
| - case WM_NCMBUTTONDOWN: |
| - case WM_NCMBUTTONUP: |
| - case WM_NCMBUTTONDBLCLK: |
| - case WM_NCXBUTTONDOWN: |
| - case WM_NCXBUTTONUP: |
| - case WM_NCXBUTTONDBLCLK: |
| - return false; |
| - default: |
| - break; |
| - } |
| -#elif defined(USE_X11) |
| - // Renderer only supports standard mouse buttons, so ignore programmable |
| - // buttons. |
| - switch (event->type()) { |
| - case ui::ET_MOUSE_PRESSED: |
| - case ui::ET_MOUSE_RELEASED: { |
| - const int kAllowedButtons = ui::EF_LEFT_MOUSE_BUTTON | |
| - ui::EF_MIDDLE_MOUSE_BUTTON | |
| - ui::EF_RIGHT_MOUSE_BUTTON; |
| - return (event->flags() & kAllowedButtons) != 0; |
| - } |
| - default: |
| - break; |
| - } |
| -#endif |
| - return true; |
| -} |
| - |
| -bool RenderWidgetHostViewAura::ShouldRouteEvent(const ui::Event* event) const { |
| - // We should route an event in two cases: |
| - // 1) Mouse events are routed only if cross-process frames are possible. |
| - // 2) Touch events are always routed. In the absence of a BrowserPlugin |
| - // we expect the routing to always send the event to this view. If |
| - // one or more BrowserPlugins are present, then the event may be targeted |
| - // to one of them, or this view. This allows GuestViews to have access to |
| - // them while still forcing pinch-zoom to be handled by the top-level |
| - // frame. TODO(wjmaclean): At present, this doesn't work for OOPIF, but |
| - // it should be a simple extension to modify RenderWidgetHostViewChildFrame |
| - // in a similar manner to RenderWidgetHostViewGuest. |
| - bool result = host_->delegate() && host_->delegate()->GetInputEventRouter() && |
| - !disable_input_event_router_for_testing_; |
| - // ScrollEvents get transformed into MouseWheel events, and so are treated |
| - // the same as mouse events for routing purposes. |
| - if (event->IsMouseEvent() || event->type() == ui::ET_SCROLL) |
| - result = result && SiteIsolationPolicy::AreCrossProcessFramesPossible(); |
| - return result; |
| -} |
| - |
| void RenderWidgetHostViewAura::HandleParentBoundsChanged() { |
| SnapToPhysicalPixelBoundary(); |
| #if defined(OS_WIN) |
| @@ -905,6 +732,10 @@ void RenderWidgetHostViewAura::SetBackgroundColor(SkColor color) { |
| window_->layer()->SetColor(color); |
| } |
| +bool RenderWidgetHostViewAura::IsMouseLocked() { |
| + return event_handler_->mouse_locked(); |
| +} |
| + |
| gfx::Size RenderWidgetHostViewAura::GetVisibleViewportSize() const { |
| gfx::Rect requested_rect(GetRequestedRendererSize()); |
| requested_rect.Inset(insets_); |
| @@ -1269,66 +1100,11 @@ RenderWidgetHostViewAura::AccessibilityGetNativeViewAccessible() { |
| } |
| bool RenderWidgetHostViewAura::LockMouse() { |
| - aura::Window* root_window = window_->GetRootWindow(); |
| - if (!root_window) |
| - return false; |
| - |
| - if (mouse_locked_) |
| - return true; |
| - |
| - mouse_locked_ = true; |
| -#if !defined(OS_WIN) |
| - window_->SetCapture(); |
| -#else |
| - UpdateMouseLockRegion(); |
| -#endif |
| - aura::client::CursorClient* cursor_client = |
| - aura::client::GetCursorClient(root_window); |
| - if (cursor_client) { |
| - cursor_client->HideCursor(); |
| - cursor_client->LockCursor(); |
| - } |
| - |
| - if (ShouldMoveToCenter()) { |
| - synthetic_move_sent_ = true; |
| - window_->MoveCursorTo(gfx::Rect(window_->bounds().size()).CenterPoint()); |
| - } |
| - tooltip_disabler_.reset(new aura::client::ScopedTooltipDisabler(root_window)); |
|
sadrul
2016/09/13 15:39:46
It might make sense to keep this tooltip disabler
jonross
2016/09/15 16:39:59
Moved the tooltip disabler back to RWHVA, and adde
|
| - return true; |
| + return event_handler_->LockMouse(); |
| } |
| void RenderWidgetHostViewAura::UnlockMouse() { |
| - tooltip_disabler_.reset(); |
| - |
| - aura::Window* root_window = window_->GetRootWindow(); |
| - if (!mouse_locked_ || !root_window) |
| - return; |
| - |
| - mouse_locked_ = false; |
| - |
| - if (window_->HasCapture()) |
| - window_->ReleaseCapture(); |
| - |
| -#if defined(OS_WIN) |
| - ::ClipCursor(NULL); |
| -#endif |
| - |
| - // Ensure that the global mouse position is updated here to its original |
| - // value. If we don't do this then the synthesized mouse move which is posted |
| - // after the cursor is moved ends up getting a large movement delta which is |
| - // not what sites expect. The delta is computed in the |
| - // ModifyEventMovementAndCoords function. |
| - global_mouse_position_ = unlocked_global_mouse_position_; |
| - window_->MoveCursorTo(unlocked_mouse_position_); |
| - |
| - aura::client::CursorClient* cursor_client = |
| - aura::client::GetCursorClient(root_window); |
| - if (cursor_client) { |
| - cursor_client->UnlockCursor(); |
| - cursor_client->ShowCursor(); |
| - } |
| - |
| - host_->LostMouseLock(); |
| + event_handler_->UnlockMouse(); |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| @@ -1396,8 +1172,8 @@ void RenderWidgetHostViewAura::InsertChar(const ui::KeyEvent& event) { |
| // Ignore character messages for VKEY_RETURN sent on CTRL+M. crbug.com/315547 |
| // TODO(wjmaclean): can host_ ever be null? |
| - if (host_ && |
| - (accept_return_character_ || event.GetCharacter() != ui::VKEY_RETURN)) { |
| + if (host_ && (event_handler_->accept_return_character() || |
| + event.GetCharacter() != ui::VKEY_RETURN)) { |
| // Send a blink::WebInputEvent::Char event to |host_|. |
| ForwardKeyboardEvent(NativeWebKeyboardEvent(event, event.GetCharacter())); |
| } |
| @@ -1766,221 +1542,11 @@ void RenderWidgetHostViewAura::GetHitTestMask(gfx::Path* mask) const { |
| // RenderWidgetHostViewAura, ui::EventHandler implementation: |
| void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) { |
| - TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnKeyEvent"); |
| - |
| - if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) { |
| - popup_child_host_view_->OnKeyEvent(event); |
| - if (event->handled()) |
| - return; |
| - } |
| - |
| - // We need to handle the Escape key for Pepper Flash. |
| - if (is_fullscreen_ && event->key_code() == ui::VKEY_ESCAPE) { |
| - // Focus the window we were created from. |
| - if (host_tracker_.get() && !host_tracker_->windows().empty()) { |
| - aura::Window* host = *(host_tracker_->windows().begin()); |
| - aura::client::FocusClient* client = aura::client::GetFocusClient(host); |
| - if (client) { |
| - // Calling host->Focus() may delete |this|. We create a local observer |
| - // for that. In that case we exit without further access to any members. |
| - aura::WindowTracker tracker; |
| - aura::Window* window = window_; |
| - tracker.Add(window); |
| - host->Focus(); |
| - if (!tracker.Contains(window)) { |
| - event->SetHandled(); |
| - return; |
| - } |
| - } |
| - } |
| - Shutdown(); |
| - } else { |
| - if (event->key_code() == ui::VKEY_RETURN) { |
| - // Do not forward return key release events if no press event was handled. |
| - if (event->type() == ui::ET_KEY_RELEASED && !accept_return_character_) |
| - return; |
| - // Accept return key character events between press and release events. |
| - accept_return_character_ = event->type() == ui::ET_KEY_PRESSED; |
| - } |
| - |
| - // Call SetKeyboardFocus() for not only ET_KEY_PRESSED but also |
| - // ET_KEY_RELEASED. If a user closed the hotdog menu with ESC key press, |
| - // we need to notify focus to Blink on ET_KEY_RELEASED for ESC key. |
| - SetKeyboardFocus(); |
| - // We don't have to communicate with an input method here. |
| - NativeWebKeyboardEvent webkit_event(*event); |
| - ForwardKeyboardEvent(webkit_event); |
| - } |
| - event->SetHandled(); |
| + event_handler_->OnKeyEvent(event); |
| } |
| void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) { |
| - TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnMouseEvent"); |
| - |
| - ForwardMouseEventToParent(event); |
| - // TODO(mgiuca): Return if event->handled() returns true. This currently |
| - // breaks drop-down lists which means something is incorrectly setting |
| - // event->handled to true (http://crbug.com/577983). |
| - |
| - if (mouse_locked_) { |
| - aura::client::CursorClient* cursor_client = |
| - aura::client::GetCursorClient(window_->GetRootWindow()); |
| - DCHECK(!cursor_client || !cursor_client->IsCursorVisible()); |
| - |
| - if (event->type() == ui::ET_MOUSEWHEEL) { |
| - blink::WebMouseWheelEvent mouse_wheel_event = |
| - ui::MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent&>(*event), |
| - base::Bind(&GetScreenLocationFromEvent)); |
| - if (mouse_wheel_event.deltaX != 0 || mouse_wheel_event.deltaY != 0) |
| - host_->ForwardWheelEvent(mouse_wheel_event); |
| - return; |
| - } |
| - |
| - gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint()); |
| - |
| - // If we receive non client mouse messages while we are in the locked state |
| - // it probably means that the mouse left the borders of our window and |
| - // needs to be moved back to the center. |
| - if (event->flags() & ui::EF_IS_NON_CLIENT) { |
| - synthetic_move_sent_ = true; |
| - window_->MoveCursorTo(center); |
| - return; |
| - } |
| - |
| - blink::WebMouseEvent mouse_event = |
| - ui::MakeWebMouseEvent(*event, base::Bind(&GetScreenLocationFromEvent)); |
| - |
| - bool is_move_to_center_event = (event->type() == ui::ET_MOUSE_MOVED || |
| - event->type() == ui::ET_MOUSE_DRAGGED) && |
| - mouse_event.x == center.x() && mouse_event.y == center.y(); |
| - |
| - // For fractional scale factors, the conversion from pixels to dip and |
| - // vice versa could result in off by 1 or 2 errors which hurts us because |
| - // we want to avoid sending the artificial move to center event to the |
| - // renderer. Sending the move to center to the renderer cause the cursor |
| - // to bounce around the center of the screen leading to the lock operation |
| - // not working correctly. |
| - // Workaround is to treat a mouse move or drag event off by at most 2 px |
| - // from the center as a move to center event. |
| - if (synthetic_move_sent_ && |
| - IsFractionalScaleFactor(current_device_scale_factor_)) { |
| - if (event->type() == ui::ET_MOUSE_MOVED || |
| - event->type() == ui::ET_MOUSE_DRAGGED) { |
| - if ((abs(mouse_event.x - center.x()) <= 2) && |
| - (abs(mouse_event.y - center.y()) <= 2)) { |
| - is_move_to_center_event = true; |
| - } |
| - } |
| - } |
| - |
| - ModifyEventMovementAndCoords(&mouse_event); |
| - |
| - bool should_not_forward = is_move_to_center_event && synthetic_move_sent_; |
| - if (should_not_forward) { |
| - synthetic_move_sent_ = false; |
| - } else { |
| - // Check if the mouse has reached the border and needs to be centered. |
| - if (ShouldMoveToCenter()) { |
| - synthetic_move_sent_ = true; |
| - window_->MoveCursorTo(center); |
| - } |
| - bool is_selection_popup = popup_child_host_view_ && |
| - popup_child_host_view_->NeedsInputGrab(); |
| - // Forward event to renderer. |
| - if (CanRendererHandleEvent(event, mouse_locked_, is_selection_popup) && |
| - !(event->flags() & ui::EF_FROM_TOUCH)) { |
| - host_->ForwardMouseEvent(mouse_event); |
| - // Ensure that we get keyboard focus on mouse down as a plugin window |
| - // may have grabbed keyboard focus. |
| - if (event->type() == ui::ET_MOUSE_PRESSED) |
| - SetKeyboardFocus(); |
| - } |
| - } |
| - return; |
| - } |
| - |
| - // As the overscroll is handled during scroll events from the trackpad, the |
| - // RWHVA window is transformed by the overscroll controller. This transform |
| - // triggers a synthetic mouse-move event to be generated (by the aura |
| - // RootWindow). But this event interferes with the overscroll gesture. So, |
| - // ignore such synthetic mouse-move events if an overscroll gesture is in |
| - // progress. |
| - if (overscroll_controller_ && |
| - overscroll_controller_->overscroll_mode() != OVERSCROLL_NONE && |
| - event->flags() & ui::EF_IS_SYNTHESIZED && |
| - (event->type() == ui::ET_MOUSE_ENTERED || |
| - event->type() == ui::ET_MOUSE_EXITED || |
| - event->type() == ui::ET_MOUSE_MOVED)) { |
| - event->StopPropagation(); |
| - return; |
| - } |
| - |
| - if (event->type() == ui::ET_MOUSEWHEEL) { |
| -#if defined(OS_WIN) |
| - // We get mouse wheel/scroll messages even if we are not in the foreground. |
| - // So here we check if we have any owned popup windows in the foreground and |
| - // dismiss them. |
| - aura::WindowTreeHost* host = window_->GetHost(); |
| - if (host) { |
| - HWND parent = host->GetAcceleratedWidget(); |
| - HWND toplevel_hwnd = ::GetAncestor(parent, GA_ROOT); |
| - EnumThreadWindows(GetCurrentThreadId(), |
| - DismissOwnedPopups, |
| - reinterpret_cast<LPARAM>(toplevel_hwnd)); |
| - } |
| -#endif |
| - blink::WebMouseWheelEvent mouse_wheel_event = |
| - ui::MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent&>(*event), |
| - base::Bind(&GetScreenLocationFromEvent)); |
| - if (mouse_wheel_event.deltaX != 0 || mouse_wheel_event.deltaY != 0) { |
| - if (ShouldRouteEvent(event)) { |
| - host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( |
| - this, &mouse_wheel_event); |
| - } else { |
| - ProcessMouseWheelEvent(mouse_wheel_event, *event->latency()); |
| - } |
| - } |
| - } else { |
| - bool is_selection_popup = |
| - popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab(); |
| - if (CanRendererHandleEvent(event, mouse_locked_, is_selection_popup) && |
| - !(event->flags() & ui::EF_FROM_TOUCH)) { |
| - // Confirm existing composition text on mouse press, to make sure |
| - // the input caret won't be moved with an ongoing composition text. |
| - if (event->type() == ui::ET_MOUSE_PRESSED) |
| - FinishImeCompositionSession(); |
| - |
| - blink::WebMouseEvent mouse_event = ui::MakeWebMouseEvent( |
| - *event, base::Bind(&GetScreenLocationFromEvent)); |
| - ModifyEventMovementAndCoords(&mouse_event); |
| - if (ShouldRouteEvent(event)) { |
| - host_->delegate()->GetInputEventRouter()->RouteMouseEvent(this, |
| - &mouse_event); |
| - } else { |
| - ProcessMouseEvent(mouse_event, *event->latency()); |
| - } |
| - |
| - // Ensure that we get keyboard focus on mouse down as a plugin window may |
| - // have grabbed keyboard focus. |
| - if (event->type() == ui::ET_MOUSE_PRESSED) |
| - SetKeyboardFocus(); |
| - } |
| - } |
| - |
| - switch (event->type()) { |
| - case ui::ET_MOUSE_PRESSED: |
| - window_->SetCapture(); |
| - break; |
| - case ui::ET_MOUSE_RELEASED: |
| - if (!NeedsMouseCapture()) |
| - window_->ReleaseCapture(); |
| - break; |
| - default: |
| - break; |
| - } |
| - |
| - if (!IsXButtonUpEvent(event)) |
| - event->SetHandled(); |
| + event_handler_->OnMouseEvent(event); |
| } |
| uint32_t RenderWidgetHostViewAura::SurfaceClientIdAtPoint( |
| @@ -2068,152 +1634,15 @@ void RenderWidgetHostViewAura::FocusedNodeChanged(bool editable) { |
| } |
| void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) { |
| - TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnScrollEvent"); |
| - |
| - if (event->type() == ui::ET_SCROLL) { |
| -#if !defined(OS_WIN) |
| - // TODO(ananta) |
| - // Investigate if this is true for Windows 8 Metro ASH as well. |
| - if (event->finger_count() != 2) |
| - return; |
| -#endif |
| - blink::WebGestureEvent gesture_event = ui::MakeWebGestureEventFlingCancel(); |
| - // Coordinates need to be transferred to the fling cancel gesture only |
| - // for Surface-targeting to ensure that it is targeted to the correct |
| - // RenderWidgetHost. |
| - gesture_event.x = event->x(); |
| - gesture_event.y = event->y(); |
| - blink::WebMouseWheelEvent mouse_wheel_event = ui::MakeWebMouseWheelEvent( |
| - *event, base::Bind(&GetScreenLocationFromEvent)); |
| - if (ShouldRouteEvent(event)) { |
| - host_->delegate()->GetInputEventRouter()->RouteGestureEvent( |
| - this, &gesture_event, ui::LatencyInfo()); |
| - host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( |
| - this, &mouse_wheel_event); |
| - } else { |
| - host_->ForwardGestureEvent(gesture_event); |
| - host_->ForwardWheelEventWithLatencyInfo(mouse_wheel_event, |
| - *event->latency()); |
| - } |
| - RecordAction(base::UserMetricsAction("TrackpadScroll")); |
| - } else if (event->type() == ui::ET_SCROLL_FLING_START || |
| - event->type() == ui::ET_SCROLL_FLING_CANCEL) { |
| - blink::WebGestureEvent gesture_event = ui::MakeWebGestureEvent( |
| - *event, base::Bind(&GetScreenLocationFromEvent)); |
| - if (ShouldRouteEvent(event)) { |
| - host_->delegate()->GetInputEventRouter()->RouteGestureEvent( |
| - this, &gesture_event, ui::LatencyInfo()); |
| - } else { |
| - host_->ForwardGestureEvent(gesture_event); |
| - } |
| - if (event->type() == ui::ET_SCROLL_FLING_START) |
| - RecordAction(base::UserMetricsAction("TrackpadScrollFling")); |
| - } |
| - |
| - event->SetHandled(); |
| + event_handler_->OnScrollEvent(event); |
| } |
| void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) { |
| - TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnTouchEvent"); |
| - |
| - bool had_no_pointer = !pointer_state_.GetPointerCount(); |
| - |
| - // Update the touch event first. |
| - if (!pointer_state_.OnTouch(*event)) { |
| - event->StopPropagation(); |
| - return; |
| - } |
| - |
| - blink::WebTouchEvent touch_event; |
| - bool handled = selection_controller_->WillHandleTouchEvent(pointer_state_); |
| - if (handled) { |
| - event->SetHandled(); |
| - } else { |
| - touch_event = ui::CreateWebTouchEventFromMotionEvent( |
| - pointer_state_, event->may_cause_scrolling()); |
| - } |
| - pointer_state_.CleanupRemovedTouchPoints(*event); |
| - |
| - if (handled) |
| - return; |
| - |
| - if (had_no_pointer) |
| - selection_controller_client_->OnTouchDown(); |
| - if (!pointer_state_.GetPointerCount()) |
| - selection_controller_client_->OnTouchUp(); |
| - |
| - // It is important to always mark events as being handled asynchronously when |
| - // they are forwarded. This ensures that the current event does not get |
| - // processed by the gesture recognizer before events currently awaiting |
| - // dispatch in the touch queue. |
| - event->DisableSynchronousHandling(); |
| - |
| - // Set unchanged touch point to StateStationary for touchmove and |
| - // touchcancel to make sure only send one ack per WebTouchEvent. |
| - MarkUnchangedTouchPointsAsStationary(&touch_event, event->touch_id()); |
| - if (ShouldRouteEvent(event)) { |
| - host_->delegate()->GetInputEventRouter()->RouteTouchEvent( |
| - this, &touch_event, *event->latency()); |
| - } else { |
| - ProcessTouchEvent(touch_event, *event->latency()); |
| - } |
| + event_handler_->OnTouchEvent(event); |
| } |
| void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) { |
| - TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnGestureEvent"); |
| - |
| - if ((event->type() == ui::ET_GESTURE_PINCH_BEGIN || |
| - event->type() == ui::ET_GESTURE_PINCH_UPDATE || |
| - event->type() == ui::ET_GESTURE_PINCH_END) && !pinch_zoom_enabled_) { |
| - event->SetHandled(); |
| - return; |
| - } |
| - |
| - HandleGestureForTouchSelection(event); |
| - if (event->handled()) |
| - return; |
| - |
| - // Confirm existing composition text on TAP gesture, to make sure the input |
| - // caret won't be moved with an ongoing composition text. |
| - if (event->type() == ui::ET_GESTURE_TAP) |
| - FinishImeCompositionSession(); |
| - |
| - blink::WebGestureEvent gesture = |
| - ui::MakeWebGestureEvent(*event, base::Bind(&GetScreenLocationFromEvent)); |
| - if (event->type() == ui::ET_GESTURE_TAP_DOWN) { |
| - // Webkit does not stop a fling-scroll on tap-down. So explicitly send an |
| - // event to stop any in-progress flings. |
| - blink::WebGestureEvent fling_cancel = gesture; |
| - fling_cancel.type = blink::WebInputEvent::GestureFlingCancel; |
| - fling_cancel.sourceDevice = blink::WebGestureDeviceTouchscreen; |
| - if (ShouldRouteEvent(event)) { |
| - host_->delegate()->GetInputEventRouter()->RouteGestureEvent( |
| - this, &fling_cancel, ui::LatencyInfo()); |
| - } else { |
| - host_->ForwardGestureEvent(fling_cancel); |
| - } |
| - } |
| - |
| - if (gesture.type != blink::WebInputEvent::Undefined) { |
| - if (ShouldRouteEvent(event)) { |
| - host_->delegate()->GetInputEventRouter()->RouteGestureEvent( |
| - this, &gesture, *event->latency()); |
| - } else { |
| - host_->ForwardGestureEventWithLatencyInfo(gesture, *event->latency()); |
| - } |
| - |
| - if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN || |
| - event->type() == ui::ET_GESTURE_SCROLL_UPDATE || |
| - event->type() == ui::ET_GESTURE_SCROLL_END) { |
| - RecordAction(base::UserMetricsAction("TouchscreenScroll")); |
| - } else if (event->type() == ui::ET_SCROLL_FLING_START) { |
| - RecordAction(base::UserMetricsAction("TouchscreenScrollFling")); |
| - } |
| - } |
| - |
| - // If a gesture is not processed by the webpage, then WebKit processes it |
| - // (e.g. generates synthetic mouse events). |
| - event->SetHandled(); |
| + event_handler_->OnGestureEvent(event); |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| @@ -2355,7 +1784,7 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() { |
| if (popup_parent_host_view_) { |
| DCHECK(popup_parent_host_view_->popup_child_host_view_ == NULL || |
| popup_parent_host_view_->popup_child_host_view_ == this); |
| - popup_parent_host_view_->popup_child_host_view_ = NULL; |
| + popup_parent_host_view_->SetPopupChildHostView(nullptr); |
| } |
| if (popup_child_host_view_) { |
| DCHECK(popup_child_host_view_->popup_parent_host_view_ == NULL || |
| @@ -2386,6 +1815,7 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() { |
| void RenderWidgetHostViewAura::CreateAuraWindow() { |
| DCHECK(!window_); |
| window_ = new aura::Window(this); |
| + event_handler_->set_window(window_); |
| window_observer_.reset(new WindowObserver(this)); |
| aura::client::SetTooltipText(window_, &tooltip_); |
| @@ -2485,51 +1915,6 @@ bool RenderWidgetHostViewAura::NeedsMouseCapture() { |
| return false; |
| } |
| -void RenderWidgetHostViewAura::FinishImeCompositionSession() { |
| - if (!has_composition_text_) |
| - return; |
| - |
| - if (!!text_input_manager_ && !!text_input_manager_->GetActiveWidget()) { |
| - text_input_manager_->GetActiveWidget()->ImeConfirmComposition( |
| - base::string16(), gfx::Range::InvalidRange(), false); |
| - } |
| - ImeCancelComposition(); |
| -} |
| - |
| -void RenderWidgetHostViewAura::ModifyEventMovementAndCoords( |
| - blink::WebMouseEvent* event) { |
| - // If the mouse has just entered, we must report zero movementX/Y. Hence we |
| - // reset any global_mouse_position set previously. |
| - if (event->type == blink::WebInputEvent::MouseEnter || |
| - event->type == blink::WebInputEvent::MouseLeave) |
| - global_mouse_position_.SetPoint(event->globalX, event->globalY); |
| - |
| - // Movement is computed by taking the difference of the new cursor position |
| - // and the previous. Under mouse lock the cursor will be warped back to the |
| - // center so that we are not limited by clipping boundaries. |
| - // We do not measure movement as the delta from cursor to center because |
| - // we may receive more mouse movement events before our warp has taken |
| - // effect. |
| - event->movementX = event->globalX - global_mouse_position_.x(); |
| - event->movementY = event->globalY - global_mouse_position_.y(); |
| - |
| - global_mouse_position_.SetPoint(event->globalX, event->globalY); |
| - |
| - // Under mouse lock, coordinates of mouse are locked to what they were when |
| - // mouse lock was entered. |
| - if (mouse_locked_) { |
| - event->x = unlocked_mouse_position_.x(); |
| - event->y = unlocked_mouse_position_.y(); |
| - event->windowX = unlocked_mouse_position_.x(); |
| - event->windowY = unlocked_mouse_position_.y(); |
| - event->globalX = unlocked_global_mouse_position_.x(); |
| - event->globalY = unlocked_global_mouse_position_.y(); |
| - } else { |
| - unlocked_mouse_position_.SetPoint(event->x, event->y); |
| - unlocked_global_mouse_position_.SetPoint(event->globalX, event->globalY); |
| - } |
| -} |
| - |
| void RenderWidgetHostViewAura::NotifyRendererOfCursorVisibilityState( |
| bool is_visible) { |
| if (host_->is_hidden() || |
| @@ -2569,22 +1954,17 @@ void RenderWidgetHostViewAura::SnapToPhysicalPixelBoundary() { |
| bool RenderWidgetHostViewAura::OnShowContextMenu( |
| const ContextMenuParams& params) { |
| #if defined(OS_WIN) |
| - last_context_menu_params_.reset(); |
| - |
| - if (params.source_type == ui::MENU_SOURCE_LONG_PRESS) { |
| - last_context_menu_params_.reset(new ContextMenuParams); |
| - *last_context_menu_params_ = params; |
| - return false; |
| - } |
| -#endif |
| + event_handler_->SetContextMenuParams(params); |
| + return params.source_type != ui::MENU_SOURCE_LONG_PRESS; |
| +#else |
| return true; |
| +#endif // defined(OS_WIN) |
| } |
| void RenderWidgetHostViewAura::SetSelectionControllerClientForTest( |
| std::unique_ptr<TouchSelectionControllerClientAura> client) { |
| selection_controller_client_.swap(client); |
| CreateSelectionController(); |
| - disable_input_event_router_for_testing_ = true; |
| } |
| void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) { |
| @@ -2640,18 +2020,6 @@ void RenderWidgetHostViewAura::SchedulePaintIfNotInClip( |
| } |
| } |
| -bool RenderWidgetHostViewAura::ShouldMoveToCenter() { |
| - gfx::Rect rect = window_->bounds(); |
| - rect = ConvertRectToScreen(rect); |
| - int border_x = rect.width() * kMouseLockBorderPercentage / 100; |
| - int border_y = rect.height() * kMouseLockBorderPercentage / 100; |
| - |
| - return global_mouse_position_.x() < rect.x() + border_x || |
| - global_mouse_position_.x() > rect.right() - border_x || |
| - global_mouse_position_.y() < rect.y() + border_y || |
| - global_mouse_position_.y() > rect.bottom() - border_y; |
| -} |
| - |
| void RenderWidgetHostViewAura::AddedToRootWindow() { |
| window_->GetHost()->AddObserver(this); |
| UpdateScreenInfo(window_); |
| @@ -2759,102 +2127,6 @@ void RenderWidgetHostViewAura::CreateSelectionController() { |
| selection_controller_client_.get(), tsc_config)); |
| } |
| -void RenderWidgetHostViewAura::HandleGestureForTouchSelection( |
| - ui::GestureEvent* event) { |
| - switch (event->type()) { |
| - case ui::ET_GESTURE_LONG_PRESS: |
| - if (selection_controller_->WillHandleLongPressEvent( |
| - event->time_stamp(), event->location_f())) { |
| - event->SetHandled(); |
| - } |
| - break; |
| - case ui::ET_GESTURE_TAP: |
| - if (selection_controller_->WillHandleTapEvent( |
| - event->location_f(), event->details().tap_count())) { |
| - event->SetHandled(); |
| - } |
| - break; |
| - case ui::ET_GESTURE_SCROLL_BEGIN: |
| - selection_controller_client_->OnScrollStarted(); |
| - break; |
| - case ui::ET_GESTURE_SCROLL_END: |
| - selection_controller_client_->OnScrollCompleted(); |
| - break; |
| -#if defined(OS_WIN) |
| - case ui::ET_GESTURE_LONG_TAP: { |
| - if (!last_context_menu_params_) |
| - break; |
| - |
| - std::unique_ptr<ContextMenuParams> context_menu_params = |
| - std::move(last_context_menu_params_); |
| - |
| - // On Windows we want to display the context menu when the long press |
| - // gesture is released. To achieve that, we switch the saved context |
| - // menu params source type to MENU_SOURCE_TOUCH. This is to ensure that |
| - // the RenderWidgetHostViewAura::OnShowContextMenu function which is |
| - // called from the ShowContextMenu call below, does not treat it as |
| - // a context menu request coming in from the long press gesture. |
| - DCHECK(context_menu_params->source_type == ui::MENU_SOURCE_LONG_PRESS); |
| - context_menu_params->source_type = ui::MENU_SOURCE_TOUCH; |
| - |
| - RenderViewHostDelegateView* delegate_view = |
| - GetRenderViewHostDelegateView(); |
| - if (delegate_view) |
| - delegate_view->ShowContextMenu(GetFocusedFrame(), |
| - *context_menu_params); |
| - |
| - event->SetHandled(); |
| - // WARNING: we may have been deleted during the call to ShowContextMenu(). |
| - break; |
| - } |
| -#endif |
| - default: |
| - break; |
| - } |
| -} |
| - |
| -void RenderWidgetHostViewAura::ForwardMouseEventToParent( |
| - ui::MouseEvent* event) { |
| - // Needed to propagate mouse event to |window_->parent()->delegate()|, but |
| - // note that it might be something other than a WebContentsViewAura instance. |
| - // TODO(pkotwicz): Find a better way of doing this. |
| - // In fullscreen mode which is typically used by flash, don't forward |
| - // the mouse events to the parent. The renderer and the plugin process |
| - // handle these events. |
| - if (is_fullscreen_) |
| - return; |
| - |
| - if (event->flags() & ui::EF_FROM_TOUCH) |
| - return; |
| - |
| - if (!window_->parent() || !window_->parent()->delegate()) |
| - return; |
| - |
| - // Take a copy of |event|, to avoid ConvertLocationToTarget mutating the |
| - // event. |
| - std::unique_ptr<ui::Event> event_copy = ui::Event::Clone(*event); |
| - ui::MouseEvent* mouse_event = static_cast<ui::MouseEvent*>(event_copy.get()); |
| - mouse_event->ConvertLocationToTarget(window_, window_->parent()); |
| - window_->parent()->delegate()->OnMouseEvent(mouse_event); |
| - if (mouse_event->handled()) |
| - event->SetHandled(); |
| -} |
| - |
| -RenderViewHostDelegateView* |
| -RenderWidgetHostViewAura::GetRenderViewHostDelegateView() { |
| - // Use RenderViewHostDelegate to get to the WebContentsViewAura, which will |
| - // actually show the disambiguation popup. |
| - RenderViewHost* rvh = RenderViewHost::From(host_); |
| - if (!rvh) |
| - return nullptr; |
| - |
| - RenderViewHostDelegate* delegate = rvh->GetDelegate(); |
| - if (!delegate) |
| - return nullptr; |
| - |
| - return delegate->GetDelegateView(); |
| -} |
| - |
| //////////////////////////////////////////////////////////////////////////////// |
| // DelegatedFrameHost, public: |
| @@ -3044,4 +2316,10 @@ void RenderWidgetHostViewAura::OnTextSelectionChanged( |
| #endif // defined(USE_X11) && !defined(OS_CHROMEOS) |
| } |
| +void RenderWidgetHostViewAura::SetPopupChildHostView( |
| + RenderWidgetHostViewAura* popup_child_host_view) { |
| + popup_child_host_view_ = popup_child_host_view; |
| + event_handler_->SetPopupChildHostView(popup_child_host_view); |
| +} |
| + |
| } // namespace content |