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 "ash/wm/workspace/workspace_manager.h" | 5 #include "ash/wm/workspace/workspace_manager.h" |
6 | 6 |
| 7 #include <map> |
| 8 |
7 #include "ash/ash_switches.h" | 9 #include "ash/ash_switches.h" |
8 #include "ash/root_window_controller.h" | 10 #include "ash/root_window_controller.h" |
9 #include "ash/screen_ash.h" | 11 #include "ash/screen_ash.h" |
10 #include "ash/shelf/shelf_layout_manager.h" | 12 #include "ash/shelf/shelf_layout_manager.h" |
11 #include "ash/shelf/shelf_widget.h" | 13 #include "ash/shelf/shelf_widget.h" |
12 #include "ash/shell.h" | 14 #include "ash/shell.h" |
13 #include "ash/shell_window_ids.h" | 15 #include "ash/shell_window_ids.h" |
14 #include "ash/system/status_area_widget.h" | 16 #include "ash/system/status_area_widget.h" |
15 #include "ash/test/ash_test_base.h" | 17 #include "ash/test/ash_test_base.h" |
16 #include "ash/test/shell_test_api.h" | 18 #include "ash/test/shell_test_api.h" |
(...skipping 16 matching lines...) Expand all Loading... |
33 #include "ui/compositor/layer.h" | 35 #include "ui/compositor/layer.h" |
34 #include "ui/compositor/scoped_animation_duration_scale_mode.h" | 36 #include "ui/compositor/scoped_animation_duration_scale_mode.h" |
35 #include "ui/gfx/screen.h" | 37 #include "ui/gfx/screen.h" |
36 #include "ui/views/widget/widget.h" | 38 #include "ui/views/widget/widget.h" |
37 | 39 |
38 using aura::Window; | 40 using aura::Window; |
39 | 41 |
40 namespace ash { | 42 namespace ash { |
41 namespace internal { | 43 namespace internal { |
42 | 44 |
| 45 // Returns a string containing the names of all the children of |window| (in |
| 46 // order). Each entry is separated by a space. |
| 47 std::string GetWindowNames(const aura::Window* window) { |
| 48 std::string result; |
| 49 for (size_t i = 0; i < window->children().size(); ++i) { |
| 50 if (i != 0) |
| 51 result += " "; |
| 52 result += window->children()[i]->name(); |
| 53 } |
| 54 return result; |
| 55 } |
| 56 |
| 57 // Returns a string containing the names of windows corresponding to each of the |
| 58 // child layers of |window|'s layer. Any layers that don't correspond to a child |
| 59 // Window of |window| are ignored. The result is ordered based on the layer |
| 60 // ordering. |
| 61 std::string GetLayerNames(const aura::Window* window) { |
| 62 typedef std::map<const ui::Layer*, std::string> LayerToWindowNameMap; |
| 63 LayerToWindowNameMap window_names; |
| 64 for (size_t i = 0; i < window->children().size(); ++i) { |
| 65 window_names[window->children()[i]->layer()] = |
| 66 window->children()[i]->name(); |
| 67 } |
| 68 |
| 69 std::string result; |
| 70 const std::vector<ui::Layer*>& layers(window->layer()->children()); |
| 71 for (size_t i = 0; i < layers.size(); ++i) { |
| 72 LayerToWindowNameMap::iterator layer_i = |
| 73 window_names.find(layers[i]); |
| 74 if (layer_i != window_names.end()) { |
| 75 if (!result.empty()) |
| 76 result += " "; |
| 77 result += layer_i->second; |
| 78 } |
| 79 } |
| 80 return result; |
| 81 } |
| 82 |
43 class WorkspaceManagerTest : public test::AshTestBase { | 83 class WorkspaceManagerTest : public test::AshTestBase { |
44 public: | 84 public: |
45 WorkspaceManagerTest() : manager_(NULL) {} | 85 WorkspaceManagerTest() : manager_(NULL) {} |
46 virtual ~WorkspaceManagerTest() {} | 86 virtual ~WorkspaceManagerTest() {} |
47 | 87 |
48 aura::Window* CreateTestWindowUnparented() { | 88 aura::Window* CreateTestWindowUnparented() { |
49 aura::Window* window = new aura::Window(NULL); | 89 aura::Window* window = new aura::Window(NULL); |
50 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); | 90 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); |
51 window->SetType(aura::client::WINDOW_TYPE_NORMAL); | 91 window->SetType(aura::client::WINDOW_TYPE_NORMAL); |
52 window->Init(ui::LAYER_TEXTURED); | 92 window->Init(ui::LAYER_TEXTURED); |
(...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1455 | 1495 |
1456 window1->layer()->GetAnimator()->StopAnimating(); | 1496 window1->layer()->GetAnimator()->StopAnimating(); |
1457 window2->layer()->GetAnimator()->StopAnimating(); | 1497 window2->layer()->GetAnimator()->StopAnimating(); |
1458 // |window1| should be flush right and |window2| flush left. | 1498 // |window1| should be flush right and |window2| flush left. |
1459 EXPECT_EQ(base::IntToString( | 1499 EXPECT_EQ(base::IntToString( |
1460 desktop_area.width() - window1->bounds().width()) + | 1500 desktop_area.width() - window1->bounds().width()) + |
1461 ",32 640x320", window1->bounds().ToString()); | 1501 ",32 640x320", window1->bounds().ToString()); |
1462 EXPECT_EQ("0,48 256x512", window2->bounds().ToString()); | 1502 EXPECT_EQ("0,48 256x512", window2->bounds().ToString()); |
1463 } | 1503 } |
1464 | 1504 |
| 1505 // This tests simulates a browser and an app and verifies the ordering of the |
| 1506 // windows and layers doesn't get out of sync as various operations occur. Its |
| 1507 // really testing code in FocusController, but easier to simulate here. Just as |
| 1508 // with a real browser the browser here has a transient child window |
| 1509 // (corresponds to the status bubble). |
| 1510 TEST_F(WorkspaceManagerTest, VerifyLayerOrdering) { |
| 1511 scoped_ptr<Window> browser( |
| 1512 aura::test::CreateTestWindowWithDelegate( |
| 1513 NULL, |
| 1514 aura::client::WINDOW_TYPE_NORMAL, |
| 1515 gfx::Rect(5, 6, 7, 8), |
| 1516 NULL)); |
| 1517 browser->SetName("browser"); |
| 1518 SetDefaultParentByPrimaryRootWindow(browser.get()); |
| 1519 browser->Show(); |
| 1520 wm::ActivateWindow(browser.get()); |
| 1521 |
| 1522 // |status_bubble| is made a transient child of |browser| and as a result |
| 1523 // owned by |browser|. |
| 1524 aura::test::TestWindowDelegate* status_bubble_delegate = |
| 1525 aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(); |
| 1526 status_bubble_delegate->set_can_focus(false); |
| 1527 Window* status_bubble = |
| 1528 aura::test::CreateTestWindowWithDelegate( |
| 1529 status_bubble_delegate, |
| 1530 aura::client::WINDOW_TYPE_POPUP, |
| 1531 gfx::Rect(5, 6, 7, 8), |
| 1532 NULL); |
| 1533 browser->AddTransientChild(status_bubble); |
| 1534 SetDefaultParentByPrimaryRootWindow(status_bubble); |
| 1535 status_bubble->SetName("status_bubble"); |
| 1536 |
| 1537 scoped_ptr<Window> app( |
| 1538 aura::test::CreateTestWindowWithDelegate( |
| 1539 NULL, |
| 1540 aura::client::WINDOW_TYPE_NORMAL, |
| 1541 gfx::Rect(5, 6, 7, 8), |
| 1542 NULL)); |
| 1543 app->SetName("app"); |
| 1544 SetDefaultParentByPrimaryRootWindow(app.get()); |
| 1545 |
| 1546 aura::Window* parent = browser->parent(); |
| 1547 |
| 1548 app->Show(); |
| 1549 wm::ActivateWindow(app.get()); |
| 1550 EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent)); |
| 1551 |
| 1552 // Minimize the app, focus should go the browser. |
| 1553 app->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); |
| 1554 EXPECT_TRUE(wm::IsActiveWindow(browser.get())); |
| 1555 EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent)); |
| 1556 |
| 1557 // Minimize the browser (neither windows are focused). |
| 1558 browser->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); |
| 1559 EXPECT_FALSE(wm::IsActiveWindow(browser.get())); |
| 1560 EXPECT_FALSE(wm::IsActiveWindow(app.get())); |
| 1561 EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent)); |
| 1562 |
| 1563 // Show the browser (which should restore it). |
| 1564 browser->Show(); |
| 1565 EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent)); |
| 1566 |
| 1567 // Activate the browser. |
| 1568 ash::wm::ActivateWindow(browser.get()); |
| 1569 EXPECT_TRUE(wm::IsActiveWindow(browser.get())); |
| 1570 EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent)); |
| 1571 |
| 1572 // Restore the app. This differs from above code for |browser| as internally |
| 1573 // the app code does this. Restoring this way or using Show() should not make |
| 1574 // a difference. |
| 1575 app->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); |
| 1576 EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent)); |
| 1577 |
| 1578 // Activate the app. |
| 1579 ash::wm::ActivateWindow(app.get()); |
| 1580 EXPECT_TRUE(wm::IsActiveWindow(app.get())); |
| 1581 EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent)); |
| 1582 } |
| 1583 |
1465 namespace { | 1584 namespace { |
1466 | 1585 |
1467 // Used by DragMaximizedNonTrackedWindow to track how many times the window | 1586 // Used by DragMaximizedNonTrackedWindow to track how many times the window |
1468 // hierarchy changes. | 1587 // hierarchy changes. |
1469 class DragMaximizedNonTrackedWindowObserver | 1588 class DragMaximizedNonTrackedWindowObserver |
1470 : public aura::WindowObserver { | 1589 : public aura::WindowObserver { |
1471 public: | 1590 public: |
1472 DragMaximizedNonTrackedWindowObserver() : change_count_(0) { | 1591 DragMaximizedNonTrackedWindowObserver() : change_count_(0) { |
1473 } | 1592 } |
1474 | 1593 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1544 // Marking the window tracked again should snap back to origin. | 1663 // Marking the window tracked again should snap back to origin. |
1545 EXPECT_EQ("0 M1 active=1", StateString()); | 1664 EXPECT_EQ("0 M1 active=1", StateString()); |
1546 EXPECT_EQ(max_bounds.ToString(), w1->bounds().ToString()); | 1665 EXPECT_EQ(max_bounds.ToString(), w1->bounds().ToString()); |
1547 EXPECT_EQ(0, observer.change_count()); | 1666 EXPECT_EQ(0, observer.change_count()); |
1548 | 1667 |
1549 w1->parent()->parent()->RemoveObserver(&observer); | 1668 w1->parent()->parent()->RemoveObserver(&observer); |
1550 } | 1669 } |
1551 | 1670 |
1552 } // namespace internal | 1671 } // namespace internal |
1553 } // namespace ash | 1672 } // namespace ash |
OLD | NEW |