OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 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. |
| 4 |
| 5 #include "ui/aura/root_window.h" |
| 6 #include "ui/aura/test/aura_test_base.h" |
| 7 #include "ui/aura/test/test_windows.h" |
| 8 #include "ui/aura/window.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" |
| 14 |
| 15 namespace views { |
| 16 namespace { |
| 17 |
| 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(); |
| 26 widget->Init(params); |
| 27 return widget; |
| 28 } |
| 29 |
| 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); |
| 34 } |
| 35 |
| 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) { |
| 39 std::string names; |
| 40 typedef std::vector<aura::Window*> Windows; |
| 41 for (Windows::const_iterator it = parent.children().begin(); |
| 42 it != parent.children().end(); ++it) { |
| 43 if (!names.empty()) |
| 44 names += " "; |
| 45 names += (*it)->name(); |
| 46 } |
| 47 return names; |
| 48 } |
| 49 |
| 50 typedef aura::test::AuraTestBase NativeWidgetLayerReordererTest; |
| 51 |
| 52 // Test that views with layers and views with attached windows are reordered |
| 53 // according to the view hierarchy. |
| 54 TEST_F(NativeWidgetLayerReordererTest, Basic) { |
| 55 scoped_ptr<Widget> parent(CreateControlWidget(root_window(), |
| 56 gfx::Rect(0, 0, 100, 100))); |
| 57 parent->Show(); |
| 58 aura::Window* parent_window = parent->GetNativeWindow(); |
| 59 |
| 60 View* contents_view = new View(); |
| 61 parent->SetContentsView(contents_view); |
| 62 |
| 63 // 1) Test that layers for views and layers for windows attached to a host |
| 64 // view are stacked above the layers for any windows not attached to a host |
| 65 // view. |
| 66 View* v = new View(); |
| 67 v->SetPaintToLayer(true); |
| 68 v->layer()->set_name("v"); |
| 69 contents_view->AddChildView(v); |
| 70 |
| 71 scoped_ptr<Widget> w1(CreateControlWidget(parent_window, |
| 72 gfx::Rect(0, 1, 100, 101))); |
| 73 SetWindowAndLayerName(w1->GetNativeView(), "w1"); |
| 74 w1->Show(); |
| 75 scoped_ptr<Widget> w2(CreateControlWidget(parent_window, |
| 76 gfx::Rect(0, 2, 100, 102))); |
| 77 SetWindowAndLayerName(w2->GetNativeView(), "w2"); |
| 78 w2->Show(); |
| 79 |
| 80 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
| 81 EXPECT_EQ("w1 w2 v", |
| 82 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 83 |
| 84 View* host_view1 = new View(); |
| 85 contents_view->AddChildViewAt(host_view1, 0); |
| 86 w1->GetNativeView()->SetProperty(kHostViewKey, host_view1); |
| 87 EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window)); |
| 88 EXPECT_EQ("w2 w1 v", |
| 89 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 90 |
| 91 View* host_view2 = new View(); |
| 92 w2->GetNativeView()->SetProperty(kHostViewKey, host_view2); |
| 93 contents_view->AddChildView(host_view2); |
| 94 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
| 95 EXPECT_EQ("w1 v w2", |
| 96 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 97 |
| 98 // 2) Test the z-order of the windows and layers as a result of reordering the |
| 99 // views. |
| 100 contents_view->RemoveChildView(host_view1); |
| 101 contents_view->AddChildView(host_view1); |
| 102 EXPECT_EQ("w2 w1", ChildWindowNamesAsString(*parent_window)); |
| 103 EXPECT_EQ("v w2 w1", |
| 104 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 105 |
| 106 contents_view->ReorderChildView(host_view2, -1); |
| 107 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
| 108 EXPECT_EQ("v w1 w2", |
| 109 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 110 |
| 111 // 3) Test the z-order of the windows and layers as a result of reordering the |
| 112 // views in situations where the window order remains unchanged. |
| 113 contents_view->ReorderChildView(v, -1); |
| 114 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
| 115 EXPECT_EQ("w1 w2 v", |
| 116 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 117 |
| 118 contents_view->ReorderChildView(host_view2, -1); |
| 119 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
| 120 EXPECT_EQ("w1 v w2", |
| 121 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 122 |
| 123 // 4) Test the z-order of the windows and layers as a result of Recreating |
| 124 // layers. |
| 125 scoped_ptr<ui::Layer> old_w1_layer(w1->GetNativeView()->RecreateLayer()); |
| 126 old_w1_layer->set_name("old_w1"); |
| 127 w1->GetNativeView()->layer()->set_name("w1"); |
| 128 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
| 129 EXPECT_EQ("old_w1 w1 v w2", |
| 130 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 131 |
| 132 scoped_ptr<ui::Layer> old_view_layer(v->RecreateLayer()); |
| 133 v->layer()->set_name("v"); |
| 134 old_view_layer->set_name("old_v"); |
| 135 EXPECT_EQ("w1 w2", ChildWindowNamesAsString(*parent_window)); |
| 136 EXPECT_EQ("old_w1 old_v w1 v w2", |
| 137 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 138 |
| 139 // Work around for bug in NativeWidgetAura. |
| 140 // TODO: fix bug and remove this. |
| 141 parent->Close(); |
| 142 } |
| 143 |
| 144 // It is possible to attach a window to a view which has a parent layer (other |
| 145 // than the widget layer). In this case, the parent layer of the host view and |
| 146 // the parent layer of the attached window are different. Test that the layers |
| 147 // and windows are properly reordered in this case. |
| 148 TEST_F(NativeWidgetLayerReordererTest, HostViewParentHasLayer) { |
| 149 scoped_ptr<Widget> parent(CreateControlWidget(root_window(), |
| 150 gfx::Rect(0, 0, 100, 100))); |
| 151 parent->Show(); |
| 152 aura::Window* parent_window = parent->GetNativeWindow(); |
| 153 |
| 154 View* contents_view = new View(); |
| 155 parent->SetContentsView(contents_view); |
| 156 |
| 157 // Create the following view hierarchy. (*) denotes views which paint to a |
| 158 // layer. |
| 159 // |
| 160 // contents_view |
| 161 // +-- v1 |
| 162 // +-- v11* |
| 163 // +-- v12 (attached window) |
| 164 // +-- v13* |
| 165 // +--v2* |
| 166 |
| 167 View* v1 = new View(); |
| 168 contents_view->AddChildView(v1); |
| 169 |
| 170 View* v11 = new View(); |
| 171 v11->SetPaintToLayer(true); |
| 172 v11->layer()->set_name("v11"); |
| 173 v1->AddChildView(v11); |
| 174 |
| 175 scoped_ptr<Widget> w(CreateControlWidget(parent_window, |
| 176 gfx::Rect(0, 1, 100, 101))); |
| 177 SetWindowAndLayerName(w->GetNativeView(), "w"); |
| 178 w->Show(); |
| 179 |
| 180 View* v12 = new View(); |
| 181 v1->AddChildView(v12); |
| 182 w->GetNativeView()->SetProperty(kHostViewKey, v12); |
| 183 |
| 184 View* v13 = new View(); |
| 185 v13->SetPaintToLayer(true); |
| 186 v13->layer()->set_name("v13"); |
| 187 v1->AddChildView(v13); |
| 188 |
| 189 View* v2 = new View(); |
| 190 v2->SetPaintToLayer(true); |
| 191 v2->layer()->set_name("v2"); |
| 192 contents_view->AddChildView(v2); |
| 193 |
| 194 // Test intial state. |
| 195 EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window)); |
| 196 EXPECT_EQ("v11 w v13 v2", |
| 197 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 198 |
| 199 // |w|'s layer should be stacked above |v1|'s layer. |
| 200 v1->SetPaintToLayer(true); |
| 201 v1->layer()->set_name("v1"); |
| 202 EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window)); |
| 203 EXPECT_EQ("v1 w v2", |
| 204 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 205 |
| 206 // Test moving the host view from one view with a layer to another. |
| 207 v2->AddChildView(v12); |
| 208 EXPECT_EQ("w", ChildWindowNamesAsString(*parent_window)); |
| 209 EXPECT_EQ("v1 v2 w", |
| 210 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 211 |
| 212 // Work around for bug in NativeWidgetAura. |
| 213 // TODO: fix bug and remove this. |
| 214 parent->Close(); |
| 215 } |
| 216 |
| 217 // Test that in the process of reordering, no windows are stacked above a window |
| 218 // with a NULL layer delegate. |
| 219 TEST_F(NativeWidgetLayerReordererTest, NULLLayerDelegate) { |
| 220 scoped_ptr<Widget> parent(CreateControlWidget(root_window(), |
| 221 gfx::Rect(0, 0, 100, 100))); |
| 222 parent->Show(); |
| 223 aura::Window* parent_window = parent->GetNativeWindow(); |
| 224 |
| 225 View* contents_view = new View(); |
| 226 parent->SetContentsView(contents_view); |
| 227 |
| 228 // Setup and test initial state. |
| 229 scoped_ptr<Widget> w1(CreateControlWidget(parent_window, |
| 230 gfx::Rect(0, 1, 100, 101))); |
| 231 SetWindowAndLayerName(w1->GetNativeView(), "w1"); |
| 232 w1->Show(); |
| 233 scoped_ptr<Widget> w2(CreateControlWidget(parent_window, |
| 234 gfx::Rect(0, 2, 100, 102))); |
| 235 SetWindowAndLayerName(w2->GetNativeView(), "w2"); |
| 236 w2->Show(); |
| 237 scoped_ptr<Widget> w3(CreateControlWidget(parent_window, |
| 238 gfx::Rect(0, 3, 100, 103))); |
| 239 SetWindowAndLayerName(w3->GetNativeView(), "w3"); |
| 240 w3->Show(); |
| 241 |
| 242 View* v = new View(); |
| 243 v->SetPaintToLayer(true); |
| 244 v->layer()->set_name("v"); |
| 245 contents_view->AddChildView(v); |
| 246 |
| 247 View* host_view = new View(); |
| 248 w3->GetNativeView()->SetProperty(views::kHostViewKey, host_view); |
| 249 contents_view->AddChildView(host_view); |
| 250 |
| 251 EXPECT_EQ("w1 w2 w3", ChildWindowNamesAsString(*parent_window)); |
| 252 EXPECT_EQ("w1 w2 v w3", |
| 253 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 254 |
| 255 // 1) Test that the reordered layers are stacked below the layer with a NULL |
| 256 // delegate. The handling for a layer with a NULL delegate which does not |
| 257 // belong to a window is different and is tested in (2). |
| 258 w1->GetNativeView()->layer()->set_delegate(NULL); |
| 259 parent_window->StackChildAtTop(w1->GetNativeView()); |
| 260 EXPECT_EQ("w2 w3 w1", ChildWindowNamesAsString(*parent_window)); |
| 261 EXPECT_EQ("w2 v w3 w1", |
| 262 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 263 |
| 264 contents_view->ReorderChildView(v, -1); |
| 265 EXPECT_EQ("w2 w3 w1", ChildWindowNamesAsString(*parent_window)); |
| 266 EXPECT_EQ("w2 w3 v w1", |
| 267 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 268 |
| 269 contents_view->ReorderChildView(host_view, -1); |
| 270 EXPECT_EQ("w2 w3 w1", ChildWindowNamesAsString(*parent_window)); |
| 271 EXPECT_EQ("w2 v w3 w1", |
| 272 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 273 |
| 274 w2->GetNativeView()->layer()->set_delegate(NULL); |
| 275 parent_window->StackChildAtTop(w2->GetNativeView()); |
| 276 contents_view->ReorderChildView(v, -1); |
| 277 EXPECT_EQ("w3 w2 w1", ChildWindowNamesAsString(*parent_window)); |
| 278 EXPECT_EQ("w3 v w2 w1", |
| 279 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 280 |
| 281 // 2) Test that layers with NULL delegates which do not belong to a window |
| 282 // do not get special handling. |
| 283 w1->GetNativeView()->layer()->set_delegate(w1->GetNativeView()); |
| 284 w2->GetNativeView()->layer()->set_delegate(w2->GetNativeView()); |
| 285 |
| 286 scoped_ptr<ui::Layer> misc_layer(new ui::Layer(ui::LAYER_NOT_DRAWN)); |
| 287 misc_layer->set_name("l"); |
| 288 parent_window->layer()->Add(misc_layer.get()); |
| 289 v->layer()->set_delegate(NULL); |
| 290 |
| 291 contents_view->ReorderChildView(host_view, -1); |
| 292 EXPECT_EQ("w2 w1 w3", ChildWindowNamesAsString(*parent_window)); |
| 293 EXPECT_EQ("w2 w1 l v w3", |
| 294 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 295 |
| 296 contents_view->ReorderChildView(v, -1); |
| 297 EXPECT_EQ("w2 w1 w3", ChildWindowNamesAsString(*parent_window)); |
| 298 EXPECT_EQ("w2 w1 l w3 v", |
| 299 ui::test::ChildLayerNamesAsString(*parent_window->layer())); |
| 300 |
| 301 // Work around for bug in NativeWidgetAura. |
| 302 // TODO: fix bug and remove this. |
| 303 parent->Close(); |
| 304 } |
| 305 |
| 306 } // namespace |
| 307 } // namespace views |
OLD | NEW |