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

Unified Diff: ui/views/widget/widget_interactive_uitest.cc

Issue 1108733002: Add tests for input method focusing to Widget interactive ui tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/widget/widget_interactive_uitest.cc
diff --git a/ui/views/widget/widget_interactive_uitest.cc b/ui/views/widget/widget_interactive_uitest.cc
index 9fbb62a42785ce3d54ea36d0c3b690ea460c7a9c..6ae3a6fbd58445c124490ecbbcb32648e29255ec 100644
--- a/ui/views/widget/widget_interactive_uitest.cc
+++ b/ui/views/widget/widget_interactive_uitest.cc
@@ -9,6 +9,10 @@
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/base/ime/input_method.h"
+#include "ui/base/ime/text_input_client.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"
@@ -20,18 +24,20 @@
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/controls/textfield/textfield_test_api.h"
#include "ui/views/focus/focus_manager.h"
+#include "ui/views/ime/input_method.h"
#include "ui/views/test/focus_manager_test.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/touchui/touch_selection_controller_impl.h"
+#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_delegate.h"
#include "ui/wm/public/activation_client.h"
#if defined(OS_WIN)
-#include "ui/aura/window.h"
-#include "ui/aura/window_tree_host.h"
-#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#include "ui/views/win/hwnd_util.h"
+#elif defined(USE_X11)
+#include "ui/base/x/x11_util.h"
+#include "ui/views/test/x11_property_change_waiter.h"
#endif
namespace views {
@@ -175,6 +181,31 @@ class WidgetActivationWaiter : public WidgetObserver {
DISALLOW_COPY_AND_ASSIGN(WidgetActivationWaiter);
};
+#if defined(USE_X11)
+class WidgetActivationWaiterX11 : public X11PropertyChangeWaiter {
+ public:
+ explicit WidgetActivationWaiterX11(Widget* widget, bool active)
+ : X11PropertyChangeWaiter(ui::GetX11RootWindow(), "_NET_ACTIVE_WINDOW"),
+ window_(widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget()) {
+ EXPECT_NE(active, widget->IsActive());
+ }
+
+ ~WidgetActivationWaiterX11() override {}
+
+ private:
+ // X11PropertyChangeWaiter:
+ bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override {
+ XID xid = 0;
+ ui::GetXIDProperty(ui::GetX11RootWindow(), "_NET_ACTIVE_WINDOW", &xid);
+ return xid != window_;
+ }
+
+ XID window_;
+
+ DISALLOW_COPY_AND_ASSIGN(WidgetActivationWaiterX11);
+};
+#endif
+
ui::WindowShowState GetWidgetShowState(const Widget* widget) {
// Use IsMaximized/IsMinimized/IsFullScreen instead of GetWindowPlacement
// because the former is implemented on all platforms but the latter is not.
@@ -214,6 +245,25 @@ void ShowSync(Widget* widget) {
waiter.Wait();
}
+#if defined(USE_AURA)
+void ActivatePlatformWindowSync(Widget* widget) {
tapted 2015/05/01 01:54:25 Hi There! I'd like to get these tests working on M
tapted 2015/05/01 09:10:17 Looks like ActivateSync() can do the job on Linux.
+#if defined(OS_WIN)
+ ::SetActiveWindow(
+ widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget());
+#elif defined(OS_CHROMEOS)
+ widget->Activate();
+#elif defined(USE_X11)
+ if (!widget->IsActive()) {
+ WidgetActivationWaiterX11 waiter(widget, true);
+ widget->Activate();
+ waiter.Wait();
+ }
+#else
+ ActivateSync(widget);
+#endif
+}
+#endif
+
// Calls ShowInactive() on a Widget, and spins a run loop. The goal is to give
// the OS a chance to activate a widget. However, for this case, the test
// doesn't expect that to happen, so there is nothing to wait for.
@@ -255,6 +305,25 @@ class WidgetTestInteractive : public WidgetTest {
DCHECK(controller);
return controller->context_menu_ && controller->context_menu_->visible();
}
+
+ scoped_ptr<Widget> CreateWidget() {
+#if !defined(USE_AURA)
+ return NULL;
+#else
+ scoped_ptr<Widget> widget(new Widget);
+ Widget::InitParams params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.bounds = gfx::Rect(0, 0, 200, 200);
+#if defined(OS_CHROMEOS)
+ params.native_widget = NULL;
+#else
+ params.native_widget = new DesktopNativeWidgetAura(widget.get());
+#endif
+ widget->Init(params);
+ return widget.Pass();
+#endif
+ }
};
#if defined(OS_WIN)
@@ -271,55 +340,41 @@ TEST_F(WidgetTestInteractive, DesktopNativeWidgetAuraActivationAndFocusTest) {
// Create widget 1 and expect the active window to be its window.
View* contents_view1 = new View;
contents_view1->SetFocusable(true);
- Widget widget1;
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- init_params.bounds = gfx::Rect(0, 0, 200, 200);
- init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- init_params.native_widget = new DesktopNativeWidgetAura(&widget1);
- widget1.Init(init_params);
- widget1.SetContentsView(contents_view1);
- widget1.Show();
- aura::Window* root_window1= widget1.GetNativeView()->GetRootWindow();
+ scoped_ptr<Widget> widget1(CreateWidget());
+ widget1->SetContentsView(contents_view1);
+ widget1->Show();
+ aura::Window* root_window1= widget1->GetNativeView()->GetRootWindow();
contents_view1->RequestFocus();
EXPECT_TRUE(root_window1 != NULL);
aura::client::ActivationClient* activation_client1 =
aura::client::GetActivationClient(root_window1);
EXPECT_TRUE(activation_client1 != NULL);
- EXPECT_EQ(activation_client1->GetActiveWindow(), widget1.GetNativeView());
+ EXPECT_EQ(activation_client1->GetActiveWindow(), widget1->GetNativeView());
// Create widget 2 and expect the active window to be its window.
View* contents_view2 = new View;
- Widget widget2;
- Widget::InitParams init_params2 =
- CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- init_params2.bounds = gfx::Rect(0, 0, 200, 200);
- init_params2.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- init_params2.native_widget = new DesktopNativeWidgetAura(&widget2);
- widget2.Init(init_params2);
- widget2.SetContentsView(contents_view2);
- widget2.Show();
- aura::Window* root_window2 = widget2.GetNativeView()->GetRootWindow();
+ scoped_ptr<Widget> widget2(CreateWidget());
+ widget2->SetContentsView(contents_view2);
+ widget2->Show();
+ aura::Window* root_window2 = widget2->GetNativeView()->GetRootWindow();
contents_view2->RequestFocus();
- ::SetActiveWindow(
- root_window2->GetHost()->GetAcceleratedWidget());
+ ActivatePlatformWindowSync(widget2.get());
aura::client::ActivationClient* activation_client2 =
aura::client::GetActivationClient(root_window2);
EXPECT_TRUE(activation_client2 != NULL);
- EXPECT_EQ(activation_client2->GetActiveWindow(), widget2.GetNativeView());
+ EXPECT_EQ(activation_client2->GetActiveWindow(), widget2->GetNativeView());
EXPECT_EQ(activation_client1->GetActiveWindow(),
reinterpret_cast<aura::Window*>(NULL));
// Now set focus back to widget 1 and expect the active window to be its
// window.
contents_view1->RequestFocus();
- ::SetActiveWindow(
- root_window1->GetHost()->GetAcceleratedWidget());
+ ActivatePlatformWindowSync(widget1.get());
EXPECT_EQ(activation_client2->GetActiveWindow(),
reinterpret_cast<aura::Window*>(NULL));
- EXPECT_EQ(activation_client1->GetActiveWindow(), widget1.GetNativeView());
+ EXPECT_EQ(activation_client1->GetActiveWindow(), widget1->GetNativeView());
}
#endif // defined(OS_WIN)
@@ -871,32 +926,27 @@ TEST_F(WidgetTestInteractive, MAYBE_TouchSelectionQuickMenuIsNotActivated) {
views_delegate().set_use_desktop_native_widgets(true);
#endif // !defined(OS_WIN)
- Widget widget;
- Widget::InitParams init_params =
- CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- init_params.bounds = gfx::Rect(0, 0, 200, 200);
- init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget.Init(init_params);
+ scoped_ptr<Widget> widget(CreateWidget());
Textfield* textfield = new Textfield;
textfield->SetBounds(0, 0, 200, 20);
textfield->SetText(base::ASCIIToUTF16("some text"));
- widget.GetRootView()->AddChildView(textfield);
+ widget->GetRootView()->AddChildView(textfield);
- widget.Show();
+ widget->Show();
textfield->RequestFocus();
textfield->SelectAll(true);
TextfieldTestApi textfield_test_api(textfield);
RunPendingMessages();
- ui::test::EventGenerator generator(widget.GetNativeWindow());
+ ui::test::EventGenerator generator(widget->GetNativeWindow());
generator.GestureTapAt(gfx::Point(10, 10));
ShowQuickMenuImmediately(static_cast<TouchSelectionControllerImpl*>(
textfield_test_api.touch_selection_controller()));
EXPECT_TRUE(textfield->HasFocus());
- EXPECT_TRUE(widget.IsActive());
+ EXPECT_TRUE(widget->IsActive());
EXPECT_TRUE(IsQuickMenuVisible(static_cast<TouchSelectionControllerImpl*>(
textfield_test_api.touch_selection_controller())));
}
@@ -1404,5 +1454,190 @@ TEST_F(WidgetCaptureTest, MouseEventDispatchedToRightWindow) {
}
#endif // defined(OS_WIN)
+#if defined(USE_AURA)
+// Test input method focus changes affected by top window activaction.
+TEST_F(WidgetTestInteractive, InputMethodFocus_activation) {
+ scoped_ptr<Widget> widget(CreateWidget());
+ scoped_ptr<Textfield> textfield(new Textfield);
+ widget->GetRootView()->AddChildView(textfield.get());
+ widget->Show();
+ textfield->RequestFocus();
+
+ ActivatePlatformWindowSync(widget.get());
+
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT,
+ widget->GetInputMethod()->GetTextInputType());
+
+ widget->Deactivate();
+
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
+ widget->GetInputMethod()->GetTextInputType());
+}
+
+// Test input method focus changes affected by focus changes within 1 window.
+TEST_F(WidgetTestInteractive, InputMethodFocus_1_window) {
+ scoped_ptr<Widget> widget(CreateWidget());
+ scoped_ptr<Textfield> textfield1(new Textfield);
+ scoped_ptr<Textfield> textfield2(new Textfield);
+ textfield2->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
+ widget->GetRootView()->AddChildView(textfield1.get());
+ widget->GetRootView()->AddChildView(textfield2.get());
+ widget->Show();
+
+ ActivatePlatformWindowSync(widget.get());
+
+ textfield1->RequestFocus();
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT,
+ widget->GetInputMethod()->GetTextInputType());
+
+ textfield2->RequestFocus();
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD,
+ widget->GetInputMethod()->GetTextInputType());
+
+// Window::Blur doesn't work for CrOS, because it uses NWA instead of DNWA and
+// involves the AuraTestHelper which setup the input method as DummyInputMethod.
+// Please refer to CreateWidget method above.
+#if !defined(OS_CHROMEOS)
+ aura::Window* window = widget->GetNativeWindow();
+ window->Blur();
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
+ widget->GetInputMethod()->GetTextInputType());
+
+ window->Focus();
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD,
+ widget->GetInputMethod()->GetTextInputType());
+
+ window->Blur();
+ textfield1->RequestFocus();
+ window->Focus();
+ EXPECT_TRUE(window->HasFocus());
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT,
+ widget->GetInputMethod()->GetTextInputType());
+#endif
+}
+
+// Test input method focus changes affected by focus changes cross 2 windows
+// which shares the same top window.
+TEST_F(WidgetTestInteractive, InputMethodFocus_2_windows) {
+ scoped_ptr<Widget> widget(CreateWidget());
+ widget->Show();
+
+ views::View* parent_root = new View;
+ scoped_ptr<Widget> parent(new Widget);
+ Widget::InitParams parent_params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ parent_params.ownership =
+ views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ parent_params.context = widget->GetNativeWindow();
+ parent->Init(parent_params);
+ parent->SetContentsView(parent_root);
+ parent->SetBounds(gfx::Rect(100, 100, 100, 100));
+ parent->Show();
+
+ scoped_ptr<Widget> child(new Widget());
+ Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
+ child_params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ child_params.parent = parent->GetNativeWindow();
+ child->Init(child_params);
+ child->SetBounds(gfx::Rect(0, 0, 50, 50));
+ child->Show();
+
+ scoped_ptr<Textfield> textfield_parent(new Textfield);
+ scoped_ptr<Textfield> textfield_child(new Textfield);
+ textfield_parent->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
+ parent->GetRootView()->AddChildView(textfield_parent.get());
+ child->GetRootView()->AddChildView(textfield_child.get());
+
+ EXPECT_EQ(parent->GetInputMethod(), child->GetInputMethod());
+
+ textfield_parent->RequestFocus();
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD,
+ parent->GetInputMethod()->GetTextInputType());
+
+ textfield_child->RequestFocus();
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT,
+ parent->GetInputMethod()->GetTextInputType());
+
+// Window::Blur doesn't work for CrOS, because it uses NWA instead of DNWA and
+// involves the AuraTestHelper which setup the input method as DummyInputMethod.
+// Please refer to CreateWidget method above.
+#if !defined(OS_CHROMEOS)
+ child->GetNativeWindow()->Blur();
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
+ parent->GetInputMethod()->GetTextInputType());
+
+ child->GetNativeWindow()->Focus();
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT,
+ parent->GetInputMethod()->GetTextInputType());
+
+ textfield_parent->RequestFocus();
+ parent->GetNativeWindow()->Blur();
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
+ parent->GetInputMethod()->GetTextInputType());
+
+ parent->GetNativeWindow()->Focus();
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD,
+ parent->GetInputMethod()->GetTextInputType());
+#endif
+}
+
+// Test input method focus changes affected by focus changes cross 2 top
+// windows.
+TEST_F(WidgetTestInteractive, InputMethodFocus_2_top_windows) {
+ scoped_ptr<Widget> widget1(CreateWidget());
+ scoped_ptr<Widget> widget2(CreateWidget());
+ scoped_ptr<Textfield> textfield1(new Textfield);
+ scoped_ptr<Textfield> textfield2(new Textfield);
+ textfield2->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
+ widget1->GetRootView()->AddChildView(textfield1.get());
+ widget2->GetRootView()->AddChildView(textfield2.get());
+ widget1->Show();
+ widget2->Show();
+
+ textfield1->RequestFocus();
+ textfield2->RequestFocus();
+
+ ActivatePlatformWindowSync(widget1.get());
+
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT,
+ widget1->GetInputMethod()->GetTextInputType());
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
+ widget2->GetInputMethod()->GetTextInputType());
+
+ ActivatePlatformWindowSync(widget2.get());
+
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
+ widget1->GetInputMethod()->GetTextInputType());
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD,
+ widget2->GetInputMethod()->GetTextInputType());
+}
+
+// Test input method focus changes affected by textfield's state changes.
+TEST_F(WidgetTestInteractive, InputMethodFocus_textfield) {
+ scoped_ptr<Widget> widget(CreateWidget());
+ scoped_ptr<Textfield> textfield(new Textfield);
+ widget->GetRootView()->AddChildView(textfield.get());
+ widget->Show();
+ ActivatePlatformWindowSync(widget.get());
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
+ widget->GetInputMethod()->GetTextInputType());
+
+ textfield->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
+ widget->GetInputMethod()->GetTextInputType());
+
+ textfield->RequestFocus();
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD,
+ widget->GetInputMethod()->GetTextInputType());
+
+ textfield->SetTextInputType(ui::TEXT_INPUT_TYPE_TEXT);
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT,
+ widget->GetInputMethod()->GetTextInputType());
+
+ textfield->SetReadOnly(true);
+ EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE,
+ widget->GetInputMethod()->GetTextInputType());
+}
+#endif // defined(USE_AURA)
+
} // namespace test
} // namespace views
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698