Index: ui/views/widget/native_widget_layer_reorderer_aura_unittest.cc |
diff --git a/ui/views/widget/native_widget_layer_reorderer_aura_unittest.cc b/ui/views/widget/native_widget_layer_reorderer_aura_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c6e5ec1b9dfe46b8fee515c2a19a5eed48afbd7b |
--- /dev/null |
+++ b/ui/views/widget/native_widget_layer_reorderer_aura_unittest.cc |
@@ -0,0 +1,202 @@ |
+// Copyright (c) 2012 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/aura/root_window.h" |
+#include "ui/aura/test/aura_test_base.h" |
+#include "ui/aura/test/test_windows.h" |
+#include "ui/aura/window.h" |
+#include "ui/compositor/layer.h" |
+#include "ui/compositor/test/test_layers.h" |
+#include "ui/views/view.h" |
+#include "ui/views/view_constants_aura.h" |
+#include "ui/views/widget/widget.h" |
+ |
+namespace views { |
+namespace { |
+ |
+// Creates a control widget with the passed in parameters. |
+// The caller takes ownership of the returned widget. |
+Widget* CreateControlWidget(aura::Window* parent, const gfx::Rect& bounds) { |
+ Widget::InitParams params(Widget::InitParams::TYPE_CONTROL); |
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
+ params.parent = parent; |
+ params.bounds = bounds; |
+ Widget* widget = new Widget(); |
+ widget->Init(params); |
+ return widget; |
+} |
+ |
+// Sets the name of |window| and |window|'s layer to |name|. |
+void SetWindowAndLayerName(aura::Window* window, const std::string& name) { |
+ window->SetName(name); |
+ window->layer()->set_name(name); |
+} |
+ |
+// Returns a string containing the name of each of the child windows (bottommost |
+// first) of |parent|. The format of the string is "name1 name2 name3 ...". |
+std::string ChildWindowNamesAsString(const aura::Window& parent) { |
+ std::string names; |
+ typedef std::vector<aura::Window*> Windows; |
+ for (Windows::const_iterator it = parent.children().begin(); |
+ it != parent.children().end(); ++it) { |
+ if (!names.empty()) |
+ names += " "; |
+ names += (*it)->name(); |
+ } |
+ return names; |
+} |
+ |
+typedef aura::test::AuraTestBase NativeWidgetLayerReordererTest; |
+ |
+// Test that views with layers and views with attached windows are reordered |
+// according to the view hierarchy. |
+TEST_F(NativeWidgetLayerReordererTest, Basic) { |
+ scoped_ptr<Widget> parent(CreateControlWidget(root_window(), |
+ gfx::Rect(0, 0, 100, 100))); |
+ parent->Show(); |
+ aura::Window* parent_window = parent->GetNativeWindow(); |
+ |
+ View* contents_view = new View(); |
+ parent->SetContentsView(contents_view); |
+ |
+ // 1) Test that layers for views and layers for windows attached to a host |
+ // view are stacked below the layers for any windows not attached to a host |
+ // view. |
+ View* v = new View(); |
+ v->SetPaintToLayer(true); |
+ v->layer()->set_name("v"); |
+ contents_view->AddChildView(v); |
+ |
+ scoped_ptr<Widget> w1(CreateControlWidget(parent_window, |
+ gfx::Rect(0, 1, 100, 101))); |
+ SetWindowAndLayerName(w1->GetNativeView(), "w1"); |
+ w1->Show(); |
+ scoped_ptr<Widget> w2(CreateControlWidget(parent_window, |
+ gfx::Rect(0, 2, 100, 102))); |
+ SetWindowAndLayerName(w2->GetNativeView(), "w2"); |
+ w2->Show(); |
+ |
+ EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("v w1 w2", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ View* host_view2 = new View(); |
+ contents_view->AddChildView(host_view2); |
+ w2->GetNativeView()->SetProperty(kHostViewKey, host_view2); |
+ EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("v w2 w1", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ View* host_view1 = new View(); |
+ w1->GetNativeView()->SetProperty(kHostViewKey, host_view1); |
+ contents_view->AddChildViewAt(host_view1, 0); |
+ EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w1 v w2", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ // 2) Test the z-order of the windows and layers as a result of reordering the |
+ // views. |
+ contents_view->RemoveChildView(host_view1); |
+ contents_view->AddChildView(host_view1); |
+ EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("v w2 w1", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ contents_view->ReorderChildView(host_view2, -1); |
+ EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("v w1 w2", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ // 3) Test the z-order of the windows and layers as a result of reordering the |
+ // views in situations where the window order remains unchanged. |
+ contents_view->ReorderChildView(v, -1); |
+ EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w1 w2 v", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ contents_view->ReorderChildView(host_view2, -1); |
+ EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w1 v w2", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ // Work around for bug in NativeWidgetAura. |
+ // TODO: fix bug and remove this. |
+ parent->Close(); |
+} |
+ |
+// It is possible to attach a window to a view which has a parent layer (other |
+// than the widget layer). In this case, the parent layer of the host view and |
+// the parent layer of the attached window are different. Test that the layers |
+// and windows are properly reordered in this case. |
+TEST_F(NativeWidgetLayerReordererTest, HostViewParentHasLayer) { |
+ scoped_ptr<Widget> parent(CreateControlWidget(root_window(), |
+ gfx::Rect(0, 0, 100, 100))); |
+ parent->Show(); |
+ aura::Window* parent_window = parent->GetNativeWindow(); |
+ |
+ View* contents_view = new View(); |
+ parent->SetContentsView(contents_view); |
+ |
+ // Create the following view hierarchy. (*) denotes views which paint to a |
+ // layer. |
+ // |
+ // contents_view |
+ // +-- v1 |
+ // +-- v11* |
+ // +-- v12 (attached window) |
+ // +-- v13* |
+ // +--v2* |
+ |
+ View* v1 = new View(); |
+ contents_view->AddChildView(v1); |
+ |
+ View* v11 = new View(); |
+ v11->SetPaintToLayer(true); |
+ v11->layer()->set_name("v11"); |
+ v1->AddChildView(v11); |
+ |
+ scoped_ptr<Widget> w(CreateControlWidget(parent_window, |
+ gfx::Rect(0, 1, 100, 101))); |
+ SetWindowAndLayerName(w->GetNativeView(), "w"); |
+ w->Show(); |
+ |
+ View* v12 = new View(); |
+ v1->AddChildView(v12); |
+ w->GetNativeView()->SetProperty(kHostViewKey, v12); |
+ |
+ View* v13 = new View(); |
+ v13->SetPaintToLayer(true); |
+ v13->layer()->set_name("v13"); |
+ v1->AddChildView(v13); |
+ |
+ View* v2 = new View(); |
+ v2->SetPaintToLayer(true); |
+ v2->layer()->set_name("v2"); |
+ contents_view->AddChildView(v2); |
+ |
+ // Test intial state. |
+ EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("v11 w v13 v2", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ // |w|'s layer should be stacked above |v1|'s layer. |
+ v1->SetPaintToLayer(true); |
+ v1->layer()->set_name("v1"); |
+ EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("v1 w v2", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ // Test moving the host view from one view with a layer to another. |
+ v2->AddChildView(v12); |
+ EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("v1 v2 w", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ // Work around for bug in NativeWidgetAura. |
+ // TODO: fix bug and remove this. |
+ parent->Close(); |
+} |
+ |
+} // namespace |
+} // namespace views |