OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_shell/stacking_controller.h" | 5 #include "ui/aura_shell/stacking_controller.h" |
6 | 6 |
7 #include "ui/aura/client/aura_constants.h" | 7 #include "ui/aura/client/aura_constants.h" |
8 #include "ui/aura/root_window.h" | 8 #include "ui/aura/root_window.h" |
9 #include "ui/aura/window.h" | 9 #include "ui/aura/window.h" |
10 #include "ui/aura_shell/always_on_top_controller.h" | 10 #include "ui/aura_shell/always_on_top_controller.h" |
11 #include "ui/aura_shell/shell.h" | 11 #include "ui/aura_shell/shell.h" |
12 #include "ui/aura_shell/shell_window_ids.h" | 12 #include "ui/aura_shell/shell_window_ids.h" |
13 | 13 |
14 namespace aura_shell { | 14 namespace aura_shell { |
15 namespace internal { | 15 namespace internal { |
16 namespace { | 16 namespace { |
17 | 17 |
18 aura::Window* GetContainer(int id) { | 18 aura::Window* GetContainer(int id) { |
19 return Shell::GetInstance()->GetContainer(id); | 19 return Shell::GetInstance()->GetContainer(id); |
20 } | 20 } |
21 | 21 |
| 22 // Returns true if children of |window| can be activated. |
| 23 bool SupportsChildActivation(aura::Window* window) { |
| 24 return window->id() == kShellWindowId_DefaultContainer || |
| 25 window->id() == kShellWindowId_AlwaysOnTopContainer || |
| 26 window->id() == kShellWindowId_ModalContainer || |
| 27 window->id() == kShellWindowId_LockModalContainer; |
| 28 } |
| 29 |
22 bool IsWindowModal(aura::Window* window) { | 30 bool IsWindowModal(aura::Window* window) { |
23 return window->transient_parent() && window->GetIntProperty(aura::kModalKey); | 31 return window->transient_parent() && window->GetIntProperty(aura::kModalKey); |
24 } | 32 } |
25 | 33 |
26 } // namespace | 34 } // namespace |
27 | 35 |
28 //////////////////////////////////////////////////////////////////////////////// | 36 //////////////////////////////////////////////////////////////////////////////// |
29 // StackingController, public: | 37 // StackingController, public: |
30 | 38 |
31 StackingController::StackingController() { | 39 StackingController::StackingController() { |
32 aura::RootWindow::GetInstance()->SetStackingClient(this); | 40 aura::RootWindow::GetInstance()->SetStackingClient(this); |
33 } | 41 } |
34 | 42 |
35 StackingController::~StackingController() { | 43 StackingController::~StackingController() { |
36 } | 44 } |
37 | 45 |
38 void StackingController::Init() { | 46 void StackingController::Init() { |
39 always_on_top_controller_.reset(new internal::AlwaysOnTopController); | 47 always_on_top_controller_.reset(new internal::AlwaysOnTopController); |
40 always_on_top_controller_->SetContainers( | 48 always_on_top_controller_->SetContainers( |
41 GetContainer(internal::kShellWindowId_DefaultContainer), | 49 GetContainer(internal::kShellWindowId_DefaultContainer), |
42 GetContainer(internal::kShellWindowId_AlwaysOnTopContainer)); | 50 GetContainer(internal::kShellWindowId_AlwaysOnTopContainer)); |
43 } | 51 } |
44 | 52 |
| 53 // static |
| 54 aura::Window* StackingController::GetActivatableWindow(aura::Window* window) { |
| 55 aura::Window* parent = window->parent(); |
| 56 aura::Window* child = window; |
| 57 while (parent) { |
| 58 if (SupportsChildActivation(parent)) |
| 59 return child; |
| 60 // If |child| isn't activatable, but has transient parent, trace |
| 61 // that path instead. |
| 62 if (child->transient_parent()) |
| 63 return GetActivatableWindow(child->transient_parent()); |
| 64 parent = parent->parent(); |
| 65 child = child->parent(); |
| 66 } |
| 67 return NULL; |
| 68 } |
| 69 |
45 //////////////////////////////////////////////////////////////////////////////// | 70 //////////////////////////////////////////////////////////////////////////////// |
46 // StackingController, aura::StackingClient implementation: | 71 // StackingController, aura::StackingClient implementation: |
47 | 72 |
48 void StackingController::AddChildToDefaultParent(aura::Window* window) { | 73 void StackingController::AddChildToDefaultParent(aura::Window* window) { |
49 aura::Window* parent = NULL; | 74 aura::Window* parent = NULL; |
50 switch (window->type()) { | 75 switch (window->type()) { |
51 case aura::WINDOW_TYPE_NORMAL: | 76 case aura::WINDOW_TYPE_NORMAL: |
52 case aura::WINDOW_TYPE_POPUP: | 77 case aura::WINDOW_TYPE_POPUP: |
53 if (IsWindowModal(window)) { | 78 if (IsWindowModal(window)) { |
54 parent = GetModalContainer(window); | 79 parent = GetModalContainer(window); |
55 break; | 80 break; |
56 } | 81 } |
57 parent = always_on_top_controller_->GetContainer(window); | 82 parent = always_on_top_controller_->GetContainer(window); |
58 break; | 83 break; |
59 case aura::WINDOW_TYPE_MENU: | 84 case aura::WINDOW_TYPE_MENU: |
60 case aura::WINDOW_TYPE_TOOLTIP: | 85 case aura::WINDOW_TYPE_TOOLTIP: |
61 parent = GetContainer(internal::kShellWindowId_MenusAndTooltipsContainer); | 86 parent = GetContainer(internal::kShellWindowId_MenusAndTooltipsContainer); |
62 break; | 87 break; |
63 default: | 88 default: |
64 NOTREACHED() << "Window " << window->id() | 89 NOTREACHED() << "Window " << window->id() |
65 << " has unhandled type " << window->type(); | 90 << " has unhandled type " << window->type(); |
66 break; | 91 break; |
67 } | 92 } |
68 parent->AddChild(window); | 93 parent->AddChild(window); |
69 } | 94 } |
70 | 95 |
| 96 bool StackingController::CanActivateWindow(aura::Window* window) const { |
| 97 return window && SupportsChildActivation(window->parent()); |
| 98 } |
| 99 |
| 100 aura::Window* StackingController::GetTopmostWindowToActivate( |
| 101 aura::Window* ignore) const { |
| 102 const aura::Window* container = GetContainer(kShellWindowId_DefaultContainer); |
| 103 for (aura::Window::Windows::const_reverse_iterator i = |
| 104 container->children().rbegin(); |
| 105 i != container->children().rend(); |
| 106 ++i) { |
| 107 if (*i != ignore && (*i)->CanActivate()) |
| 108 return *i; |
| 109 } |
| 110 return NULL; |
| 111 } |
| 112 |
| 113 |
71 //////////////////////////////////////////////////////////////////////////////// | 114 //////////////////////////////////////////////////////////////////////////////// |
72 // StackingController, private: | 115 // StackingController, private: |
73 | 116 |
74 aura::Window* StackingController::GetModalContainer( | 117 aura::Window* StackingController::GetModalContainer( |
75 aura::Window* window) const { | 118 aura::Window* window) const { |
76 if (!IsWindowModal(window)) | 119 if (!IsWindowModal(window)) |
77 return NULL; | 120 return NULL; |
78 | 121 |
79 // If screen lock is not active, all modal windows are placed into the | 122 // If screen lock is not active, all modal windows are placed into the |
80 // normal modal container. | 123 // normal modal container. |
(...skipping 11 matching lines...) Expand all Loading... |
92 if (window_container_id < lock_container_id) | 135 if (window_container_id < lock_container_id) |
93 container = GetContainer(internal::kShellWindowId_ModalContainer); | 136 container = GetContainer(internal::kShellWindowId_ModalContainer); |
94 else | 137 else |
95 container = GetContainer(internal::kShellWindowId_LockModalContainer); | 138 container = GetContainer(internal::kShellWindowId_LockModalContainer); |
96 | 139 |
97 return container; | 140 return container; |
98 } | 141 } |
99 | 142 |
100 } // namespace internal | 143 } // namespace internal |
101 } // namespace aura_shell | 144 } // namespace aura_shell |
OLD | NEW |