| 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..4ed2eefd4baa98ff0ecef5cd1928fa306d36d7fa
|
| --- /dev/null
|
| +++ b/ui/views/widget/native_widget_layer_reorderer_aura_unittest.cc
|
| @@ -0,0 +1,307 @@
|
| +// 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 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();
|
| +
|
| + EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window));
|
| + EXPECT_EQ("w1 w2 v",
|
| + ui::test::ChildLayerNamesAsString(*parent_window->layer()));
|
| +
|
| + View* host_view1 = new View();
|
| + contents_view->AddChildViewAt(host_view1, 0);
|
| + w1->GetNativeView()->SetProperty(kHostViewKey, host_view1);
|
| + 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");
|
| + 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 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();
|
| +}
|
| +
|
| +// Test that in the process of reordering, no windows are stacked above a window
|
| +// with a NULL layer delegate.
|
| +TEST_F(NativeWidgetLayerReordererTest, NULLLayerDelegate) {
|
| + 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();
|
| +}
|
| +
|
| +} // namespace
|
| +} // namespace views
|
|
|