diff options
author | georgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-07 00:55:16 +0000 |
---|---|---|
committer | georgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-07 00:55:16 +0000 |
commit | bda9556c63579835dd14055a048f4e2094e7b3f5 (patch) | |
tree | f215d883f2ded85f48bc14d27edd4048f12c364b /views/view_unittest.cc | |
parent | c83c9e683a9376cea1ef675bfe92f7dbb98d45f5 (diff) | |
download | chromium_src-bda9556c63579835dd14055a048f4e2094e7b3f5.zip chromium_src-bda9556c63579835dd14055a048f4e2094e7b3f5.tar.gz chromium_src-bda9556c63579835dd14055a048f4e2094e7b3f5.tar.bz2 |
Addded notification when ancestor gets changed. So windows that lack focus manager, because of being
created on inactive tab, could do the necessary work when focus manager is actually attached.
This is relevant for Windows only, but some support functions (FindAllRootViews) could be useful for
other architectures as well.
BUG=22481
TEST=in the bug
Review URL: http://codereview.chromium.org/492025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35675 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/view_unittest.cc')
-rw-r--r-- | views/view_unittest.cc | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/views/view_unittest.cc b/views/view_unittest.cc index 605d4838..1f4cfc1 100644 --- a/views/view_unittest.cc +++ b/views/view_unittest.cc @@ -16,6 +16,7 @@ #if defined(OS_WIN) #include "views/controls/button/native_button_win.h" #endif +#include "views/controls/native/native_view_host.h" #include "views/controls/scroll_view.h" #include "views/controls/textfield/textfield.h" #include "views/event.h" @@ -59,6 +60,9 @@ class ViewTest : public testing::Test { #endif } + void RunPendingMessages() { + message_loop_.RunAllPending(); + } private: MessageLoopForUI message_loop_; }; @@ -1207,3 +1211,138 @@ TEST_F(ViewTest, ChangeVisibility) { native->SetVisible(true); } */ + +//////////////////////////////////////////////////////////////////////////////// +// Native view hierachy +//////////////////////////////////////////////////////////////////////////////// +class TestNativeViewHierarchy : public views::View { + public: + TestNativeViewHierarchy() { + } + + virtual void NativeViewHierarchyChanged(bool attached, + gfx::NativeView native_view, + RootView* root_view) { + NotificationInfo info; + info.attached = attached; + info.native_view = native_view; + info.root_view = root_view; + notifications_.push_back(info); + }; + struct NotificationInfo { + bool attached; + gfx::NativeView native_view; + RootView* root_view; + }; + static const size_t kTotalViews = 2; + std::vector<NotificationInfo> notifications_; +}; + +class TestChangeNativeViewHierarchy { + public: + explicit TestChangeNativeViewHierarchy(ViewTest *view_test) { + view_test_ = view_test; + native_host_ = new views::NativeViewHost(); + host_ = view_test->CreateWidget(); + host_->Init(NULL, gfx::Rect(0, 0, 500, 300)); + host_->GetRootView()->AddChildView(native_host_); + for (size_t i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) { + windows_[i] = view_test->CreateWidget(); + windows_[i]->Init(host_->GetNativeView(), gfx::Rect(0, 0, 500, 300)); + root_views_[i] = windows_[i]->GetRootView(); + test_views_[i] = new TestNativeViewHierarchy; + root_views_[i]->AddChildView(test_views_[i]); + } + } + + ~TestChangeNativeViewHierarchy() { + for (size_t i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) { + windows_[i]->Close(); + } + host_->Close(); + // Will close and self-delete widgets - no need to manually delete them. + view_test_->RunPendingMessages(); + } + + void CheckEnumeratingRootViews() { + std::vector<RootView*> enumerated_root_views; +#if defined(OS_WIN) + views::Widget::FindAllRootViews(host_->GetNativeView(), + &enumerated_root_views); +#else + // host_->GetNativeView() returns gfx::NativeView which is GtkWidget on + // systems other than Windows and views::Widget::FindAllRootViews() + // requires GtkWindow. + if (host_->GetWindow()) { + views::Widget::FindAllRootViews(host_->GetWindow()->GetNativeWindow(), + &enumerated_root_views); + } else { + return; + } +#endif + EXPECT_EQ(TestNativeViewHierarchy::kTotalViews + 1, + enumerated_root_views.size()); + // Unfortunately there is no guarantee the sequence of views here so always + // go through all of them. + for (std::vector<RootView*>::iterator i = enumerated_root_views.begin(); + i != enumerated_root_views.end(); ++i) { + if (host_->GetRootView() == *i) + continue; + size_t j; + for (j = 0; j < TestNativeViewHierarchy::kTotalViews; ++j) + if (root_views_[j] == *i) + break; + // EXPECT_LT/GT/GE() fails to compile with class-defined constants + // with gcc, with error + // "error: undefined reference to 'TestNativeViewHierarchy::kTotalViews'" + // so I forced to use EXPECT_TRUE() instead. + EXPECT_TRUE(TestNativeViewHierarchy::kTotalViews > j); + } + } + + void CheckChangingHierarhy() { + size_t i; + for (i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) { + // TODO(georgey): use actual hierarchy changes to send notifications. + root_views_[i]->NotifyNativeViewHierarchyChanged(false, + host_->GetNativeView()); + root_views_[i]->NotifyNativeViewHierarchyChanged(true, + host_->GetNativeView()); + } + for (i = 0; i < TestNativeViewHierarchy::kTotalViews; ++i) { + ASSERT_EQ(static_cast<size_t>(2), test_views_[i]->notifications_.size()); + EXPECT_FALSE(test_views_[i]->notifications_[0].attached); + EXPECT_EQ(host_->GetNativeView(), + test_views_[i]->notifications_[0].native_view); + EXPECT_EQ(root_views_[i], test_views_[i]->notifications_[0].root_view); + EXPECT_TRUE(test_views_[i]->notifications_[1].attached); + EXPECT_EQ(host_->GetNativeView(), + test_views_[i]->notifications_[1].native_view); + EXPECT_EQ(root_views_[i], test_views_[i]->notifications_[1].root_view); + } + } + + views::NativeViewHost* native_host_; + views::Widget* host_; + views::Widget* windows_[TestNativeViewHierarchy::kTotalViews]; + views::RootView* root_views_[TestNativeViewHierarchy::kTotalViews]; + TestNativeViewHierarchy* test_views_[TestNativeViewHierarchy::kTotalViews]; + ViewTest* view_test_; +}; + +TEST_F(ViewTest, ChangeNativeViewHierarchyFindRoots) { + // TODO(georgey): Fix the test for Linux +#if defined(OS_WIN) + TestChangeNativeViewHierarchy test(this); + test.CheckEnumeratingRootViews(); +#endif +} + +TEST_F(ViewTest, ChangeNativeViewHierarchyChangeHierarchy) { + // TODO(georgey): Fix the test for Linux +#if defined(OS_WIN) + TestChangeNativeViewHierarchy test(this); + test.CheckChangingHierarhy(); +#endif +} + |