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 67cd7d905ec0fbaeb10338cc320eac6cee3afc20..01690f4cfac8e9170ae706c3365340f804183c57 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 |
@@ -432,17 +365,14 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host, |
window_(nullptr), |
in_shutdown_(false), |
in_bounds_changed_(false), |
- is_fullscreen_(false), |
popup_parent_host_view_(nullptr), |
popup_child_host_view_(nullptr), |
is_loading_(false), |
has_composition_text_(false), |
- accept_return_character_(false), |
begin_frame_source_(nullptr), |
needs_begin_frames_(false), |
needs_flush_input_(false), |
added_frame_observer_(false), |
- synthetic_move_sent_(false), |
cursor_visibility_state_in_renderer_(UNKNOWN), |
#if defined(OS_WIN) |
legacy_render_widget_host_HWND_(nullptr), |
@@ -451,11 +381,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, this)), |
weak_ptr_factory_(this) { |
// GuestViews have two RenderWidgetHostViews and so we need to make sure |
// we don't have FrameSinkId collisions. |
@@ -542,7 +471,7 @@ void RenderWidgetHostViewAura::InitAsPopup( |
} |
old_child->popup_parent_host_view_ = NULL; |
} |
- popup_parent_host_view_->popup_child_host_view_ = this; |
+ popup_parent_host_view_->SetPopupChild(this); |
window_->SetType(ui::wm::WINDOW_TYPE_MENU); |
window_->Init(ui::LAYER_SOLID_COLOR); |
window_->SetName("RenderWidgetHostViewAura"); |
@@ -587,10 +516,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(); |
@@ -768,24 +694,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) |
@@ -798,88 +706,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) |
@@ -937,6 +763,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_); |
@@ -1301,66 +1131,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)); |
- 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(); |
} |
//////////////////////////////////////////////////////////////////////////////// |
@@ -1430,8 +1205,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())); |
} |
@@ -1800,221 +1575,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(*event, &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, *event->latency()); |
- } 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(*event, &mouse_event); |
- if (ShouldRouteEvent(event)) { |
- host_->delegate()->GetInputEventRouter()->RouteMouseEvent( |
- this, &mouse_event, *event->latency()); |
- } 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); |
} |
cc::FrameSinkId RenderWidgetHostViewAura::FrameSinkIdAtPoint( |
@@ -2108,152 +1673,15 @@ void RenderWidgetHostViewAura::FocusedNodeChanged( |
} |
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(ui::SourceEventType::WHEEL)); |
- host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( |
- this, &mouse_wheel_event, *event->latency()); |
- } 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(ui::SourceEventType::WHEEL)); |
- } 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(ui::SourceEventType::TOUCH)); |
- } 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); |
} |
//////////////////////////////////////////////////////////////////////////////// |
@@ -2395,7 +1823,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_->SetPopupChild(nullptr); |
} |
if (popup_child_host_view_) { |
DCHECK(popup_child_host_view_->popup_parent_host_view_ == NULL || |
@@ -2426,6 +1854,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_); |
@@ -2525,52 +1954,33 @@ 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()->ImeFinishComposingText(false); |
- } |
- ImeCancelComposition(); |
-} |
- |
-void RenderWidgetHostViewAura::ModifyEventMovementAndCoords( |
- const ui::MouseEvent& ui_mouse_event, |
- 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 (ui_mouse_event.type() == ui::ET_MOUSE_ENTERED || |
- ui_mouse_event.type() == ui::ET_MOUSE_EXITED) { |
- 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(); |
+void RenderWidgetHostViewAura::SetTooltipsEnabled(bool enable) { |
+ if (enable) { |
+ tooltip_disabler_.reset(); |
} else { |
- unlocked_mouse_position_.SetPoint(event->x, event->y); |
- unlocked_global_mouse_position_.SetPoint(event->globalX, event->globalY); |
+ tooltip_disabler_.reset( |
+ new aura::client::ScopedTooltipDisabler(window_->GetRootWindow())); |
} |
} |
+void RenderWidgetHostViewAura::ShowContextMenu( |
+ const ContextMenuParams& params) { |
+ // Use RenderViewHostDelegate to get to the WebContentsViewAura, which will |
+ // actually show the disambiguation popup. |
+ RenderViewHost* rvh = RenderViewHost::From(host_); |
+ if (!rvh) |
+ return; |
+ |
+ RenderViewHostDelegate* delegate = rvh->GetDelegate(); |
+ if (!delegate) |
+ return; |
+ |
+ RenderViewHostDelegateView* delegate_view = delegate->GetDelegateView(); |
+ if (!delegate_view) |
+ return; |
+ delegate_view->ShowContextMenu(GetFocusedFrame(), params); |
+} |
+ |
void RenderWidgetHostViewAura::NotifyRendererOfCursorVisibilityState( |
bool is_visible) { |
if (host_->is_hidden() || |
@@ -2610,22 +2020,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) { |
@@ -2681,18 +2086,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_); |
@@ -2799,102 +2192,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: |
@@ -3086,4 +2383,12 @@ void RenderWidgetHostViewAura::OnTextSelectionChanged( |
#endif // defined(USE_X11) && !defined(OS_CHROMEOS) |
} |
+void RenderWidgetHostViewAura::SetPopupChild( |
+ RenderWidgetHostViewAura* popup_child_host_view) { |
+ popup_child_host_view_ = popup_child_host_view; |
+ event_handler_->SetPopupChild( |
+ popup_child_host_view, |
+ popup_child_host_view ? popup_child_host_view->event_handler() : nullptr); |
+} |
+ |
} // namespace content |