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

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
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 aura::ActivationDelegate* GetActivationDelegate(aura::Window* window) {
26 return reinterpret_cast<aura::ActivationDelegate*>(
27 window->GetProperty(aura::kActivationDelegateKey));
28 }
29
30 // Returns true if children of |window| can be activated.
31 bool SupportsChildActivation(aura::Window* window) {
32 return window->id() == kShellWindowId_DefaultContainer ||
33 window->id() == kShellWindowId_AlwaysOnTopContainer ||
34 window->id() == kShellWindowId_ModalContainer ||
35 window->id() == kShellWindowId_LockModalContainer;
36 }
37
38 // Returns true if |window| can be activated or deactivated.
39 // A window manager typically defines some notion of "top level window" that
40 // supports activation/deactivation.
41 bool CanActivateWindow(aura::Window* window) {
42 return window &&
43 window->IsVisible() &&
44 (!GetActivationDelegate(window) ||
45 GetActivationDelegate(window)->ShouldActivate(NULL)) &&
46 SupportsChildActivation(window->parent());
47 }
48
49 } // namespace
50
51 ////////////////////////////////////////////////////////////////////////////////
52 // ActivationController, public:
53
54 ActivationController::ActivationController()
55 : updating_activation_(false),
56 default_container_for_test_(NULL) {
57 aura::RootWindow::GetInstance()->SetProperty(
58 aura::kRootWindowActivationClient, this);
59 aura::RootWindow::GetInstance()->AddRootWindowObserver(this);
60 }
61
62 ActivationController::~ActivationController() {
63 aura::RootWindow::GetInstance()->RemoveRootWindowObserver(this);
64 }
65
66 // static
67 aura::Window* ActivationController::GetActivatableWindow(aura::Window* window) {
68 aura::Window* parent = window->parent();
69 aura::Window* child = window;
70 while (parent) {
71 if (SupportsChildActivation(parent))
72 return child;
73 // If |child| isn't activatable, but has transient parent, trace
74 // that path instead.
75 if (child->transient_parent())
76 return GetActivatableWindow(child->transient_parent());
77 parent = parent->parent();
78 child = child->parent();
79 }
80 return NULL;
81 }
82
83 // static
84 bool ActivationController::CanFocusWindow(aura::Window* window) {
85 return CanActivateWindow(GetActivatableWindow(window));
86 }
87
88 ////////////////////////////////////////////////////////////////////////////////
89 // StackingController, aura::ActivationClient implementation:
90
91 void ActivationController::ActivateWindow(aura::Window* window) {
92 AutoReset<bool> in_activate_window(&updating_activation_, true);
93 if (!window)
94 return;
95 // Nothing may actually have changed.
96 aura::Window* old_active = GetActiveWindow();
97 if (old_active == window)
98 return;
99 // The stacking client may impose rules on what window configurations can be
100 // activated or deactivated.
101 if (!CanActivateWindow(window))
sky 2011/12/09 23:11:23 If we end up here because of focus change, wouldn'
Ben Goodger (Google) 2011/12/12 18:01:16 I am not quite sure what you mean by this. I've ad
sky 2011/12/12 18:06:11 Say you had a window that didn't want to become ac
102 return;
103
104 if (!window->Contains(window->GetFocusManager()->GetFocusedWindow()))
105 window->GetFocusManager()->SetFocusedWindow(window);
106 aura::RootWindow::GetInstance()->SetProperty(aura::kRootWindowActiveWindow,
107 window);
108 // Invoke OnLostActive after we've changed the active window. That way if the
109 // delegate queries for active state it doesn't think the window is still
110 // active.
111 if (old_active && GetActivationDelegate(old_active))
112 GetActivationDelegate(old_active)->OnLostActive();
113 if (window) {
114 window->parent()->StackChildAtTop(window);
115 if (GetActivationDelegate(window))
116 GetActivationDelegate(window)->OnActivated();
117 }
118 }
119
120 void ActivationController::DeactivateWindow(aura::Window* window) {
121 if (window)
122 ActivateNextWindow(window);
123 }
124
125 aura::Window* ActivationController::GetActiveWindow() {
126 return reinterpret_cast<aura::Window*>(
127 aura::RootWindow::GetInstance()->GetProperty(
128 aura::kRootWindowActiveWindow));
129 }
130
131 ////////////////////////////////////////////////////////////////////////////////
132 // ActivationController, aura::WindowObserver implementation:
133
134 void ActivationController::OnWindowVisibilityChanged(aura::Window* window,
135 bool visible) {
136 if (!visible)
137 ActivateNextWindow(window);
138 }
139
140 void ActivationController::OnWindowDestroyed(aura::Window* window) {
141 if (IsActiveWindow(window)) {
142 // Clear the property before activating something else, since
143 // ActivateWindow() will attempt to notify the window stored in this value
144 // otherwise.
145 aura::RootWindow::GetInstance()->SetProperty(aura::kRootWindowActiveWindow,
146 NULL);
147 ActivateWindow(GetTopmostWindowToActivate(window));
148 }
149 }
150
151 ////////////////////////////////////////////////////////////////////////////////
152 // ActivationController, aura::RootWindowObserver implementation:
153
154 void ActivationController::OnWindowInitialized(aura::Window* window) {
155 window->AddObserver(this);
sky 2011/12/09 23:11:23 It doesn't seem like you ever remove this. Maybe O
156 }
157
158 void ActivationController::OnWindowFocused(aura::Window* window) {
159 if (!updating_activation_)
160 ActivateWindow(GetActivatableWindow(window));
161 }
162
163 ////////////////////////////////////////////////////////////////////////////////
164 // ActivationController, private:
165
166 void ActivationController::ActivateNextWindow(aura::Window* window) {
167 if (IsActiveWindow(window))
168 ActivateWindow(GetTopmostWindowToActivate(window));
169 }
170
171 aura::Window* ActivationController::GetTopmostWindowToActivate(
172 aura::Window* ignore) const {
173 const aura::Window* container =
174 default_container_for_test_ ? default_container_for_test_ :
175 GetContainer(kShellWindowId_DefaultContainer);
176 for (aura::Window::Windows::const_reverse_iterator i =
177 container->children().rbegin();
178 i != container->children().rend();
179 ++i) {
180 if (*i != ignore && CanActivateWindow(*i))
181 return *i;
182 }
183 return NULL;
184 }
185
186 } // namespace internal
187 } // namespace aura_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698