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

Unified Diff: ui/views/focus/focus_manager_unittest_win.cc

Issue 8642002: Enable FocusManager tests for Aura. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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: ui/views/focus/focus_manager_unittest_win.cc
===================================================================
--- ui/views/focus/focus_manager_unittest_win.cc (revision 0)
+++ ui/views/focus/focus_manager_unittest_win.cc (revision 0)
@@ -0,0 +1,285 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/focus/focus_manager.h"
+
+#include "base/utf_string_conversions.h"
+#include "ui/views/focus/accelerator_handler.h"
+#include "ui/views/focus/focus_manager_test.h"
+#include "ui/views/widget/widget.h"
+#include "views/controls/button/text_button.h"
+
+namespace views {
+
+namespace {
+
+class MessageTrackingView : public View {
+ public:
+ MessageTrackingView() : accelerator_pressed_(false) {
+ }
+
+ void Reset() {
+ accelerator_pressed_ = false;
+ keys_pressed_.clear();
+ keys_released_.clear();
+ }
+
+ const std::vector<ui::KeyboardCode>& keys_pressed() const {
+ return keys_pressed_;
+ }
+
+ const std::vector<ui::KeyboardCode>& keys_released() const {
+ return keys_released_;
+ }
+
+ bool accelerator_pressed() const {
+ return accelerator_pressed_;
+ }
+
+ // Overridden from View:
+ virtual bool OnKeyPressed(const KeyEvent& e) OVERRIDE {
+ keys_pressed_.push_back(e.key_code());
+ return true;
+ }
+ virtual bool OnKeyReleased(const KeyEvent& e) OVERRIDE {
+ keys_released_.push_back(e.key_code());
+ return true;
+ }
+ virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
+ accelerator_pressed_ = true;
+ return true;
+ }
+
+ private:
+ bool accelerator_pressed_;
+ std::vector<ui::KeyboardCode> keys_pressed_;
+ std::vector<ui::KeyboardCode> keys_released_;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageTrackingView);
+};
+
+} // namespace
+
+// Test that when activating/deactivating the top window, the focus is stored/
+// restored properly.
+TEST_F(FocusManagerTest, FocusStoreRestore) {
+ // Simulate an activate, otherwise the deactivate isn't going to do anything.
+ SimulateActivateWindow();
+
+ NativeTextButton* button = new NativeTextButton(NULL,
+ ASCIIToUTF16("Press me"));
+ View* view = new View();
+ view->set_focusable(true);
+
+ GetContentsView()->AddChildView(button);
+ button->SetBounds(10, 10, 200, 30);
+ GetContentsView()->AddChildView(view);
+ RunPendingMessages();
+
+ TestFocusChangeListener listener;
+ AddFocusChangeListener(&listener);
+
+ view->RequestFocus();
+ RunPendingMessages();
+ // MessageLoopForUI::current()->RunWithDispatcher(new AcceleratorHandler());
+
+ // Visual Studio 2010 has problems converting NULL to the null pointer for
+ // std::pair. See http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair
+ // It will work if we pass nullptr.
+#if defined(_MSC_VER) && _MSC_VER >= 1600
+ views::View* null_view = nullptr;
+#else
+ views::View* null_view = NULL;
+#endif
+
+ // Deacivate the window, it should store its focus.
+ SimulateDeactivateWindow();
+ EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
+ ASSERT_EQ(2, static_cast<int>(listener.focus_changes().size()));
+ EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, view));
+ EXPECT_TRUE(listener.focus_changes()[1] == ViewPair(view, null_view));
+ listener.ClearFocusChanges();
+
+ // Reactivate, focus should come-back to the previously focused view.
+ SimulateActivateWindow();
+ EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
+ ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
+ EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, view));
+ listener.ClearFocusChanges();
+
+ // Same test with a NativeControl.
+ button->RequestFocus();
+ SimulateDeactivateWindow();
+ EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
+ ASSERT_EQ(2, static_cast<int>(listener.focus_changes().size()));
+ EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view, button));
+ EXPECT_TRUE(listener.focus_changes()[1] == ViewPair(button, null_view));
+ listener.ClearFocusChanges();
+
+ SimulateActivateWindow();
+ EXPECT_EQ(button, GetFocusManager()->GetFocusedView());
+ ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
+ EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, button));
+ listener.ClearFocusChanges();
+
+ /*
+ // Now test that while the window is inactive we can change the focused view
+ // (we do that in several places).
+ SimulateDeactivateWindow();
+ // TODO: would have to mock the window being inactive (with a TestWidgetWin
+ // that would return false on IsActive()).
+ GetFocusManager()->SetFocusedView(view);
+ ::SendMessage(window_->GetNativeWindow(), WM_ACTIVATE, WA_ACTIVE, NULL);
+
+ EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
+ ASSERT_EQ(2, static_cast<int>(listener.focus_changes().size()));
+ EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(button, null_view));
+ EXPECT_TRUE(listener.focus_changes()[1] == ViewPair(null_view, view));
+ */
+}
+
+// Test that the focus manager is created successfully for the first view
+// window parented to a native dialog.
+TEST_F(FocusManagerTest, CreationForNativeRoot) {
+ // Create a window class.
+ WNDCLASSEX class_ex;
+ memset(&class_ex, 0, sizeof(class_ex));
+ class_ex.cbSize = sizeof(WNDCLASSEX);
+ class_ex.lpfnWndProc = &DefWindowProc;
+ class_ex.lpszClassName = L"TestWindow";
+ ATOM atom = RegisterClassEx(&class_ex);
+ ASSERT_TRUE(atom);
+
+ // Create a native dialog window.
+ HWND hwnd = CreateWindowEx(0, class_ex.lpszClassName, NULL,
+ WS_OVERLAPPEDWINDOW, 0, 0, 200, 200,
+ NULL, NULL, NULL, NULL);
+ ASSERT_TRUE(hwnd);
+
+ // Create a view window parented to native dialog.
+ scoped_ptr<Widget> widget1(new Widget);
+ Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.parent = hwnd;
+ params.bounds = gfx::Rect(0, 0, 100, 100);
+ params.top_level = true; // This is top level in views hierarchy.
+ widget1->Init(params);
+
+ // Get the focus manager directly from the first window. Should exist
+ // because the first window is the root widget.
+ views::FocusManager* focus_manager1 = widget1->GetFocusManager();
+ EXPECT_TRUE(focus_manager1);
+
+ // Create another view window parented to the first view window.
+ scoped_ptr<Widget> widget2(new Widget);
+ params.parent = widget1->GetNativeView();
+ params.top_level = false; // This is child widget.
+ widget2->Init(params);
+
+ // Access the shared focus manager directly from the second window.
+ views::FocusManager* focus_manager2 = widget2->GetFocusManager();
+ EXPECT_EQ(focus_manager2, focus_manager1);
+
+ // Access the shared focus manager indirectly from the first window handle.
+ gfx::NativeWindow native_window = widget1->GetNativeWindow();
+ views::Widget* widget =
+ views::Widget::GetWidgetForNativeWindow(native_window);
+ EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
+
+ // Access the shared focus manager indirectly from the second window handle.
+ native_window = widget2->GetNativeWindow();
+ widget = views::Widget::GetWidgetForNativeWindow(native_window);
+ EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
+
+ // Access the shared focus manager indirectly from the first view handle.
+ gfx::NativeView native_view = widget1->GetNativeView();
+ widget = views::Widget::GetTopLevelWidgetForNativeView(native_view);
+ EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
+
+ // Access the shared focus manager indirectly from the second view handle.
+ native_view = widget2->GetNativeView();
+ widget = views::Widget::GetTopLevelWidgetForNativeView(native_view);
+ EXPECT_EQ(widget->GetFocusManager(), focus_manager1);
+
+ DestroyWindow(hwnd);
+}
+
+// Tests that the keyup messages are eaten for accelerators.
+// Windows-only, Windows is the only platform that handles accelerators in
+// AcceleratorHandler. NativeWidgetAura/NativeWidgetGtk::OnKeyEvent handles
+// them in other configurations.
+TEST_F(FocusManagerTest, IgnoreKeyupForAccelerators) {
+ FocusManager* focus_manager = GetFocusManager();
+ MessageTrackingView* mtv = new MessageTrackingView();
+ mtv->AddAccelerator(ui::Accelerator(ui::VKEY_0, false, false, false));
+ mtv->AddAccelerator(ui::Accelerator(ui::VKEY_1, false, false, false));
+ GetContentsView()->AddChildView(mtv);
+ focus_manager->SetFocusedView(mtv);
+
+ // First send a non-accelerator key sequence.
+ PostKeyDown(ui::VKEY_9);
+ PostKeyUp(ui::VKEY_9);
+ AcceleratorHandler accelerator_handler;
+ MessageLoopForUI::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+ MessageLoopForUI::current()->RunWithDispatcher(&accelerator_handler);
+ // Make sure we get a key-up and key-down.
+ ASSERT_EQ(1U, mtv->keys_pressed().size());
+ EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[0]);
+ ASSERT_EQ(1U, mtv->keys_released().size());
+ EXPECT_EQ(ui::VKEY_9, mtv->keys_released()[0]);
+ EXPECT_FALSE(mtv->accelerator_pressed());
+ mtv->Reset();
+
+ // Same thing with repeat and more than one key at once.
+ PostKeyDown(ui::VKEY_9);
+ PostKeyDown(ui::VKEY_9);
+ PostKeyDown(ui::VKEY_8);
+ PostKeyDown(ui::VKEY_9);
+ PostKeyDown(ui::VKEY_7);
+ PostKeyUp(ui::VKEY_9);
+ PostKeyUp(ui::VKEY_7);
+ PostKeyUp(ui::VKEY_8);
+ MessageLoopForUI::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+ MessageLoopForUI::current()->RunWithDispatcher(&accelerator_handler);
+ // Make sure we get a key-up and key-down.
+ ASSERT_EQ(5U, mtv->keys_pressed().size());
+ EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[0]);
+ EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[1]);
+ EXPECT_EQ(ui::VKEY_8, mtv->keys_pressed()[2]);
+ EXPECT_EQ(ui::VKEY_9, mtv->keys_pressed()[3]);
+ EXPECT_EQ(ui::VKEY_7, mtv->keys_pressed()[4]);
+ ASSERT_EQ(3U, mtv->keys_released().size());
+ EXPECT_EQ(ui::VKEY_9, mtv->keys_released()[0]);
+ EXPECT_EQ(ui::VKEY_7, mtv->keys_released()[1]);
+ EXPECT_EQ(ui::VKEY_8, mtv->keys_released()[2]);
+ EXPECT_FALSE(mtv->accelerator_pressed());
+ mtv->Reset();
+
+ // Now send an accelerator key sequence.
+ PostKeyDown(ui::VKEY_0);
+ PostKeyUp(ui::VKEY_0);
+ MessageLoopForUI::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+ MessageLoopForUI::current()->RunWithDispatcher(&accelerator_handler);
+ EXPECT_TRUE(mtv->keys_pressed().empty());
+ EXPECT_TRUE(mtv->keys_released().empty());
+ EXPECT_TRUE(mtv->accelerator_pressed());
+ mtv->Reset();
+
+ // Same thing with repeat and more than one key at once.
+ PostKeyDown(ui::VKEY_0);
+ PostKeyDown(ui::VKEY_1);
+ PostKeyDown(ui::VKEY_1);
+ PostKeyDown(ui::VKEY_0);
+ PostKeyDown(ui::VKEY_0);
+ PostKeyUp(ui::VKEY_1);
+ PostKeyUp(ui::VKEY_0);
+ MessageLoopForUI::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+ MessageLoopForUI::current()->RunWithDispatcher(&accelerator_handler);
+ EXPECT_TRUE(mtv->keys_pressed().empty());
+ EXPECT_TRUE(mtv->keys_released().empty());
+ EXPECT_TRUE(mtv->accelerator_pressed());
+ mtv->Reset();
+}
+
+} // namespace views
Property changes on: ui\views\focus\focus_manager_unittest_win.cc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698