Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: ui/views/corewm/transient_window_manager_unittest.cc

Issue 115453004: Moves management of transients out of Window (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove unneeded parens Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014 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/views/corewm/transient_window_manager.h"
6
7 #include "ui/aura/client/visibility_client.h"
8 #include "ui/aura/client/window_tree_client.h"
9 #include "ui/aura/layout_manager.h"
10 #include "ui/aura/test/test_windows.h"
11 #include "ui/aura/window.h"
12 #include "ui/views/corewm/window_util.h"
13 #include "ui/views/test/views_test_base.h"
14
15 using aura::Window;
16
17 using aura::test::ChildWindowIDsAsString;
18 using aura::test::CreateTestWindowWithId;
19
20 namespace views {
21 namespace corewm {
22
23 class TransientWindowManagerTest : public views::ViewsTestBase {
24 public:
25 TransientWindowManagerTest() {}
26 virtual ~TransientWindowManagerTest() {}
27
28 protected:
29 // Creates a transient window that is transient to |parent|.
30 Window* CreateTransientChild(int id, Window* parent) {
31 Window* window = new Window(NULL);
32 window->set_id(id);
33 window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
34 window->Init(ui::LAYER_TEXTURED);
35 aura::client::ParentWindowWithContext(window, GetContext(), gfx::Rect());
36 AddTransientChild(parent, window);
37 return window;
38 }
39
40 private:
41 DISALLOW_COPY_AND_ASSIGN(TransientWindowManagerTest);
42 };
43
44 // Various assertions for transient children.
45 TEST_F(TransientWindowManagerTest, TransientChildren) {
46 scoped_ptr<Window> parent(CreateTestWindowWithId(0, GetContext()));
47 scoped_ptr<Window> w1(CreateTestWindowWithId(1, parent.get()));
48 scoped_ptr<Window> w3(CreateTestWindowWithId(3, parent.get()));
49 Window* w2 = CreateTestWindowWithId(2, parent.get());
50 // w2 is now owned by w1.
51 AddTransientChild(w1.get(), w2);
52 // Stack w1 at the top (end), this should force w2 to be last (on top of w1).
53 parent->StackChildAtTop(w1.get());
54 ASSERT_EQ(3u, parent->children().size());
55 EXPECT_EQ(w2, parent->children().back());
56
57 // Destroy w1, which should also destroy w3 (since it's a transient child).
58 w1.reset();
59 w2 = NULL;
60 ASSERT_EQ(1u, parent->children().size());
61 EXPECT_EQ(w3.get(), parent->children()[0]);
62
63 w1.reset(CreateTestWindowWithId(4, parent.get()));
64 w2 = CreateTestWindowWithId(5, w3.get());
65 AddTransientChild(w1.get(), w2);
66 parent->StackChildAtTop(w3.get());
67 // Stack w1 at the top (end), this shouldn't affect w2 since it has a
68 // different parent.
69 parent->StackChildAtTop(w1.get());
70 ASSERT_EQ(2u, parent->children().size());
71 EXPECT_EQ(w3.get(), parent->children()[0]);
72 EXPECT_EQ(w1.get(), parent->children()[1]);
73
74 // Hiding parent should hide transient children.
75 EXPECT_TRUE(w2->IsVisible());
76 w1->Hide();
77 EXPECT_FALSE(w2->IsVisible());
78 }
79
80 // Tests that transient children are stacked as a unit when using stack above.
81 TEST_F(TransientWindowManagerTest, TransientChildrenGroupAbove) {
82 scoped_ptr<Window> parent(CreateTestWindowWithId(0, GetContext()));
83 scoped_ptr<Window> w1(CreateTestWindowWithId(1, parent.get()));
84 Window* w11 = CreateTestWindowWithId(11, parent.get());
85 scoped_ptr<Window> w2(CreateTestWindowWithId(2, parent.get()));
86 Window* w21 = CreateTestWindowWithId(21, parent.get());
87 Window* w211 = CreateTestWindowWithId(211, parent.get());
88 Window* w212 = CreateTestWindowWithId(212, parent.get());
89 Window* w213 = CreateTestWindowWithId(213, parent.get());
90 Window* w22 = CreateTestWindowWithId(22, parent.get());
91 ASSERT_EQ(8u, parent->children().size());
92
93 // w11 is now owned by w1.
94 AddTransientChild(w1.get(), w11);
95 // w21 is now owned by w2.
96 AddTransientChild(w2.get(), w21);
97 // w22 is now owned by w2.
98 AddTransientChild(w2.get(), w22);
99 // w211 is now owned by w21.
100 AddTransientChild(w21, w211);
101 // w212 is now owned by w21.
102 AddTransientChild(w21, w212);
103 // w213 is now owned by w21.
104 AddTransientChild(w21, w213);
105 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
106
107 // Stack w1 at the top (end), this should force w11 to be last (on top of w1).
108 parent->StackChildAtTop(w1.get());
109 EXPECT_EQ(w11, parent->children().back());
110 EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
111
112 // This tests that the order in children_ array rather than in
113 // transient_children_ array is used when reinserting transient children.
114 // If transient_children_ array was used '22' would be following '21'.
115 parent->StackChildAtTop(w2.get());
116 EXPECT_EQ(w22, parent->children().back());
117 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
118
119 parent->StackChildAbove(w11, w2.get());
120 EXPECT_EQ(w11, parent->children().back());
121 EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
122
123 parent->StackChildAbove(w21, w1.get());
124 EXPECT_EQ(w22, parent->children().back());
125 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
126
127 parent->StackChildAbove(w21, w22);
128 EXPECT_EQ(w213, parent->children().back());
129 EXPECT_EQ("1 11 2 22 21 211 212 213", ChildWindowIDsAsString(parent.get()));
130
131 parent->StackChildAbove(w11, w21);
132 EXPECT_EQ(w11, parent->children().back());
133 EXPECT_EQ("2 22 21 211 212 213 1 11", ChildWindowIDsAsString(parent.get()));
134
135 parent->StackChildAbove(w213, w21);
136 EXPECT_EQ(w11, parent->children().back());
137 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
138
139 // No change when stacking a transient parent above its transient child.
140 parent->StackChildAbove(w21, w211);
141 EXPECT_EQ(w11, parent->children().back());
142 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
143
144 // This tests that the order in children_ array rather than in
145 // transient_children_ array is used when reinserting transient children.
146 // If transient_children_ array was used '22' would be following '21'.
147 parent->StackChildAbove(w2.get(), w1.get());
148 EXPECT_EQ(w212, parent->children().back());
149 EXPECT_EQ("1 11 2 22 21 213 211 212", ChildWindowIDsAsString(parent.get()));
150
151 parent->StackChildAbove(w11, w213);
152 EXPECT_EQ(w11, parent->children().back());
153 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
154 }
155
156 // Tests that transient children are stacked as a unit when using stack below.
157 TEST_F(TransientWindowManagerTest, TransientChildrenGroupBelow) {
158 scoped_ptr<Window> parent(CreateTestWindowWithId(0, GetContext()));
159 scoped_ptr<Window> w1(CreateTestWindowWithId(1, parent.get()));
160 Window* w11 = CreateTestWindowWithId(11, parent.get());
161 scoped_ptr<Window> w2(CreateTestWindowWithId(2, parent.get()));
162 Window* w21 = CreateTestWindowWithId(21, parent.get());
163 Window* w211 = CreateTestWindowWithId(211, parent.get());
164 Window* w212 = CreateTestWindowWithId(212, parent.get());
165 Window* w213 = CreateTestWindowWithId(213, parent.get());
166 Window* w22 = CreateTestWindowWithId(22, parent.get());
167 ASSERT_EQ(8u, parent->children().size());
168
169 // w11 is now owned by w1.
170 AddTransientChild(w1.get(), w11);
171 // w21 is now owned by w2.
172 AddTransientChild(w2.get(), w21);
173 // w22 is now owned by w2.
174 AddTransientChild(w2.get(), w22);
175 // w211 is now owned by w21.
176 AddTransientChild(w21, w211);
177 // w212 is now owned by w21.
178 AddTransientChild(w21, w212);
179 // w213 is now owned by w21.
180 AddTransientChild(w21, w213);
181 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
182
183 // Stack w2 at the bottom, this should force w11 to be last (on top of w1).
184 // This also tests that the order in children_ array rather than in
185 // transient_children_ array is used when reinserting transient children.
186 // If transient_children_ array was used '22' would be following '21'.
187 parent->StackChildAtBottom(w2.get());
188 EXPECT_EQ(w11, parent->children().back());
189 EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
190
191 parent->StackChildAtBottom(w1.get());
192 EXPECT_EQ(w22, parent->children().back());
193 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
194
195 parent->StackChildBelow(w21, w1.get());
196 EXPECT_EQ(w11, parent->children().back());
197 EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
198
199 parent->StackChildBelow(w11, w2.get());
200 EXPECT_EQ(w22, parent->children().back());
201 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
202
203 parent->StackChildBelow(w22, w21);
204 EXPECT_EQ(w213, parent->children().back());
205 EXPECT_EQ("1 11 2 22 21 211 212 213", ChildWindowIDsAsString(parent.get()));
206
207 parent->StackChildBelow(w21, w11);
208 EXPECT_EQ(w11, parent->children().back());
209 EXPECT_EQ("2 22 21 211 212 213 1 11", ChildWindowIDsAsString(parent.get()));
210
211 parent->StackChildBelow(w213, w211);
212 EXPECT_EQ(w11, parent->children().back());
213 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
214
215 // No change when stacking a transient parent below its transient child.
216 parent->StackChildBelow(w21, w211);
217 EXPECT_EQ(w11, parent->children().back());
218 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
219
220 parent->StackChildBelow(w1.get(), w2.get());
221 EXPECT_EQ(w212, parent->children().back());
222 EXPECT_EQ("1 11 2 22 21 213 211 212", ChildWindowIDsAsString(parent.get()));
223
224 parent->StackChildBelow(w213, w11);
225 EXPECT_EQ(w11, parent->children().back());
226 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
227 }
228
229 namespace {
230
231 // Used by NotifyDelegateAfterDeletingTransients. Adds a string to a vector when
232 // OnWindowDestroyed() is invoked so that destruction order can be verified.
233 class DestroyedTrackingDelegate : public aura::test::TestWindowDelegate {
234 public:
235 explicit DestroyedTrackingDelegate(const std::string& name,
236 std::vector<std::string>* results)
237 : name_(name),
238 results_(results) {}
239
240 virtual void OnWindowDestroyed() OVERRIDE {
241 results_->push_back(name_);
242 }
243
244 private:
245 const std::string name_;
246 std::vector<std::string>* results_;
247
248 DISALLOW_COPY_AND_ASSIGN(DestroyedTrackingDelegate);
249 };
250
251 } // namespace
252
253 // Verifies the delegate is notified of destruction after transients are
254 // destroyed.
255 TEST_F(TransientWindowManagerTest, NotifyDelegateAfterDeletingTransients) {
256 std::vector<std::string> destruction_order;
257
258 DestroyedTrackingDelegate parent_delegate("parent", &destruction_order);
259 scoped_ptr<Window> parent(new Window(&parent_delegate));
260 parent->Init(ui::LAYER_NOT_DRAWN);
261
262 DestroyedTrackingDelegate transient_delegate("transient", &destruction_order);
263 Window* transient = new Window(&transient_delegate); // Owned by |parent|.
264 transient->Init(ui::LAYER_NOT_DRAWN);
265 AddTransientChild(parent.get(), transient);
266 parent.reset();
267
268 ASSERT_EQ(2u, destruction_order.size());
269 EXPECT_EQ("transient", destruction_order[0]);
270 EXPECT_EQ("parent", destruction_order[1]);
271 }
272
273 TEST_F(TransientWindowManagerTest, StackTransientsWhoseLayersHaveNoDelegate) {
274 // Create a window with several transients, then a couple windows on top.
275 scoped_ptr<Window> window1(CreateTestWindowWithId(1, GetContext()));
276 scoped_ptr<Window> window11(CreateTransientChild(11, window1.get()));
277 scoped_ptr<Window> window12(CreateTransientChild(12, window1.get()));
278 scoped_ptr<Window> window13(CreateTransientChild(13, window1.get()));
279 scoped_ptr<Window> window2(CreateTestWindowWithId(2, GetContext()));
280 scoped_ptr<Window> window3(CreateTestWindowWithId(3, GetContext()));
281
282 EXPECT_EQ("1 11 12 13 2 3", ChildWindowIDsAsString(GetContext()));
283
284 // Remove the delegates of a couple of transients, as if they are closing
285 // and animating out.
286 window11->layer()->set_delegate(NULL);
287 window13->layer()->set_delegate(NULL);
288
289 // Move window1 to the front. All transients should move with it, and their
290 // order should be preserved.
291 GetContext()->StackChildAtTop(window1.get());
292
293 EXPECT_EQ("2 3 1 11 12 13", ChildWindowIDsAsString(GetContext()));
294 }
295
296 TEST_F(TransientWindowManagerTest,
297 StackTransientsLayersRelativeToOtherTransients) {
298 // Create a window with several transients, then a couple windows on top.
299 scoped_ptr<Window> window1(CreateTestWindowWithId(1, GetContext()));
300 scoped_ptr<Window> window11(CreateTransientChild(11, window1.get()));
301 scoped_ptr<Window> window12(CreateTransientChild(12, window1.get()));
302 scoped_ptr<Window> window13(CreateTransientChild(13, window1.get()));
303
304 EXPECT_EQ("1 11 12 13", ChildWindowIDsAsString(GetContext()));
305
306 // Stack 11 above 12.
307 GetContext()->StackChildAbove(window11.get(), window12.get());
308 EXPECT_EQ("1 12 11 13", ChildWindowIDsAsString(GetContext()));
309
310 // Stack 13 below 12.
311 GetContext()->StackChildBelow(window13.get(), window12.get());
312 EXPECT_EQ("1 13 12 11", ChildWindowIDsAsString(GetContext()));
313
314 // Stack 11 above 1.
315 GetContext()->StackChildAbove(window11.get(), window1.get());
316 EXPECT_EQ("1 11 13 12", ChildWindowIDsAsString(GetContext()));
317
318 // Stack 12 below 13.
319 GetContext()->StackChildBelow(window12.get(), window13.get());
320 EXPECT_EQ("1 11 12 13", ChildWindowIDsAsString(GetContext()));
321 }
322
323 TEST_F(TransientWindowManagerTest,
324 StackTransientsLayersRelativeToOtherTransientsNoLayerDelegate) {
325 // Create a window with several transients, then a couple windows on top.
326 scoped_ptr<Window> window1(CreateTestWindowWithId(1, GetContext()));
327 scoped_ptr<Window> window11(CreateTransientChild(11, window1.get()));
328 scoped_ptr<Window> window12(CreateTransientChild(12, window1.get()));
329 scoped_ptr<Window> window13(CreateTransientChild(13, window1.get()));
330 scoped_ptr<Window> window2(CreateTestWindowWithId(2, GetContext()));
331 scoped_ptr<Window> window3(CreateTestWindowWithId(3, GetContext()));
332
333 EXPECT_EQ("1 11 12 13 2 3", ChildWindowIDsAsString(GetContext()));
334
335 window1->layer()->set_delegate(NULL);
336
337 // Stack 1 at top.
338 GetContext()->StackChildAtTop(window1.get());
339 EXPECT_EQ("2 3 1 11 12 13", ChildWindowIDsAsString(GetContext()));
340 }
341
342 class StackingMadrigalLayoutManager : public aura::LayoutManager {
343 public:
344 explicit StackingMadrigalLayoutManager(Window* root_window)
345 : root_window_(root_window) {
346 root_window_->SetLayoutManager(this);
347 }
348 virtual ~StackingMadrigalLayoutManager() {
349 }
350
351 private:
352 // Overridden from LayoutManager:
353 virtual void OnWindowResized() OVERRIDE {}
354 virtual void OnWindowAddedToLayout(Window* child) OVERRIDE {}
355 virtual void OnWillRemoveWindowFromLayout(Window* child) OVERRIDE {}
356 virtual void OnWindowRemovedFromLayout(Window* child) OVERRIDE {}
357 virtual void OnChildWindowVisibilityChanged(Window* child,
358 bool visible) OVERRIDE {
359 Window::Windows::const_iterator it = root_window_->children().begin();
360 Window* last_window = NULL;
361 for (; it != root_window_->children().end(); ++it) {
362 if (*it == child && last_window) {
363 if (!visible)
364 root_window_->StackChildAbove(last_window, *it);
365 else
366 root_window_->StackChildAbove(*it, last_window);
367 break;
368 }
369 last_window = *it;
370 }
371 }
372 virtual void SetChildBounds(Window* child,
373 const gfx::Rect& requested_bounds) OVERRIDE {
374 SetChildBoundsDirect(child, requested_bounds);
375 }
376
377 Window* root_window_;
378
379 DISALLOW_COPY_AND_ASSIGN(StackingMadrigalLayoutManager);
380 };
381
382 class StackingMadrigalVisibilityClient : public aura::client::VisibilityClient {
383 public:
384 explicit StackingMadrigalVisibilityClient(Window* root_window)
385 : ignored_window_(NULL) {
386 aura::client::SetVisibilityClient(root_window, this);
387 }
388 virtual ~StackingMadrigalVisibilityClient() {
389 }
390
391 void set_ignored_window(Window* ignored_window) {
392 ignored_window_ = ignored_window;
393 }
394
395 private:
396 // Overridden from client::VisibilityClient:
397 virtual void UpdateLayerVisibility(Window* window, bool visible) OVERRIDE {
398 if (!visible) {
399 if (window == ignored_window_)
400 window->layer()->set_delegate(NULL);
401 else
402 window->layer()->SetVisible(visible);
403 } else {
404 window->layer()->SetVisible(visible);
405 }
406 }
407
408 Window* ignored_window_;
409
410 DISALLOW_COPY_AND_ASSIGN(StackingMadrigalVisibilityClient);
411 };
412
413 // This test attempts to reconstruct a circumstance that can happen when the
414 // aura client attempts to manipulate the visibility and delegate of a layer
415 // independent of window visibility.
416 // A use case is where the client attempts to keep a window visible onscreen
417 // even after code has called Hide() on the window. The use case for this would
418 // be that window hides are animated (e.g. the window fades out). To prevent
419 // spurious updating the client code may also clear window's layer's delegate,
420 // so that the window cannot attempt to paint or update it further. The window
421 // uses the presence of a NULL layer delegate as a signal in stacking to note
422 // that the window is being manipulated by such a use case and its stacking
423 // should not be adjusted.
424 // One issue that can arise when a window opens two transient children, and the
425 // first is hidden. Subsequent attempts to activate the transient parent can
426 // result in the transient parent being stacked above the second transient
427 // child. A fix is made to Window::StackAbove to prevent this, and this test
428 // verifies this fix.
429 TEST_F(TransientWindowManagerTest, StackingMadrigal) {
430 new StackingMadrigalLayoutManager(GetContext());
431 StackingMadrigalVisibilityClient visibility_client(GetContext());
432
433 scoped_ptr<Window> window1(CreateTestWindowWithId(1, GetContext()));
434 scoped_ptr<Window> window11(CreateTransientChild(11, window1.get()));
435
436 visibility_client.set_ignored_window(window11.get());
437
438 window11->Show();
439 window11->Hide();
440
441 // As a transient, window11 should still be stacked above window1, even when
442 // hidden.
443 EXPECT_TRUE(aura::test::WindowIsAbove(window11.get(), window1.get()));
444 EXPECT_TRUE(aura::test::LayerIsAbove(window11.get(), window1.get()));
445
446 // A new transient should still be above window1. It will appear behind
447 // window11 because we don't stack windows on top of targets with NULL
448 // delegates.
449 scoped_ptr<Window> window12(CreateTransientChild(12, window1.get()));
450 window12->Show();
451
452 EXPECT_TRUE(aura::test::WindowIsAbove(window12.get(), window1.get()));
453 EXPECT_TRUE(aura::test::LayerIsAbove(window12.get(), window1.get()));
454
455 // In earlier versions of the StackChildAbove() method, attempting to stack
456 // window1 above window12 at this point would actually restack the layers
457 // resulting in window12's layer being below window1's layer (though the
458 // windows themselves would still be correctly stacked, so events would pass
459 // through.)
460 GetContext()->StackChildAbove(window1.get(), window12.get());
461
462 // Both window12 and its layer should be stacked above window1.
463 EXPECT_TRUE(aura::test::WindowIsAbove(window12.get(), window1.get()));
464 EXPECT_TRUE(aura::test::LayerIsAbove(window12.get(), window1.get()));
465 }
466
467 // Test for an issue where attempting to stack a primary window on top of a
468 // transient with a NULL layer delegate causes that primary window to be moved,
469 // but the layer order not changed to match. http://crbug.com/112562
470 TEST_F(TransientWindowManagerTest, StackOverClosingTransient) {
471 scoped_ptr<Window> window1(CreateTestWindowWithId(1, GetContext()));
472 scoped_ptr<Window> transient1(CreateTransientChild(11, window1.get()));
473 scoped_ptr<Window> window2(CreateTestWindowWithId(2, GetContext()));
474 scoped_ptr<Window> transient2(CreateTransientChild(21, window2.get()));
475
476 // Both windows and layers are stacked in creation order.
477 Window* root = GetContext();
478 ASSERT_EQ(4u, root->children().size());
479 EXPECT_EQ(root->children()[0], window1.get());
480 EXPECT_EQ(root->children()[1], transient1.get());
481 EXPECT_EQ(root->children()[2], window2.get());
482 EXPECT_EQ(root->children()[3], transient2.get());
483 ASSERT_EQ(4u, root->layer()->children().size());
484 EXPECT_EQ(root->layer()->children()[0], window1->layer());
485 EXPECT_EQ(root->layer()->children()[1], transient1->layer());
486 EXPECT_EQ(root->layer()->children()[2], window2->layer());
487 EXPECT_EQ(root->layer()->children()[3], transient2->layer());
488 EXPECT_EQ("1 11 2 21", ChildWindowIDsAsString(GetContext()));
489
490 // This brings window1 and its transient to the front.
491 root->StackChildAtTop(window1.get());
492 EXPECT_EQ("2 21 1 11", ChildWindowIDsAsString(GetContext()));
493
494 EXPECT_EQ(root->children()[0], window2.get());
495 EXPECT_EQ(root->children()[1], transient2.get());
496 EXPECT_EQ(root->children()[2], window1.get());
497 EXPECT_EQ(root->children()[3], transient1.get());
498 EXPECT_EQ(root->layer()->children()[0], window2->layer());
499 EXPECT_EQ(root->layer()->children()[1], transient2->layer());
500 EXPECT_EQ(root->layer()->children()[2], window1->layer());
501 EXPECT_EQ(root->layer()->children()[3], transient1->layer());
502
503 // Pretend we're closing the top-most transient, then bring window2 to the
504 // front. This mimics activating a browser window while the status bubble
505 // is fading out. The transient should stay topmost.
506 transient1->layer()->set_delegate(NULL);
507 root->StackChildAtTop(window2.get());
508
509 EXPECT_EQ(root->children()[0], window1.get());
510 EXPECT_EQ(root->children()[1], window2.get());
511 EXPECT_EQ(root->children()[2], transient2.get());
512 EXPECT_EQ(root->children()[3], transient1.get());
513 EXPECT_EQ(root->layer()->children()[0], window1->layer());
514 EXPECT_EQ(root->layer()->children()[1], window2->layer());
515 EXPECT_EQ(root->layer()->children()[2], transient2->layer());
516 EXPECT_EQ(root->layer()->children()[3], transient1->layer());
517
518 // Close the transient. Remaining windows are stable.
519 transient1.reset();
520
521 ASSERT_EQ(3u, root->children().size());
522 EXPECT_EQ(root->children()[0], window1.get());
523 EXPECT_EQ(root->children()[1], window2.get());
524 EXPECT_EQ(root->children()[2], transient2.get());
525 ASSERT_EQ(3u, root->layer()->children().size());
526 EXPECT_EQ(root->layer()->children()[0], window1->layer());
527 EXPECT_EQ(root->layer()->children()[1], window2->layer());
528 EXPECT_EQ(root->layer()->children()[2], transient2->layer());
529
530 // Open another window on top.
531 scoped_ptr<Window> window3(CreateTestWindowWithId(3, GetContext()));
532
533 ASSERT_EQ(4u, root->children().size());
534 EXPECT_EQ(root->children()[0], window1.get());
535 EXPECT_EQ(root->children()[1], window2.get());
536 EXPECT_EQ(root->children()[2], transient2.get());
537 EXPECT_EQ(root->children()[3], window3.get());
538 ASSERT_EQ(4u, root->layer()->children().size());
539 EXPECT_EQ(root->layer()->children()[0], window1->layer());
540 EXPECT_EQ(root->layer()->children()[1], window2->layer());
541 EXPECT_EQ(root->layer()->children()[2], transient2->layer());
542 EXPECT_EQ(root->layer()->children()[3], window3->layer());
543
544 // Pretend we're closing the topmost non-transient window, then bring
545 // window2 to the top. It should not move.
546 window3->layer()->set_delegate(NULL);
547 root->StackChildAtTop(window2.get());
548
549 ASSERT_EQ(4u, root->children().size());
550 EXPECT_EQ(root->children()[0], window1.get());
551 EXPECT_EQ(root->children()[1], window2.get());
552 EXPECT_EQ(root->children()[2], transient2.get());
553 EXPECT_EQ(root->children()[3], window3.get());
554 ASSERT_EQ(4u, root->layer()->children().size());
555 EXPECT_EQ(root->layer()->children()[0], window1->layer());
556 EXPECT_EQ(root->layer()->children()[1], window2->layer());
557 EXPECT_EQ(root->layer()->children()[2], transient2->layer());
558 EXPECT_EQ(root->layer()->children()[3], window3->layer());
559
560 // Bring window1 to the top. It should move ahead of window2, but not
561 // ahead of window3 (with NULL delegate).
562 root->StackChildAtTop(window1.get());
563
564 ASSERT_EQ(4u, root->children().size());
565 EXPECT_EQ(root->children()[0], window2.get());
566 EXPECT_EQ(root->children()[1], transient2.get());
567 EXPECT_EQ(root->children()[2], window1.get());
568 EXPECT_EQ(root->children()[3], window3.get());
569 ASSERT_EQ(4u, root->layer()->children().size());
570 EXPECT_EQ(root->layer()->children()[0], window2->layer());
571 EXPECT_EQ(root->layer()->children()[1], transient2->layer());
572 EXPECT_EQ(root->layer()->children()[2], window1->layer());
573 EXPECT_EQ(root->layer()->children()[3], window3->layer());
574 }
575
576 } // namespace corewm
577 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/corewm/transient_window_manager.cc ('k') | ui/views/corewm/transient_window_stacking_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698