Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(649)

Unified Diff: content/browser/renderer_host/render_widget_host_view_aura.cc

Issue 2317333002: Refactor EventHandler out of RenderWidgetHostViewAura (Closed)
Patch Set: Fix Windows Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698