1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/aura/test/aura_test_base.h"
6 #include "ui/aura/test/test_windows.h"
7 #include "ui/aura/window.h"
8 #include "ui/aura/window_event_dispatcher.h"
9 #include "ui/compositor/layer.h"
10 #include "ui/compositor/test/test_layers.h"
11 #include "ui/views/view.h"
12 #include "ui/views/view_constants_aura.h"
13 #include "ui/views/widget/widget.h"
18 // Creates a control widget with the passed in parameters.
19 // The caller takes ownership of the returned widget.
20 Widget
* CreateControlWidget(aura::Window
* parent
, const gfx::Rect
& bounds
) {
21 Widget::InitParams
params(Widget::InitParams::TYPE_CONTROL
);
22 params
.ownership
= views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
23 params
.parent
= parent
;
24 params
.bounds
= bounds
;
25 Widget
* widget
= new Widget();
30 // Sets the name of |window| and |window|'s layer to |name|.
31 void SetWindowAndLayerName(aura::Window
* window
, const std::string
& name
) {
32 window
->SetName(name
);
33 window
->layer()->set_name(name
);
36 // Returns a string containing the name of each of the child windows (bottommost
37 // first) of |parent|. The format of the string is "name1 name2 name3 ...".
38 std::string
ChildWindowNamesAsString(const aura::Window
& parent
) {
40 typedef std::vector
<aura::Window
*> Windows
;
41 for (Windows::const_iterator it
= parent
.children().begin();
42 it
!= parent
.children().end(); ++it
) {
45 names
+= (*it
)->name();
50 typedef aura::test::AuraTestBase WindowReordererTest
;
52 // Test that views with layers and views with associated windows are reordered
53 // according to the view hierarchy.
54 TEST_F(WindowReordererTest
, Basic
) {
55 scoped_ptr
<Widget
> parent(CreateControlWidget(root_window(),
56 gfx::Rect(0, 0, 100, 100)));
58 aura::Window
* parent_window
= parent
->GetNativeWindow();
60 View
* contents_view
= new View();
61 parent
->SetContentsView(contents_view
);
63 // 1) Test that layers for views and layers for windows associated to a host
64 // view are stacked below the layers for any windows not associated to a host
67 v
->SetPaintToLayer(true);
68 v
->layer()->set_name("v");
69 contents_view
->AddChildView(v
);
71 scoped_ptr
<Widget
> w1(CreateControlWidget(parent_window
,
72 gfx::Rect(0, 1, 100, 101)));
73 SetWindowAndLayerName(w1
->GetNativeView(), "w1");
75 scoped_ptr
<Widget
> w2(CreateControlWidget(parent_window
,
76 gfx::Rect(0, 2, 100, 102)));
77 SetWindowAndLayerName(w2
->GetNativeView(), "w2");
80 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window
));
82 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
84 View
* host_view2
= new View();
85 contents_view
->AddChildView(host_view2
);
86 w2
->GetNativeView()->SetProperty(kHostViewKey
, host_view2
);
87 EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window
));
89 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
91 View
* host_view1
= new View();
92 w1
->GetNativeView()->SetProperty(kHostViewKey
, host_view1
);
93 contents_view
->AddChildViewAt(host_view1
, 0);
94 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window
));
96 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
98 // 2) Test the z-order of the windows and layers as a result of reordering the
100 contents_view
->ReorderChildView(host_view1
, -1);
101 EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window
));
103 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
105 contents_view
->ReorderChildView(host_view2
, -1);
106 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window
));
108 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
110 // 3) Test the z-order of the windows and layers as a result of reordering the
111 // views in situations where the window order remains unchanged.
112 contents_view
->ReorderChildView(v
, -1);
113 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window
));
115 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
117 contents_view
->ReorderChildView(host_view2
, -1);
118 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window
));
120 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
122 // Work around for bug in NativeWidgetAura.
123 // TODO: fix bug and remove this.
127 // Test that different orderings of:
128 // - adding a window to a parent widget
129 // - adding a "host" view to a parent widget
130 // - associating the "host" view and window
131 // all correctly reorder the child windows and layers.
132 TEST_F(WindowReordererTest
, Association
) {
133 scoped_ptr
<Widget
> parent(CreateControlWidget(root_window(),
134 gfx::Rect(0, 0, 100, 100)));
136 aura::Window
* parent_window
= parent
->GetNativeWindow();
138 View
* contents_view
= new View();
139 parent
->SetContentsView(contents_view
);
141 aura::Window
* w1
= aura::test::CreateTestWindowWithId(0,
142 parent
->GetNativeWindow());
143 SetWindowAndLayerName(w1
, "w1");
145 aura::Window
* w2
= aura::test::CreateTestWindowWithId(0, NULL
);
146 SetWindowAndLayerName(w2
, "w2");
148 View
* host_view2
= new View();
150 // 1) Test that parenting the window to the parent widget last results in a
151 // correct ordering of child windows and layers.
152 contents_view
->AddChildView(host_view2
);
153 w2
->SetProperty(views::kHostViewKey
, host_view2
);
154 EXPECT_EQ("w1", ChildWindowNamesAsString(*parent_window
));
156 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
158 parent_window
->AddChild(w2
);
159 EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window
));
161 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
163 // 2) Test that associating the window and "host" view last results in a
164 // correct ordering of child windows and layers.
165 View
* host_view1
= new View();
166 contents_view
->AddChildViewAt(host_view1
, 0);
167 EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window
));
169 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
171 w1
->SetProperty(views::kHostViewKey
, host_view1
);
172 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window
));
174 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
176 // 3) Test that parenting the "host" view to the parent widget last results
177 // in a correct ordering of child windows and layers.
178 contents_view
->RemoveChildView(host_view2
);
179 contents_view
->AddChildViewAt(host_view2
, 0);
180 EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window
));
182 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
184 // Work around for bug in NativeWidgetAura.
185 // TODO: fix bug and remove this.
189 // It is possible to associate a window to a view which has a parent layer
190 // (other than the widget layer). In this case, the parent layer of the host
191 // view and the parent layer of the associated window are different. Test that
192 // the layers and windows are properly reordered in this case.
193 TEST_F(WindowReordererTest
, HostViewParentHasLayer
) {
194 scoped_ptr
<Widget
> parent(CreateControlWidget(root_window(),
195 gfx::Rect(0, 0, 100, 100)));
197 aura::Window
* parent_window
= parent
->GetNativeWindow();
199 View
* contents_view
= new View();
200 parent
->SetContentsView(contents_view
);
202 // Create the following view hierarchy. (*) denotes views which paint to a
208 // +-- v12 (attached window)
212 View
* v1
= new View();
213 contents_view
->AddChildView(v1
);
215 View
* v11
= new View();
216 v11
->SetPaintToLayer(true);
217 v11
->layer()->set_name("v11");
218 v1
->AddChildView(v11
);
220 scoped_ptr
<Widget
> w(CreateControlWidget(parent_window
,
221 gfx::Rect(0, 1, 100, 101)));
222 SetWindowAndLayerName(w
->GetNativeView(), "w");
225 View
* v12
= new View();
226 v1
->AddChildView(v12
);
227 w
->GetNativeView()->SetProperty(kHostViewKey
, v12
);
229 View
* v13
= new View();
230 v13
->SetPaintToLayer(true);
231 v13
->layer()->set_name("v13");
232 v1
->AddChildView(v13
);
234 View
* v2
= new View();
235 v2
->SetPaintToLayer(true);
236 v2
->layer()->set_name("v2");
237 contents_view
->AddChildView(v2
);
239 // Test intial state.
240 EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window
));
241 EXPECT_EQ("v11 w v13 v2",
242 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
244 // |w|'s layer should be stacked above |v1|'s layer.
245 v1
->SetPaintToLayer(true);
246 v1
->layer()->set_name("v1");
247 EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window
));
249 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
251 // Test moving the host view from one view with a layer to another.
252 v2
->AddChildView(v12
);
253 EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window
));
255 ui::test::ChildLayerNamesAsString(*parent_window
->layer()));
257 // Work around for bug in NativeWidgetAura.
258 // TODO: fix bug and remove this.