Index: ui/views/widget/native_widget_aura_unittest.cc |
diff --git a/ui/views/widget/native_widget_aura_unittest.cc b/ui/views/widget/native_widget_aura_unittest.cc |
index 13e7de542ef160994b9f2b19008ccf7aa1eb7de4..3b9cea77020e62d56e83a9f027ed1655144ec190 100644 |
--- a/ui/views/widget/native_widget_aura_unittest.cc |
+++ b/ui/views/widget/native_widget_aura_unittest.cc |
@@ -16,8 +16,10 @@ |
#include "ui/aura/test/aura_test_helper.h" |
#include "ui/aura/window.h" |
#include "ui/base/events/event.h" |
+#include "ui/compositor/test/test_layers.h" |
#include "ui/gfx/screen.h" |
#include "ui/views/layout/fill_layout.h" |
+#include "ui/views/view_constants_aura.h" |
#include "ui/views/widget/root_view.h" |
#include "ui/views/widget/widget_delegate.h" |
@@ -32,6 +34,38 @@ NativeWidgetAura* Init(aura::Window* parent, Widget* widget) { |
return static_cast<NativeWidgetAura*>(widget->native_widget()); |
} |
+// 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; |
+} |
+ |
class NativeWidgetAuraTest : public testing::Test { |
public: |
NativeWidgetAuraTest() {} |
@@ -328,12 +362,8 @@ TEST_F(NativeWidgetAuraTest, PreferViewLayersToChildWindows) { |
parent->SetBounds(gfx::Rect(0, 0, 400, 400)); |
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, 200, 200)); |
+ scoped_ptr<Widget> child(CreateControlWidget(parent->GetNativeWindow(), |
+ gfx::Rect(0, 0, 200, 200))); |
child->Show(); |
// Point is over |child|. |
@@ -376,6 +406,255 @@ TEST_F(NativeWidgetAuraTest, PreferViewLayersToChildWindows) { |
parent->Close(); |
} |
+// Test that ReorderLayers() reorders layers according to the view hierarchy. |
+TEST_F(NativeWidgetAuraTest, ReorderLayers) { |
+ 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 above 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(); |
+ parent->ReorderLayers(); |
+ |
+ EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w1 w2 v", |
+ 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("w2 w1", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w2 w1 v", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ View* host_view2 = new View(); |
+ w2->GetNativeView()->SetProperty(kHostViewKey, host_view2); |
+ contents_view->AddChildView(host_view2); |
+ 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())); |
+ |
+ // 4) Test the z-order of the windows and layers as a result of Recreating |
+ // layers. |
+ scoped_ptr<ui::Layer> old_w1_layer(w1->GetNativeView()->RecreateLayer()); |
+ old_w1_layer->set_name("old_w1"); |
+ w1->GetNativeView()->layer()->set_name("w1"); |
+ parent->ReorderLayers(); |
+ EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("old_w1 w1 v w2", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ scoped_ptr<ui::Layer> old_view_layer(v->RecreateLayer()); |
+ v->layer()->set_name("v"); |
+ old_view_layer->set_name("old_v"); |
+ EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("old_w1 old_v 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 the behavior |
+// of ReorderLayers() in this case. |
+TEST_F(NativeWidgetAuraTest, ReorderLayersHostViewParentHasLayer) { |
+ 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 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())); |
+ |
+ // Work around for bug in NativeWidgetAura. |
+ // TODO: fix bug and remove this. |
+ parent->Close(); |
+} |
+ |
+// Test that ReorderLayers() does not stack any windows above a window with a |
+// NULL delegate. |
+TEST_F(NativeWidgetAuraTest, ReorderLayersNULLDelegate) { |
+ 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); |
+ |
+ // Setup and test initial state. |
+ 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(); |
+ scoped_ptr<Widget> w3(CreateControlWidget(parent_window, |
+ gfx::Rect(0, 3, 100, 103))); |
+ SetWindowAndLayerName(w3->GetNativeView(), "w3"); |
+ w3->Show(); |
+ |
+ View* v = new View(); |
+ v->SetPaintToLayer(true); |
+ v->layer()->set_name("v"); |
+ contents_view->AddChildView(v); |
+ |
+ View* host_view = new View(); |
+ w3->GetNativeView()->SetProperty(views::kHostViewKey, host_view); |
+ contents_view->AddChildView(host_view); |
+ |
+ EXPECT_EQ("w1 w2 w3", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w1 w2 v w3", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ // 1) Test that the reordered layers are stacked below the layer with a NULL |
+ // delegate. The handling for a layer with a NULL delegate which does not |
+ // belong to a window is different and is tested in (2). |
+ w1->GetNativeView()->layer()->set_delegate(NULL); |
+ parent_window->StackChildAtTop(w1->GetNativeView()); |
+ EXPECT_EQ("w2 w3 w1", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w2 v w3 w1", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ contents_view->ReorderChildView(v, -1); |
+ EXPECT_EQ("w2 w3 w1", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w2 w3 v w1", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ contents_view->ReorderChildView(host_view, -1); |
+ EXPECT_EQ("w2 w3 w1", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w2 v w3 w1", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ w2->GetNativeView()->layer()->set_delegate(NULL); |
+ parent_window->StackChildAtTop(w2->GetNativeView()); |
+ contents_view->ReorderChildView(v, -1); |
+ EXPECT_EQ("w3 w2 w1", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w3 v w2 w1", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ // 2) Test that layers with NULL delegates which do not belong to a window |
+ // do not get special handling. |
+ w1->GetNativeView()->layer()->set_delegate(w1->GetNativeView()); |
+ w2->GetNativeView()->layer()->set_delegate(w2->GetNativeView()); |
+ |
+ scoped_ptr<ui::Layer> misc_layer(new ui::Layer(ui::LAYER_NOT_DRAWN)); |
+ misc_layer->set_name("l"); |
+ parent_window->layer()->Add(misc_layer.get()); |
+ v->layer()->set_delegate(NULL); |
+ |
+ contents_view->ReorderChildView(host_view, -1); |
+ EXPECT_EQ("w2 w1 w3", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w2 w1 l v w3", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ contents_view->ReorderChildView(v, -1); |
+ EXPECT_EQ("w2 w1 w3", ChildWindowNamesAsString(*parent_window)); |
+ EXPECT_EQ("w2 w1 l w3 v", |
+ ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
+ |
+ // Work around for bug in NativeWidgetAura. |
+ // TODO: fix bug and remove this. |
+ parent->Close(); |
+} |
+ |
// Verifies that widget->FlashFrame() sets aura::client::kDrawAttentionKey, |
// and activating the window clears it. |
TEST_F(NativeWidgetAuraTest, FlashFrame) { |