| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/aura/window.h" | 5 #include "ui/aura/window.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "ui/aura/client/capture_client.h" | 17 #include "ui/aura/client/capture_client.h" |
| 18 #include "ui/aura/client/focus_change_observer.h" | 18 #include "ui/aura/client/focus_change_observer.h" |
| 19 #include "ui/aura/client/visibility_client.h" | 19 #include "ui/aura/client/visibility_client.h" |
| 20 #include "ui/aura/client/window_tree_client.h" | 20 #include "ui/aura/client/window_tree_client.h" |
| 21 #include "ui/aura/layout_manager.h" | |
| 22 #include "ui/aura/root_window.h" | 21 #include "ui/aura/root_window.h" |
| 23 #include "ui/aura/root_window_observer.h" | 22 #include "ui/aura/root_window_observer.h" |
| 24 #include "ui/aura/test/aura_test_base.h" | 23 #include "ui/aura/test/aura_test_base.h" |
| 25 #include "ui/aura/test/event_generator.h" | 24 #include "ui/aura/test/event_generator.h" |
| 26 #include "ui/aura/test/test_window_delegate.h" | 25 #include "ui/aura/test/test_window_delegate.h" |
| 27 #include "ui/aura/test/test_windows.h" | 26 #include "ui/aura/test/test_windows.h" |
| 28 #include "ui/aura/test/window_test_api.h" | 27 #include "ui/aura/test/window_test_api.h" |
| 29 #include "ui/aura/window_delegate.h" | 28 #include "ui/aura/window_delegate.h" |
| 30 #include "ui/aura/window_observer.h" | 29 #include "ui/aura/window_observer.h" |
| 31 #include "ui/aura/window_property.h" | 30 #include "ui/aura/window_property.h" |
| (...skipping 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1576 transform.Translate(size.height(), 0.0); | 1575 transform.Translate(size.height(), 0.0); |
| 1577 transform.Rotate(90.0); | 1576 transform.Rotate(90.0); |
| 1578 dispatcher()->host()->SetTransform(transform); | 1577 dispatcher()->host()->SetTransform(transform); |
| 1579 | 1578 |
| 1580 ui::TouchEvent press( | 1579 ui::TouchEvent press( |
| 1581 ui::ET_TOUCH_PRESSED, gfx::Point(size.height() - 10, 10), 0, getTime()); | 1580 ui::ET_TOUCH_PRESSED, gfx::Point(size.height() - 10, 10), 0, getTime()); |
| 1582 dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); | 1581 dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); |
| 1583 EXPECT_EQ(gfx::Point(10, 10).ToString(), delegate->position().ToString()); | 1582 EXPECT_EQ(gfx::Point(10, 10).ToString(), delegate->position().ToString()); |
| 1584 } | 1583 } |
| 1585 | 1584 |
| 1586 // Various assertions for transient children. | |
| 1587 TEST_F(WindowTest, TransientChildren) { | |
| 1588 scoped_ptr<Window> parent(CreateTestWindowWithId(0, root_window())); | |
| 1589 scoped_ptr<Window> w1(CreateTestWindowWithId(1, parent.get())); | |
| 1590 scoped_ptr<Window> w3(CreateTestWindowWithId(3, parent.get())); | |
| 1591 Window* w2 = CreateTestWindowWithId(2, parent.get()); | |
| 1592 w1->AddTransientChild(w2); // w2 is now owned by w1. | |
| 1593 // Stack w1 at the top (end), this should force w2 to be last (on top of w1). | |
| 1594 parent->StackChildAtTop(w1.get()); | |
| 1595 ASSERT_EQ(3u, parent->children().size()); | |
| 1596 EXPECT_EQ(w2, parent->children().back()); | |
| 1597 | |
| 1598 // Destroy w1, which should also destroy w3 (since it's a transient child). | |
| 1599 w1.reset(); | |
| 1600 w2 = NULL; | |
| 1601 ASSERT_EQ(1u, parent->children().size()); | |
| 1602 EXPECT_EQ(w3.get(), parent->children()[0]); | |
| 1603 | |
| 1604 w1.reset(CreateTestWindowWithId(4, parent.get())); | |
| 1605 w2 = CreateTestWindowWithId(5, w3.get()); | |
| 1606 w1->AddTransientChild(w2); | |
| 1607 parent->StackChildAtTop(w3.get()); | |
| 1608 // Stack w1 at the top (end), this shouldn't affect w2 since it has a | |
| 1609 // different parent. | |
| 1610 parent->StackChildAtTop(w1.get()); | |
| 1611 ASSERT_EQ(2u, parent->children().size()); | |
| 1612 EXPECT_EQ(w3.get(), parent->children()[0]); | |
| 1613 EXPECT_EQ(w1.get(), parent->children()[1]); | |
| 1614 | |
| 1615 // Hiding parent should hide transient children. | |
| 1616 EXPECT_TRUE(w2->IsVisible()); | |
| 1617 w1->Hide(); | |
| 1618 EXPECT_FALSE(w2->IsVisible()); | |
| 1619 } | |
| 1620 | |
| 1621 namespace { | 1585 namespace { |
| 1622 DEFINE_WINDOW_PROPERTY_KEY(int, kIntKey, -2); | 1586 DEFINE_WINDOW_PROPERTY_KEY(int, kIntKey, -2); |
| 1623 DEFINE_WINDOW_PROPERTY_KEY(const char*, kStringKey, "squeamish"); | 1587 DEFINE_WINDOW_PROPERTY_KEY(const char*, kStringKey, "squeamish"); |
| 1624 } | 1588 } |
| 1625 | 1589 |
| 1626 TEST_F(WindowTest, Property) { | 1590 TEST_F(WindowTest, Property) { |
| 1627 scoped_ptr<Window> w(CreateTestWindowWithId(0, root_window())); | 1591 scoped_ptr<Window> w(CreateTestWindowWithId(0, root_window())); |
| 1628 | 1592 |
| 1629 static const char native_prop_key[] = "fnord"; | 1593 static const char native_prop_key[] = "fnord"; |
| 1630 | 1594 |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2049 ui::test::ChildLayerNamesAsString(*root_window()->layer())); | 2013 ui::test::ChildLayerNamesAsString(*root_window()->layer())); |
| 2050 window1->layer()->set_delegate(NULL); | 2014 window1->layer()->set_delegate(NULL); |
| 2051 root_window()->StackChildAtBottom(window3.get()); | 2015 root_window()->StackChildAtBottom(window3.get()); |
| 2052 | 2016 |
| 2053 // Window 3 should have moved to the bottom. | 2017 // Window 3 should have moved to the bottom. |
| 2054 EXPECT_EQ("3 1 2", ChildWindowIDsAsString(root_window())); | 2018 EXPECT_EQ("3 1 2", ChildWindowIDsAsString(root_window())); |
| 2055 EXPECT_EQ("3 1 2", | 2019 EXPECT_EQ("3 1 2", |
| 2056 ui::test::ChildLayerNamesAsString(*root_window()->layer())); | 2020 ui::test::ChildLayerNamesAsString(*root_window()->layer())); |
| 2057 } | 2021 } |
| 2058 | 2022 |
| 2059 TEST_F(WindowTest, StackWindowsWhoseLayersHaveNoDelegate) { | |
| 2060 scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window())); | |
| 2061 window1->layer()->set_name("1"); | |
| 2062 scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window())); | |
| 2063 window2->layer()->set_name("2"); | |
| 2064 scoped_ptr<Window> window3(CreateTestWindowWithId(3, root_window())); | |
| 2065 window3->layer()->set_name("3"); | |
| 2066 | |
| 2067 // This brings |window1| (and its layer) to the front. | |
| 2068 root_window()->StackChildAbove(window1.get(), window3.get()); | |
| 2069 EXPECT_EQ("2 3 1", ChildWindowIDsAsString(root_window())); | |
| 2070 EXPECT_EQ("2 3 1", | |
| 2071 ui::test::ChildLayerNamesAsString(*root_window()->layer())); | |
| 2072 | |
| 2073 // Since |window1| does not have a delegate, |window2| should not move in | |
| 2074 // front of it, nor should its layer. | |
| 2075 window1->layer()->set_delegate(NULL); | |
| 2076 root_window()->StackChildAbove(window2.get(), window1.get()); | |
| 2077 EXPECT_EQ("3 2 1", ChildWindowIDsAsString(root_window())); | |
| 2078 EXPECT_EQ("3 2 1", | |
| 2079 ui::test::ChildLayerNamesAsString(*root_window()->layer())); | |
| 2080 | |
| 2081 // It should still be possible to stack |window3| immediately below |window1|. | |
| 2082 root_window()->StackChildBelow(window3.get(), window1.get()); | |
| 2083 EXPECT_EQ("2 3 1", ChildWindowIDsAsString(root_window())); | |
| 2084 EXPECT_EQ("2 3 1", | |
| 2085 ui::test::ChildLayerNamesAsString(*root_window()->layer())); | |
| 2086 | |
| 2087 // Since neither |window3| nor |window1| have a delegate, |window2| should | |
| 2088 // not move in front of either. | |
| 2089 window3->layer()->set_delegate(NULL); | |
| 2090 root_window()->StackChildBelow(window2.get(), window1.get()); | |
| 2091 EXPECT_EQ("2 3 1", ChildWindowIDsAsString(root_window())); | |
| 2092 EXPECT_EQ("2 3 1", | |
| 2093 ui::test::ChildLayerNamesAsString(*root_window()->layer())); | |
| 2094 } | |
| 2095 | |
| 2096 TEST_F(WindowTest, StackTransientsWhoseLayersHaveNoDelegate) { | |
| 2097 // Create a window with several transients, then a couple windows on top. | |
| 2098 scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window())); | |
| 2099 scoped_ptr<Window> window11(CreateTransientChild(11, window1.get())); | |
| 2100 scoped_ptr<Window> window12(CreateTransientChild(12, window1.get())); | |
| 2101 scoped_ptr<Window> window13(CreateTransientChild(13, window1.get())); | |
| 2102 scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window())); | |
| 2103 scoped_ptr<Window> window3(CreateTestWindowWithId(3, root_window())); | |
| 2104 | |
| 2105 EXPECT_EQ("1 11 12 13 2 3", ChildWindowIDsAsString(root_window())); | |
| 2106 | |
| 2107 // Remove the delegates of a couple of transients, as if they are closing | |
| 2108 // and animating out. | |
| 2109 window11->layer()->set_delegate(NULL); | |
| 2110 window13->layer()->set_delegate(NULL); | |
| 2111 | |
| 2112 // Move window1 to the front. All transients should move with it, and their | |
| 2113 // order should be preserved. | |
| 2114 root_window()->StackChildAtTop(window1.get()); | |
| 2115 | |
| 2116 EXPECT_EQ("2 3 1 11 12 13", ChildWindowIDsAsString(root_window())); | |
| 2117 } | |
| 2118 | |
| 2119 class TestVisibilityClient : public client::VisibilityClient { | 2023 class TestVisibilityClient : public client::VisibilityClient { |
| 2120 public: | 2024 public: |
| 2121 explicit TestVisibilityClient(Window* root_window) | 2025 explicit TestVisibilityClient(Window* root_window) |
| 2122 : ignore_visibility_changes_(false) { | 2026 : ignore_visibility_changes_(false) { |
| 2123 client::SetVisibilityClient(root_window, this); | 2027 client::SetVisibilityClient(root_window, this); |
| 2124 } | 2028 } |
| 2125 virtual ~TestVisibilityClient() { | 2029 virtual ~TestVisibilityClient() { |
| 2126 } | 2030 } |
| 2127 | 2031 |
| 2128 void set_ignore_visibility_changes(bool ignore_visibility_changes) { | 2032 void set_ignore_visibility_changes(bool ignore_visibility_changes) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2246 EXPECT_EQ("0 0 0", d1.GetMouseMotionCountsAndReset()); | 2150 EXPECT_EQ("0 0 0", d1.GetMouseMotionCountsAndReset()); |
| 2247 EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset()); | 2151 EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset()); |
| 2248 | 2152 |
| 2249 // Closing windows | 2153 // Closing windows |
| 2250 w11.reset(); | 2154 w11.reset(); |
| 2251 RunAllPendingInMessageLoop(); | 2155 RunAllPendingInMessageLoop(); |
| 2252 EXPECT_EQ("0 0 0", d1.GetMouseMotionCountsAndReset()); | 2156 EXPECT_EQ("0 0 0", d1.GetMouseMotionCountsAndReset()); |
| 2253 EXPECT_EQ("0 0 0", d11.GetMouseMotionCountsAndReset()); | 2157 EXPECT_EQ("0 0 0", d11.GetMouseMotionCountsAndReset()); |
| 2254 } | 2158 } |
| 2255 | 2159 |
| 2256 class StackingMadrigalLayoutManager : public LayoutManager { | |
| 2257 public: | |
| 2258 explicit StackingMadrigalLayoutManager(Window* root_window) | |
| 2259 : root_window_(root_window) { | |
| 2260 root_window_->SetLayoutManager(this); | |
| 2261 } | |
| 2262 virtual ~StackingMadrigalLayoutManager() { | |
| 2263 } | |
| 2264 | |
| 2265 private: | |
| 2266 // Overridden from LayoutManager: | |
| 2267 virtual void OnWindowResized() OVERRIDE {} | |
| 2268 virtual void OnWindowAddedToLayout(Window* child) OVERRIDE {} | |
| 2269 virtual void OnWillRemoveWindowFromLayout(Window* child) OVERRIDE {} | |
| 2270 virtual void OnWindowRemovedFromLayout(Window* child) OVERRIDE {} | |
| 2271 virtual void OnChildWindowVisibilityChanged(Window* child, | |
| 2272 bool visible) OVERRIDE { | |
| 2273 Window::Windows::const_iterator it = root_window_->children().begin(); | |
| 2274 Window* last_window = NULL; | |
| 2275 for (; it != root_window_->children().end(); ++it) { | |
| 2276 if (*it == child && last_window) { | |
| 2277 if (!visible) | |
| 2278 root_window_->StackChildAbove(last_window, *it); | |
| 2279 else | |
| 2280 root_window_->StackChildAbove(*it, last_window); | |
| 2281 break; | |
| 2282 } | |
| 2283 last_window = *it; | |
| 2284 } | |
| 2285 } | |
| 2286 virtual void SetChildBounds(Window* child, | |
| 2287 const gfx::Rect& requested_bounds) OVERRIDE { | |
| 2288 SetChildBoundsDirect(child, requested_bounds); | |
| 2289 } | |
| 2290 | |
| 2291 Window* root_window_; | |
| 2292 | |
| 2293 DISALLOW_COPY_AND_ASSIGN(StackingMadrigalLayoutManager); | |
| 2294 }; | |
| 2295 | |
| 2296 class StackingMadrigalVisibilityClient : public client::VisibilityClient { | |
| 2297 public: | |
| 2298 explicit StackingMadrigalVisibilityClient(Window* root_window) | |
| 2299 : ignored_window_(NULL) { | |
| 2300 client::SetVisibilityClient(root_window, this); | |
| 2301 } | |
| 2302 virtual ~StackingMadrigalVisibilityClient() { | |
| 2303 } | |
| 2304 | |
| 2305 void set_ignored_window(Window* ignored_window) { | |
| 2306 ignored_window_ = ignored_window; | |
| 2307 } | |
| 2308 | |
| 2309 private: | |
| 2310 // Overridden from client::VisibilityClient: | |
| 2311 virtual void UpdateLayerVisibility(Window* window, bool visible) OVERRIDE { | |
| 2312 if (!visible) { | |
| 2313 if (window == ignored_window_) | |
| 2314 window->layer()->set_delegate(NULL); | |
| 2315 else | |
| 2316 window->layer()->SetVisible(visible); | |
| 2317 } else { | |
| 2318 window->layer()->SetVisible(visible); | |
| 2319 } | |
| 2320 } | |
| 2321 | |
| 2322 Window* ignored_window_; | |
| 2323 | |
| 2324 DISALLOW_COPY_AND_ASSIGN(StackingMadrigalVisibilityClient); | |
| 2325 }; | |
| 2326 | |
| 2327 // This test attempts to reconstruct a circumstance that can happen when the | |
| 2328 // aura client attempts to manipulate the visibility and delegate of a layer | |
| 2329 // independent of window visibility. | |
| 2330 // A use case is where the client attempts to keep a window visible onscreen | |
| 2331 // even after code has called Hide() on the window. The use case for this would | |
| 2332 // be that window hides are animated (e.g. the window fades out). To prevent | |
| 2333 // spurious updating the client code may also clear window's layer's delegate, | |
| 2334 // so that the window cannot attempt to paint or update it further. The window | |
| 2335 // uses the presence of a NULL layer delegate as a signal in stacking to note | |
| 2336 // that the window is being manipulated by such a use case and its stacking | |
| 2337 // should not be adjusted. | |
| 2338 // One issue that can arise when a window opens two transient children, and the | |
| 2339 // first is hidden. Subsequent attempts to activate the transient parent can | |
| 2340 // result in the transient parent being stacked above the second transient | |
| 2341 // child. A fix is made to Window::StackAbove to prevent this, and this test | |
| 2342 // verifies this fix. | |
| 2343 TEST_F(WindowTest, StackingMadrigal) { | |
| 2344 new StackingMadrigalLayoutManager(root_window()); | |
| 2345 StackingMadrigalVisibilityClient visibility_client(root_window()); | |
| 2346 | |
| 2347 scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window())); | |
| 2348 scoped_ptr<Window> window11(CreateTransientChild(11, window1.get())); | |
| 2349 | |
| 2350 visibility_client.set_ignored_window(window11.get()); | |
| 2351 | |
| 2352 window11->Show(); | |
| 2353 window11->Hide(); | |
| 2354 | |
| 2355 // As a transient, window11 should still be stacked above window1, even when | |
| 2356 // hidden. | |
| 2357 EXPECT_TRUE(WindowIsAbove(window11.get(), window1.get())); | |
| 2358 EXPECT_TRUE(LayerIsAbove(window11.get(), window1.get())); | |
| 2359 | |
| 2360 // A new transient should still be above window1. It will appear behind | |
| 2361 // window11 because we don't stack windows on top of targets with NULL | |
| 2362 // delegates. | |
| 2363 scoped_ptr<Window> window12(CreateTransientChild(12, window1.get())); | |
| 2364 window12->Show(); | |
| 2365 | |
| 2366 EXPECT_TRUE(WindowIsAbove(window12.get(), window1.get())); | |
| 2367 EXPECT_TRUE(LayerIsAbove(window12.get(), window1.get())); | |
| 2368 | |
| 2369 // In earlier versions of the StackChildAbove() method, attempting to stack | |
| 2370 // window1 above window12 at this point would actually restack the layers | |
| 2371 // resulting in window12's layer being below window1's layer (though the | |
| 2372 // windows themselves would still be correctly stacked, so events would pass | |
| 2373 // through.) | |
| 2374 root_window()->StackChildAbove(window1.get(), window12.get()); | |
| 2375 | |
| 2376 // Both window12 and its layer should be stacked above window1. | |
| 2377 EXPECT_TRUE(WindowIsAbove(window12.get(), window1.get())); | |
| 2378 EXPECT_TRUE(LayerIsAbove(window12.get(), window1.get())); | |
| 2379 } | |
| 2380 | |
| 2381 // Test for an issue where attempting to stack a primary window on top of a | |
| 2382 // transient with a NULL layer delegate causes that primary window to be moved, | |
| 2383 // but the layer order not changed to match. http://crbug.com/112562 | |
| 2384 TEST_F(WindowTest, StackOverClosingTransient) { | |
| 2385 scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window())); | |
| 2386 scoped_ptr<Window> transient1(CreateTransientChild(11, window1.get())); | |
| 2387 scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window())); | |
| 2388 scoped_ptr<Window> transient2(CreateTransientChild(21, window2.get())); | |
| 2389 | |
| 2390 // Both windows and layers are stacked in creation order. | |
| 2391 Window* root = root_window(); | |
| 2392 ASSERT_EQ(4u, root->children().size()); | |
| 2393 EXPECT_EQ(root->children()[0], window1.get()); | |
| 2394 EXPECT_EQ(root->children()[1], transient1.get()); | |
| 2395 EXPECT_EQ(root->children()[2], window2.get()); | |
| 2396 EXPECT_EQ(root->children()[3], transient2.get()); | |
| 2397 ASSERT_EQ(4u, root->layer()->children().size()); | |
| 2398 EXPECT_EQ(root->layer()->children()[0], window1->layer()); | |
| 2399 EXPECT_EQ(root->layer()->children()[1], transient1->layer()); | |
| 2400 EXPECT_EQ(root->layer()->children()[2], window2->layer()); | |
| 2401 EXPECT_EQ(root->layer()->children()[3], transient2->layer()); | |
| 2402 EXPECT_EQ("1 11 2 21", ChildWindowIDsAsString(root_window())); | |
| 2403 | |
| 2404 // This brings window1 and its transient to the front. | |
| 2405 root->StackChildAtTop(window1.get()); | |
| 2406 EXPECT_EQ("2 21 1 11", ChildWindowIDsAsString(root_window())); | |
| 2407 | |
| 2408 EXPECT_EQ(root->children()[0], window2.get()); | |
| 2409 EXPECT_EQ(root->children()[1], transient2.get()); | |
| 2410 EXPECT_EQ(root->children()[2], window1.get()); | |
| 2411 EXPECT_EQ(root->children()[3], transient1.get()); | |
| 2412 EXPECT_EQ(root->layer()->children()[0], window2->layer()); | |
| 2413 EXPECT_EQ(root->layer()->children()[1], transient2->layer()); | |
| 2414 EXPECT_EQ(root->layer()->children()[2], window1->layer()); | |
| 2415 EXPECT_EQ(root->layer()->children()[3], transient1->layer()); | |
| 2416 | |
| 2417 // Pretend we're closing the top-most transient, then bring window2 to the | |
| 2418 // front. This mimics activating a browser window while the status bubble | |
| 2419 // is fading out. The transient should stay topmost. | |
| 2420 transient1->layer()->set_delegate(NULL); | |
| 2421 root->StackChildAtTop(window2.get()); | |
| 2422 | |
| 2423 EXPECT_EQ(root->children()[0], window1.get()); | |
| 2424 EXPECT_EQ(root->children()[1], window2.get()); | |
| 2425 EXPECT_EQ(root->children()[2], transient2.get()); | |
| 2426 EXPECT_EQ(root->children()[3], transient1.get()); | |
| 2427 EXPECT_EQ(root->layer()->children()[0], window1->layer()); | |
| 2428 EXPECT_EQ(root->layer()->children()[1], window2->layer()); | |
| 2429 EXPECT_EQ(root->layer()->children()[2], transient2->layer()); | |
| 2430 EXPECT_EQ(root->layer()->children()[3], transient1->layer()); | |
| 2431 | |
| 2432 // Close the transient. Remaining windows are stable. | |
| 2433 transient1.reset(); | |
| 2434 | |
| 2435 ASSERT_EQ(3u, root->children().size()); | |
| 2436 EXPECT_EQ(root->children()[0], window1.get()); | |
| 2437 EXPECT_EQ(root->children()[1], window2.get()); | |
| 2438 EXPECT_EQ(root->children()[2], transient2.get()); | |
| 2439 ASSERT_EQ(3u, root->layer()->children().size()); | |
| 2440 EXPECT_EQ(root->layer()->children()[0], window1->layer()); | |
| 2441 EXPECT_EQ(root->layer()->children()[1], window2->layer()); | |
| 2442 EXPECT_EQ(root->layer()->children()[2], transient2->layer()); | |
| 2443 | |
| 2444 // Open another window on top. | |
| 2445 scoped_ptr<Window> window3(CreateTestWindowWithId(3, root_window())); | |
| 2446 | |
| 2447 ASSERT_EQ(4u, root->children().size()); | |
| 2448 EXPECT_EQ(root->children()[0], window1.get()); | |
| 2449 EXPECT_EQ(root->children()[1], window2.get()); | |
| 2450 EXPECT_EQ(root->children()[2], transient2.get()); | |
| 2451 EXPECT_EQ(root->children()[3], window3.get()); | |
| 2452 ASSERT_EQ(4u, root->layer()->children().size()); | |
| 2453 EXPECT_EQ(root->layer()->children()[0], window1->layer()); | |
| 2454 EXPECT_EQ(root->layer()->children()[1], window2->layer()); | |
| 2455 EXPECT_EQ(root->layer()->children()[2], transient2->layer()); | |
| 2456 EXPECT_EQ(root->layer()->children()[3], window3->layer()); | |
| 2457 | |
| 2458 // Pretend we're closing the topmost non-transient window, then bring | |
| 2459 // window2 to the top. It should not move. | |
| 2460 window3->layer()->set_delegate(NULL); | |
| 2461 root->StackChildAtTop(window2.get()); | |
| 2462 | |
| 2463 ASSERT_EQ(4u, root->children().size()); | |
| 2464 EXPECT_EQ(root->children()[0], window1.get()); | |
| 2465 EXPECT_EQ(root->children()[1], window2.get()); | |
| 2466 EXPECT_EQ(root->children()[2], transient2.get()); | |
| 2467 EXPECT_EQ(root->children()[3], window3.get()); | |
| 2468 ASSERT_EQ(4u, root->layer()->children().size()); | |
| 2469 EXPECT_EQ(root->layer()->children()[0], window1->layer()); | |
| 2470 EXPECT_EQ(root->layer()->children()[1], window2->layer()); | |
| 2471 EXPECT_EQ(root->layer()->children()[2], transient2->layer()); | |
| 2472 EXPECT_EQ(root->layer()->children()[3], window3->layer()); | |
| 2473 | |
| 2474 // Bring window1 to the top. It should move ahead of window2, but not | |
| 2475 // ahead of window3 (with NULL delegate). | |
| 2476 root->StackChildAtTop(window1.get()); | |
| 2477 | |
| 2478 ASSERT_EQ(4u, root->children().size()); | |
| 2479 EXPECT_EQ(root->children()[0], window2.get()); | |
| 2480 EXPECT_EQ(root->children()[1], transient2.get()); | |
| 2481 EXPECT_EQ(root->children()[2], window1.get()); | |
| 2482 EXPECT_EQ(root->children()[3], window3.get()); | |
| 2483 ASSERT_EQ(4u, root->layer()->children().size()); | |
| 2484 EXPECT_EQ(root->layer()->children()[0], window2->layer()); | |
| 2485 EXPECT_EQ(root->layer()->children()[1], transient2->layer()); | |
| 2486 EXPECT_EQ(root->layer()->children()[2], window1->layer()); | |
| 2487 EXPECT_EQ(root->layer()->children()[3], window3->layer()); | |
| 2488 } | |
| 2489 | |
| 2490 class RootWindowAttachmentObserver : public WindowObserver { | 2160 class RootWindowAttachmentObserver : public WindowObserver { |
| 2491 public: | 2161 public: |
| 2492 RootWindowAttachmentObserver() : added_count_(0), removed_count_(0) {} | 2162 RootWindowAttachmentObserver() : added_count_(0), removed_count_(0) {} |
| 2493 virtual ~RootWindowAttachmentObserver() {} | 2163 virtual ~RootWindowAttachmentObserver() {} |
| 2494 | 2164 |
| 2495 int added_count() const { return added_count_; } | 2165 int added_count() const { return added_count_; } |
| 2496 int removed_count() const { return removed_count_; } | 2166 int removed_count() const { return removed_count_; } |
| 2497 | 2167 |
| 2498 void Clear() { | 2168 void Clear() { |
| 2499 added_count_ = 0; | 2169 added_count_ = 0; |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3000 o.ValidateState(index++, params); | 2670 o.ValidateState(index++, params); |
| 3001 params.receiver = root_window(); | 2671 params.receiver = root_window(); |
| 3002 o.ValidateState(index++, params); | 2672 o.ValidateState(index++, params); |
| 3003 | 2673 |
| 3004 w1.reset(); | 2674 w1.reset(); |
| 3005 w2.reset(); | 2675 w2.reset(); |
| 3006 } | 2676 } |
| 3007 | 2677 |
| 3008 } | 2678 } |
| 3009 | 2679 |
| 3010 namespace { | |
| 3011 | |
| 3012 // Used by NotifyDelegateAfterDeletingTransients. Adds a string to a vector when | |
| 3013 // OnWindowDestroyed() is invoked so that destruction order can be verified. | |
| 3014 class DestroyedTrackingDelegate : public TestWindowDelegate { | |
| 3015 public: | |
| 3016 explicit DestroyedTrackingDelegate(const std::string& name, | |
| 3017 std::vector<std::string>* results) | |
| 3018 : name_(name), | |
| 3019 results_(results) {} | |
| 3020 | |
| 3021 virtual void OnWindowDestroyed() OVERRIDE { | |
| 3022 results_->push_back(name_); | |
| 3023 } | |
| 3024 | |
| 3025 private: | |
| 3026 const std::string name_; | |
| 3027 std::vector<std::string>* results_; | |
| 3028 | |
| 3029 DISALLOW_COPY_AND_ASSIGN(DestroyedTrackingDelegate); | |
| 3030 }; | |
| 3031 | |
| 3032 } // namespace | |
| 3033 | |
| 3034 // Verifies the delegate is notified of destruction after transients are | |
| 3035 // destroyed. | |
| 3036 TEST_F(WindowTest, NotifyDelegateAfterDeletingTransients) { | |
| 3037 std::vector<std::string> destruction_order; | |
| 3038 | |
| 3039 DestroyedTrackingDelegate parent_delegate("parent", &destruction_order); | |
| 3040 scoped_ptr<Window> parent(new Window(&parent_delegate)); | |
| 3041 parent->Init(ui::LAYER_NOT_DRAWN); | |
| 3042 | |
| 3043 DestroyedTrackingDelegate transient_delegate("transient", &destruction_order); | |
| 3044 Window* transient = new Window(&transient_delegate); // Owned by |parent|. | |
| 3045 transient->Init(ui::LAYER_NOT_DRAWN); | |
| 3046 parent->AddTransientChild(transient); | |
| 3047 parent.reset(); | |
| 3048 | |
| 3049 ASSERT_EQ(2u, destruction_order.size()); | |
| 3050 EXPECT_EQ("transient", destruction_order[0]); | |
| 3051 EXPECT_EQ("parent", destruction_order[1]); | |
| 3052 } | |
| 3053 | |
| 3054 // Verifies SchedulePaint() on a layerless window results in damaging the right | 2680 // Verifies SchedulePaint() on a layerless window results in damaging the right |
| 3055 // thing. | 2681 // thing. |
| 3056 TEST_F(WindowTest, LayerlessWindowSchedulePaint) { | 2682 TEST_F(WindowTest, LayerlessWindowSchedulePaint) { |
| 3057 Window root(NULL); | 2683 Window root(NULL); |
| 3058 root.Init(ui::LAYER_NOT_DRAWN); | 2684 root.Init(ui::LAYER_NOT_DRAWN); |
| 3059 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | 2685 root.SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 3060 | 2686 |
| 3061 Window* layerless_window = new Window(NULL); // Owned by |root|. | 2687 Window* layerless_window = new Window(NULL); // Owned by |root|. |
| 3062 layerless_window->InitWithWindowLayerType(WINDOW_LAYER_NONE); | 2688 layerless_window->InitWithWindowLayerType(WINDOW_LAYER_NONE); |
| 3063 layerless_window->SetBounds(gfx::Rect(10, 11, 12, 13)); | 2689 layerless_window->SetBounds(gfx::Rect(10, 11, 12, 13)); |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3708 BuildRootLayerTreeDescription(*root.layer())) | 3334 BuildRootLayerTreeDescription(*root.layer())) |
| 3709 << "layer tree doesn't match at " << i; | 3335 << "layer tree doesn't match at " << i; |
| 3710 EXPECT_EQ(data[i].expected_description, | 3336 EXPECT_EQ(data[i].expected_description, |
| 3711 BuildRootWindowTreeDescription(root)) | 3337 BuildRootWindowTreeDescription(root)) |
| 3712 << "window tree doesn't match at " << i; | 3338 << "window tree doesn't match at " << i; |
| 3713 } | 3339 } |
| 3714 } | 3340 } |
| 3715 | 3341 |
| 3716 } // namespace test | 3342 } // namespace test |
| 3717 } // namespace aura | 3343 } // namespace aura |
| OLD | NEW |