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 9d6b2e2e662ce5287583e907cba01822f41e097e..09027b1abd876ceba9b61d513416f06314e02a5a 100644 |
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc |
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc |
@@ -34,6 +34,7 @@ |
#include "content/browser/renderer_host/render_widget_host_impl.h" |
#include "content/browser/renderer_host/ui_events_helper.h" |
#include "content/browser/renderer_host/web_input_event_aura.h" |
+#include "content/browser/web_contents/web_contents_impl.h" |
#include "content/common/gpu/client/gl_helper.h" |
#include "content/common/gpu/gpu_messages.h" |
#include "content/common/view_messages.h" |
@@ -42,6 +43,7 @@ |
#include "content/public/browser/render_view_host.h" |
#include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
#include "content/public/browser/user_metrics.h" |
+#include "content/public/browser/web_contents.h" |
#include "content/public/common/content_switches.h" |
#include "third_party/WebKit/public/platform/WebScreenInfo.h" |
#include "third_party/WebKit/public/web/WebCompositionUnderline.h" |
@@ -73,6 +75,7 @@ |
#include "ui/gfx/screen.h" |
#include "ui/gfx/size_conversions.h" |
#include "ui/gfx/skia_util.h" |
+#include "ui/strings/grit/ui_strings.h" |
#include "ui/wm/public/activation_client.h" |
#include "ui/wm/public/scoped_tooltip_disabler.h" |
#include "ui/wm/public/tooltip_client.h" |
@@ -450,7 +453,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host, |
legacy_render_widget_host_HWND_(NULL), |
#endif |
has_snapped_to_boundary_(false), |
- touch_editing_client_(NULL), |
+ selection_controller_(new TouchSelectionControllerAura(this)), |
is_guest_view_hack_(is_guest_view_hack), |
weak_ptr_factory_(this) { |
if (!is_guest_view_hack_) |
@@ -770,6 +773,7 @@ void RenderWidgetHostViewAura::Focus() { |
void RenderWidgetHostViewAura::Blur() { |
window_->Blur(); |
+ selection_controller_->HideAndDisallowShowingAutomatically(); |
} |
bool RenderWidgetHostViewAura::HasFocus() const { |
@@ -847,8 +851,8 @@ void RenderWidgetHostViewAura::TextInputTypeChanged( |
text_input_flags_ = flags; |
if (GetInputMethod()) |
GetInputMethod()->OnTextInputTypeChanged(this); |
- if (touch_editing_client_) |
- touch_editing_client_->OnTextInputTypeChanged(text_input_type_); |
+ const bool is_editable_node = type != ui::TEXT_INPUT_TYPE_NONE; |
+ selection_controller_->OnSelectionEditable(is_editable_node); |
} |
} |
@@ -905,6 +909,8 @@ void RenderWidgetHostViewAura::SelectionChanged(const base::string16& text, |
const gfx::Range& range) { |
RenderWidgetHostViewBase::SelectionChanged(text, offset, range); |
+ selection_controller_->OnSelectionEmpty(text.empty()); |
+ |
#if defined(USE_X11) && !defined(OS_CHROMEOS) |
if (text.empty() || range.is_empty()) |
return; |
@@ -929,46 +935,7 @@ gfx::Size RenderWidgetHostViewAura::GetRequestedRendererSize() const { |
void RenderWidgetHostViewAura::SelectionBoundsChanged( |
const ViewHostMsg_SelectionBounds_Params& params) { |
- ui::SelectionBound anchor_bound, focus_bound; |
- anchor_bound.edge_top = params.anchor_rect.origin(); |
- anchor_bound.edge_bottom = params.anchor_rect.bottom_left(); |
- focus_bound.edge_top = params.focus_rect.origin(); |
- focus_bound.edge_bottom = params.focus_rect.bottom_left(); |
- |
- if (params.anchor_rect == params.focus_rect) { |
- anchor_bound.type = focus_bound.type = ui::SelectionBound::CENTER; |
- } else { |
- // Whether text is LTR at the anchor handle. |
- bool anchor_LTR = params.anchor_dir == blink::WebTextDirectionLeftToRight; |
- // Whether text is LTR at the focus handle. |
- bool focus_LTR = params.focus_dir == blink::WebTextDirectionLeftToRight; |
- |
- if ((params.is_anchor_first && anchor_LTR) || |
- (!params.is_anchor_first && !anchor_LTR)) { |
- anchor_bound.type = ui::SelectionBound::LEFT; |
- } else { |
- anchor_bound.type = ui::SelectionBound::RIGHT; |
- } |
- if ((params.is_anchor_first && focus_LTR) || |
- (!params.is_anchor_first && !focus_LTR)) { |
- focus_bound.type = ui::SelectionBound::RIGHT; |
- } else { |
- focus_bound.type = ui::SelectionBound::LEFT; |
- } |
- } |
- |
- if (anchor_bound == selection_anchor_ && focus_bound == selection_focus_) |
- return; |
- |
- selection_anchor_ = anchor_bound; |
- selection_focus_ = focus_bound; |
- if (GetInputMethod()) |
- GetInputMethod()->OnCaretBoundsChanged(this); |
- |
- if (touch_editing_client_) { |
- touch_editing_client_->OnSelectionOrCursorChanged( |
- anchor_bound, focus_bound); |
- } |
+ NOTREACHED() << "Selection bounds should be routed through the compositor."; |
} |
void RenderWidgetHostViewAura::CopyFromCompositingSurface( |
@@ -1052,6 +1019,8 @@ void RenderWidgetHostViewAura::OnSwapCompositorFrame( |
frame->delegated_frame_data.Pass(), |
frame->metadata.device_scale_factor, |
frame->metadata.latency_info); |
+ SelectionBoundsUpdated(frame->metadata.selection_start, |
+ frame->metadata.selection_end); |
return; |
} |
@@ -1065,8 +1034,7 @@ void RenderWidgetHostViewAura::OnSwapCompositorFrame( |
} |
void RenderWidgetHostViewAura::DidStopFlinging() { |
- if (touch_editing_client_) |
- touch_editing_client_->DidStopFlinging(); |
+ selection_controller_->OnFlingCompleted(); |
} |
#if defined(OS_WIN) |
@@ -1152,9 +1120,6 @@ void RenderWidgetHostViewAura::WheelEventAck( |
void RenderWidgetHostViewAura::GestureEventAck( |
const blink::WebGestureEvent& event, |
InputEventAckState ack_result) { |
- if (touch_editing_client_) |
- touch_editing_client_->GestureEventAck(event.type); |
- |
if (overscroll_controller_) { |
overscroll_controller_->ReceivedEventACK( |
event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); |
@@ -1531,9 +1496,7 @@ gfx::Rect RenderWidgetHostViewAura::ConvertRectFromScreen( |
} |
gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const { |
- gfx::Rect rect = |
- ui::RectBetweenSelectionBounds(selection_anchor_, selection_focus_); |
- return ConvertRectToScreen(rect); |
+ return ConvertRectToScreen(selection_controller_->GetCaretBounds()); |
} |
bool RenderWidgetHostViewAura::GetCompositionCharacterBounds( |
@@ -1732,8 +1695,7 @@ bool RenderWidgetHostViewAura::CanFocus() { |
void RenderWidgetHostViewAura::OnCaptureLost() { |
host_->LostCapture(); |
- if (touch_editing_client_) |
- touch_editing_client_->EndTouchEditing(false); |
+ selection_controller_->HideAndDisallowShowingAutomatically(); |
} |
void RenderWidgetHostViewAura::OnPaint(gfx::Canvas* canvas) { |
@@ -1803,8 +1765,6 @@ void RenderWidgetHostViewAura::GetHitTestMask(gfx::Path* mask) const { |
void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) { |
TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnKeyEvent"); |
- if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event)) |
- return; |
if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) { |
popup_child_host_view_->OnKeyEvent(event); |
@@ -1861,9 +1821,6 @@ void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) { |
void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) { |
TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnMouseEvent"); |
- if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event)) |
- return; |
- |
if (mouse_locked_) { |
aura::client::CursorClient* cursor_client = |
aura::client::GetCursorClient(window_->GetRootWindow()); |
@@ -2002,8 +1959,6 @@ void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) { |
void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) { |
TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnScrollEvent"); |
- if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event)) |
- return; |
if (event->type() == ui::ET_SCROLL) { |
#if !defined(OS_WIN) |
@@ -2033,7 +1988,9 @@ void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) { |
void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) { |
TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnTouchEvent"); |
- if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event)) |
+ |
+ selection_controller_->HandleTouchEvent(event); |
+ if (event->handled()) |
return; |
// Update the touch event first. |
@@ -2058,6 +2015,11 @@ void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) { |
void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) { |
TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnGestureEvent"); |
+ |
+ selection_controller_->HandleGestureEvent(event); |
+ if (event->handled()) |
+ return; |
+ |
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_) { |
@@ -2065,9 +2027,6 @@ void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) { |
return; |
} |
- if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event)) |
- 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) |
@@ -2115,6 +2074,104 @@ void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) { |
} |
//////////////////////////////////////////////////////////////////////////////// |
+// RenderWidgetHostViewAura, TouchSelectionControllerClientAura implementation: |
+ |
+float RenderWidgetHostViewAura::GetDeviceScaleFactor() { |
+ return current_device_scale_factor_; |
+} |
+ |
+void RenderWidgetHostViewAura::MoveCaret(const gfx::PointF& position) { |
+ host_->MoveCaret(gfx::Point(position.x(), position.y())); |
+} |
+ |
+void RenderWidgetHostViewAura::MoveRangeSelectionExtent( |
+ const gfx::PointF& extent) { |
+ RenderViewHost* rvh = RenderViewHost::From(host_); |
+ WebContentsImpl* wc = |
+ static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(rvh)); |
+ wc->MoveRangeSelectionExtent(gfx::Point(extent.x(), extent.y())); |
+} |
+ |
+void RenderWidgetHostViewAura::SelectBetweenCoordinates( |
+ const gfx::PointF& base, |
+ const gfx::PointF& extent) { |
+ RenderViewHost* rvh = RenderViewHost::From(host_); |
+ WebContentsImpl* wc = |
+ static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(rvh)); |
+ gfx::Point base_point(base.x(), base.y()); |
+ gfx::Point extent_point(extent.x(), extent.y()); |
+ wc->SelectRange(base_point, extent_point); |
+} |
+ |
+aura::Window* RenderWidgetHostViewAura::GetParentWindow() { |
+ return window_; |
+} |
+ |
+bool RenderWidgetHostViewAura::IsCommandIdEnabled(int command_id) { |
+ bool editable = GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE; |
+ bool readable = GetTextInputType() != ui::TEXT_INPUT_TYPE_PASSWORD; |
+ gfx::Range selection_range; |
+ GetSelectionRange(&selection_range); |
+ bool has_selection = !selection_range.is_empty(); |
+ switch (command_id) { |
+ case IDS_APP_CUT: |
+ return editable && readable && has_selection; |
+ case IDS_APP_COPY: |
+ return readable && has_selection; |
+ case IDS_APP_PASTE: { |
+ base::string16 result; |
+ ui::Clipboard::GetForCurrentThread()->ReadText( |
+ ui::CLIPBOARD_TYPE_COPY_PASTE, &result); |
+ return editable && !result.empty(); |
+ } |
+ case IDS_APP_DELETE: |
+ return editable && has_selection; |
+ case IDS_APP_SELECT_ALL: |
+ return true; |
+ default: |
+ return false; |
+ } |
+} |
+ |
+void RenderWidgetHostViewAura::ExecuteCommand(int command_id, int event_flags) { |
+ RenderViewHost* rvh = RenderViewHost::From(host_); |
+ WebContents* wc = WebContents::FromRenderViewHost(rvh); |
+ |
+ switch (command_id) { |
+ case IDS_APP_CUT: |
+ wc->Cut(); |
+ break; |
+ case IDS_APP_COPY: |
+ wc->Copy(); |
+ break; |
+ case IDS_APP_PASTE: |
+ wc->Paste(); |
+ break; |
+ case IDS_APP_DELETE: |
+ wc->Delete(); |
+ break; |
+ case IDS_APP_SELECT_ALL: |
+ wc->SelectAll(); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
+} |
+ |
+void RenderWidgetHostViewAura::OpenContextMenu(const gfx::PointF& point) { |
+ host_->Send(new ViewMsg_ShowContextMenu(host_->GetRoutingID(), |
+ ui::MENU_SOURCE_TOUCH_EDIT_MENU, |
+ gfx::Point(point.x(), point.y()))); |
+} |
+ |
+gfx::Rect RenderWidgetHostViewAura::ConvertRectToScreen( |
+ const gfx::RectF& rect) const { |
+ gfx::Rect r(rect.x(), rect.y(), rect.width(), rect.height()); |
+ return ConvertRectToScreen(r); |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
// RenderWidgetHostViewAura, aura::client::ActivationDelegate implementation: |
bool RenderWidgetHostViewAura::ShouldActivate() const { |
@@ -2190,8 +2247,7 @@ void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus, |
DetachFromInputMethod(); |
host_->SetInputMethodActive(false); |
- if (touch_editing_client_) |
- touch_editing_client_->EndTouchEditing(false); |
+ selection_controller_->HideAndDisallowShowingAutomatically(); |
if (overscroll_controller_) |
overscroll_controller_->Cancel(); |
@@ -2248,9 +2304,6 @@ void RenderWidgetHostViewAura::OnHostMoved(const aura::WindowTreeHost* host, |
// RenderWidgetHostViewAura, private: |
RenderWidgetHostViewAura::~RenderWidgetHostViewAura() { |
- if (touch_editing_client_) |
- touch_editing_client_->OnViewDestroyed(); |
- |
delegated_frame_host_.reset(); |
window_observer_.reset(); |
if (window_->GetHost()) |
@@ -2425,10 +2478,6 @@ void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) { |
window_->SetBounds(rect); |
host_->WasResized(); |
delegated_frame_host_->WasResized(); |
- if (touch_editing_client_) { |
- touch_editing_client_->OnSelectionOrCursorChanged(selection_anchor_, |
- selection_focus_); |
- } |
#if defined(OS_WIN) |
if (mouse_locked_) |
UpdateMouseLockRegion(); |
@@ -2529,6 +2578,14 @@ SkColorType RenderWidgetHostViewAura::PreferredReadbackFormat() { |
return kN32_SkColorType; |
} |
+void RenderWidgetHostViewAura::SelectionBoundsUpdated( |
+ const cc::ViewportSelectionBound& start, |
+ const cc::ViewportSelectionBound& end) { |
+ selection_controller_->OnSelectionBoundsChanged(start, end); |
+ if (GetInputMethod()) |
+ GetInputMethod()->OnCaretBoundsChanged(this); |
+} |
+ |
//////////////////////////////////////////////////////////////////////////////// |
// DelegatedFrameHost, public: |