summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormohsen@chromium.org <mohsen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-12 17:36:57 +0000
committermohsen@chromium.org <mohsen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-12 17:36:57 +0000
commit16d2abe7e4acc6cd66cdf1c4cd83f8d1e9d58f29 (patch)
tree14913c480362c94ca07a476b4d3906e68a6155ea
parent89bd27d15ea08f443bf3d8bea64b15265d9cc66d (diff)
downloadchromium_src-16d2abe7e4acc6cd66cdf1c4cd83f8d1e9d58f29.zip
chromium_src-16d2abe7e4acc6cd66cdf1c4cd83f8d1e9d58f29.tar.gz
chromium_src-16d2abe7e4acc6cd66cdf1c4cd83f8d1e9d58f29.tar.bz2
Change type of touch selection handles to POPUP
Previously, touch selection handles were of type TOOLTIP which in Chrome OS would put them above almost everything else (e.g. menus and shelf; see associated bugs). With this patch they are changed to type POPUP and made transient children of their top-level parent, so they are positioned correctly above their parent window, but below menus and shelf. Also, they are not clipped to their parent window in Windows Aura anymore, as now they have their own HWND. BUG=303870,316286 Review URL: https://codereview.chromium.org/177173007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@263539 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/views/touchui/touch_selection_controller_impl.cc9
-rw-r--r--ui/views/touchui/touch_selection_controller_impl.h1
-rw-r--r--ui/views/touchui/touch_selection_controller_impl_unittest.cc71
3 files changed, 74 insertions, 7 deletions
diff --git a/ui/views/touchui/touch_selection_controller_impl.cc b/ui/views/touchui/touch_selection_controller_impl.cc
index e5a6b7f..1e8c2f5 100644
--- a/ui/views/touchui/touch_selection_controller_impl.cc
+++ b/ui/views/touchui/touch_selection_controller_impl.cc
@@ -72,11 +72,11 @@ views::Widget* CreateTouchSelectionPopupWidget(
gfx::NativeView context,
views::WidgetDelegate* widget_delegate) {
views::Widget* widget = new views::Widget;
- views::Widget::InitParams params(views::Widget::InitParams::TYPE_TOOLTIP);
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
params.can_activate = false;
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.context = context;
+ params.parent = context;
params.delegate = widget_delegate;
widget->Init(params);
SetShadowType(widget->GetNativeView(), wm::SHADOW_TYPE_NONE);
@@ -156,7 +156,6 @@ class TouchSelectionControllerImpl::EditingHandleView
draw_invisible_(false) {
widget_.reset(CreateTouchSelectionPopupWidget(context, this));
widget_->SetContentsView(this);
- widget_->SetAlwaysOnTop(true);
aura::Window* window = widget_->GetNativeWindow();
window->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
@@ -582,6 +581,10 @@ void TouchSelectionControllerImpl::HideContextMenu() {
context_menu_timer_.Stop();
}
+gfx::NativeView TouchSelectionControllerImpl::GetCursorHandleNativeView() {
+ return cursor_handle_->GetWidget()->GetNativeView();
+}
+
gfx::Point TouchSelectionControllerImpl::GetSelectionHandle1Position() {
return selection_handle_1_->GetScreenPosition();
}
diff --git a/ui/views/touchui/touch_selection_controller_impl.h b/ui/views/touchui/touch_selection_controller_impl.h
index c7694bf..7c1144e 100644
--- a/ui/views/touchui/touch_selection_controller_impl.h
+++ b/ui/views/touchui/touch_selection_controller_impl.h
@@ -81,6 +81,7 @@ class VIEWS_EXPORT TouchSelectionControllerImpl
void HideContextMenu();
// Convenience methods for testing.
+ gfx::NativeView GetCursorHandleNativeView();
gfx::Point GetSelectionHandle1Position();
gfx::Point GetSelectionHandle2Position();
gfx::Point GetCursorHandlePosition();
diff --git a/ui/views/touchui/touch_selection_controller_impl_unittest.cc b/ui/views/touchui/touch_selection_controller_impl_unittest.cc
index f79020a..41bf733 100644
--- a/ui/views/touchui/touch_selection_controller_impl_unittest.cc
+++ b/ui/views/touchui/touch_selection_controller_impl_unittest.cc
@@ -103,13 +103,17 @@ class TouchSelectionControllerImplTest : public ViewsTestBase {
protected:
static bool IsCursorHandleVisibleFor(
ui::TouchSelectionController* controller) {
- return static_cast<TouchSelectionControllerImpl*>(
- controller)->IsCursorHandleVisible();
+ TouchSelectionControllerImpl* impl =
+ static_cast<TouchSelectionControllerImpl*>(controller);
+ return impl->IsCursorHandleVisible();
+ }
+
+ gfx::Rect GetCursorRect(const gfx::SelectionModel& sel) {
+ return textfield_->GetRenderText()->GetCursorBounds(sel, true);
}
gfx::Point GetCursorPosition(const gfx::SelectionModel& sel) {
- gfx::RenderText* render_text = textfield_->GetRenderText();
- gfx::Rect cursor_bounds = render_text->GetCursorBounds(sel, true);
+ gfx::Rect cursor_bounds = GetCursorRect(sel);
return gfx::Point(cursor_bounds.x(), cursor_bounds.y());
}
@@ -118,6 +122,14 @@ class TouchSelectionControllerImplTest : public ViewsTestBase {
textfield_->touch_selection_controller_.get());
}
+ void StartTouchEditing() {
+ textfield_->CreateTouchSelectionControllerAndNotifyIt();
+ }
+
+ void EndTouchEditing() {
+ textfield_->touch_selection_controller_.reset();
+ }
+
void SimulateSelectionHandleDrag(gfx::Point p, int selection_handle) {
TouchSelectionControllerImpl* controller = GetSelectionController();
// Do the work of OnMousePressed().
@@ -135,6 +147,10 @@ class TouchSelectionControllerImplTest : public ViewsTestBase {
controller->dragging_handle_ = NULL;
}
+ gfx::NativeView GetCursorHandleNativeView() {
+ return GetSelectionController()->GetCursorHandleNativeView();
+ }
+
gfx::Point GetSelectionHandle1Position() {
return GetSelectionController()->GetSelectionHandle1Position();
}
@@ -163,6 +179,15 @@ class TouchSelectionControllerImplTest : public ViewsTestBase {
return textfield_->GetRenderText();
}
+ gfx::Point GetCursorHandleDragPoint() {
+ gfx::Point point = GetCursorHandlePosition();
+ const gfx::SelectionModel& sel = textfield_->GetSelectionModel();
+ int cursor_height = GetCursorRect(sel).height();
+ point.Offset(GetHandleImageSize().width() / 2 + kPadding,
+ GetHandleImageSize().height() / 2 + cursor_height);
+ return point;
+ }
+
Widget* textfield_widget_;
Widget* widget_;
@@ -644,4 +669,42 @@ TEST_F(TouchSelectionControllerImplTest,
touch_selection_controller.reset();
}
+TEST_F(TouchSelectionControllerImplTest, HandlesStackAboveParent) {
+ ui::EventTarget* root = GetContext();
+ ui::EventTargeter* targeter = root->GetEventTargeter();
+
+ // Create the first window containing a Views::Textfield.
+ CreateTextfield();
+ aura::Window* window1 = textfield_widget_->GetNativeView();
+
+ // Start touch editing, check that the handle is above the first window, and
+ // end touch editing.
+ StartTouchEditing();
+ gfx::Point test_point = GetCursorHandleDragPoint();
+ ui::MouseEvent test_event1(ui::ET_MOUSE_MOVED, test_point, test_point,
+ ui::EF_NONE, ui::EF_NONE);
+ EXPECT_EQ(GetCursorHandleNativeView(),
+ targeter->FindTargetForEvent(root, &test_event1));
+ EndTouchEditing();
+
+ // Create the second (empty) window over the first one.
+ CreateWidget();
+ aura::Window* window2 = widget_->GetNativeView();
+
+ // Start touch editing (in the first window) and check that the handle is not
+ // above the second window.
+ StartTouchEditing();
+ ui::MouseEvent test_event2(ui::ET_MOUSE_MOVED, test_point, test_point,
+ ui::EF_NONE, ui::EF_NONE);
+ EXPECT_EQ(window2, targeter->FindTargetForEvent(root, &test_event2));
+
+ // Move the first window to top and check that the handle is kept above the
+ // first window.
+ window1->GetRootWindow()->StackChildAtTop(window1);
+ ui::MouseEvent test_event3(ui::ET_MOUSE_MOVED, test_point, test_point,
+ ui::EF_NONE, ui::EF_NONE);
+ EXPECT_EQ(GetCursorHandleNativeView(),
+ targeter->FindTargetForEvent(root, &test_event3));
+}
+
} // namespace views