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

Side by Side Diff: ui/aura_shell/activation_controller.cc

Issue 8894018: Move the concept of Activation to the Shell. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years 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
« no previous file with comments | « ui/aura_shell/activation_controller.h ('k') | ui/aura_shell/activation_controller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/aura_shell/activation_controller.h"
6
7 #include "base/auto_reset.h"
8 #include "ui/aura/client/activation_delegate.h"
9 #include "ui/aura/client/aura_constants.h"
10 #include "ui/aura/root_window.h"
11 #include "ui/aura/window.h"
12 #include "ui/aura/window_delegate.h"
13 #include "ui/aura_shell/shell.h"
14 #include "ui/aura_shell/shell_window_ids.h"
15 #include "ui/aura_shell/window_util.h"
16
17 namespace aura_shell {
18 namespace internal {
19 namespace {
20
21 aura::Window* GetContainer(int id) {
22 return Shell::GetInstance()->GetContainer(id);
23 }
24
25 // Returns true if children of |window| can be activated.
26 bool SupportsChildActivation(aura::Window* window) {
27 return window->id() == kShellWindowId_DefaultContainer ||
28 window->id() == kShellWindowId_AlwaysOnTopContainer ||
29 window->id() == kShellWindowId_ModalContainer ||
30 window->id() == kShellWindowId_LockModalContainer;
31 }
32
33 // Returns true if |window| can be activated or deactivated.
34 // A window manager typically defines some notion of "top level window" that
35 // supports activation/deactivation.
36 bool CanActivateWindow(aura::Window* window) {
37 return window &&
38 window->IsVisible() &&
39 (!aura::ActivationDelegate::GetActivationDelegate(window) ||
40 aura::ActivationDelegate::GetActivationDelegate(window)->
41 ShouldActivate(NULL)) &&
42 SupportsChildActivation(window->parent());
43 }
44
45 } // namespace
46
47 ////////////////////////////////////////////////////////////////////////////////
48 // ActivationController, public:
49
50 ActivationController::ActivationController()
51 : updating_activation_(false),
52 default_container_for_test_(NULL) {
53 aura::ActivationClient::SetActivationClient(this);
54 aura::RootWindow::GetInstance()->AddRootWindowObserver(this);
55 }
56
57 ActivationController::~ActivationController() {
58 aura::RootWindow::GetInstance()->RemoveRootWindowObserver(this);
59 }
60
61 // static
62 aura::Window* ActivationController::GetActivatableWindow(aura::Window* window) {
63 aura::Window* parent = window->parent();
64 aura::Window* child = window;
65 while (parent) {
66 if (SupportsChildActivation(parent))
67 return child;
68 // If |child| isn't activatable, but has transient parent, trace
69 // that path instead.
70 if (child->transient_parent())
71 return GetActivatableWindow(child->transient_parent());
72 parent = parent->parent();
73 child = child->parent();
74 }
75 return NULL;
76 }
77
78 ////////////////////////////////////////////////////////////////////////////////
79 // StackingController, aura::ActivationClient implementation:
80
81 void ActivationController::ActivateWindow(aura::Window* window) {
82 // Prevent recursion when called from focus.
83 if (updating_activation_)
84 return;
85
86 AutoReset<bool> in_activate_window(&updating_activation_, true);
87 if (!window)
88 return;
89 // Nothing may actually have changed.
90 aura::Window* old_active = GetActiveWindow();
91 if (old_active == window)
92 return;
93 // The stacking client may impose rules on what window configurations can be
94 // activated or deactivated.
95 if (!CanActivateWindow(window))
96 return;
97
98 if (!window->Contains(window->GetFocusManager()->GetFocusedWindow()))
99 window->GetFocusManager()->SetFocusedWindow(window);
100 aura::RootWindow::GetInstance()->SetProperty(aura::kRootWindowActiveWindow,
101 window);
102 // Invoke OnLostActive after we've changed the active window. That way if the
103 // delegate queries for active state it doesn't think the window is still
104 // active.
105 if (old_active && aura::ActivationDelegate::GetActivationDelegate(old_active))
106 aura::ActivationDelegate::GetActivationDelegate(old_active)->OnLostActive();
107 if (window) {
108 window->parent()->StackChildAtTop(window);
109 if (aura::ActivationDelegate::GetActivationDelegate(window))
110 aura::ActivationDelegate::GetActivationDelegate(window)->OnActivated();
111 }
112 }
113
114 void ActivationController::DeactivateWindow(aura::Window* window) {
115 if (window)
116 ActivateNextWindow(window);
117 }
118
119 aura::Window* ActivationController::GetActiveWindow() {
120 return reinterpret_cast<aura::Window*>(
121 aura::RootWindow::GetInstance()->GetProperty(
122 aura::kRootWindowActiveWindow));
123 }
124
125 bool ActivationController::CanFocusWindow(aura::Window* window) const {
126 return CanActivateWindow(GetActivatableWindow(window));
127 }
128
129 ////////////////////////////////////////////////////////////////////////////////
130 // ActivationController, aura::WindowObserver implementation:
131
132 void ActivationController::OnWindowVisibilityChanged(aura::Window* window,
133 bool visible) {
134 if (!visible)
135 ActivateNextWindow(window);
136 }
137
138 void ActivationController::OnWindowDestroyed(aura::Window* window) {
139 if (IsActiveWindow(window)) {
140 // Clear the property before activating something else, since
141 // ActivateWindow() will attempt to notify the window stored in this value
142 // otherwise.
143 aura::RootWindow::GetInstance()->SetProperty(aura::kRootWindowActiveWindow,
144 NULL);
145 ActivateWindow(GetTopmostWindowToActivate(window));
146 }
147 window->RemoveObserver(this);
148 }
149
150 ////////////////////////////////////////////////////////////////////////////////
151 // ActivationController, aura::RootWindowObserver implementation:
152
153 void ActivationController::OnWindowInitialized(aura::Window* window) {
154 window->AddObserver(this);
155 }
156
157 void ActivationController::OnWindowFocused(aura::Window* window) {
158 ActivateWindow(GetActivatableWindow(window));
159 }
160
161 ////////////////////////////////////////////////////////////////////////////////
162 // ActivationController, private:
163
164 void ActivationController::ActivateNextWindow(aura::Window* window) {
165 if (IsActiveWindow(window))
166 ActivateWindow(GetTopmostWindowToActivate(window));
167 }
168
169 aura::Window* ActivationController::GetTopmostWindowToActivate(
170 aura::Window* ignore) const {
171 const aura::Window* container =
172 default_container_for_test_ ? default_container_for_test_ :
173 GetContainer(kShellWindowId_DefaultContainer);
174 for (aura::Window::Windows::const_reverse_iterator i =
175 container->children().rbegin();
176 i != container->children().rend();
177 ++i) {
178 if (*i != ignore && CanActivateWindow(*i))
179 return *i;
180 }
181 return NULL;
182 }
183
184 } // namespace internal
185 } // namespace aura_shell
OLDNEW
« no previous file with comments | « ui/aura_shell/activation_controller.h ('k') | ui/aura_shell/activation_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698