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

Side by Side Diff: ash/wm/window_cycle_controller.cc

Issue 10700057: Add always on top windows to the alt+tab list (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix clang Created 8 years, 4 months 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
OLDNEW
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/window_cycle_controller.h" 5 #include "ash/wm/window_cycle_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ash/shell.h" 9 #include "ash/shell.h"
10 #include "ash/shell_delegate.h" 10 #include "ash/shell_delegate.h"
11 #include "ash/shell_window_ids.h" 11 #include "ash/shell_window_ids.h"
12 #include "ash/wm/activation_controller.h"
12 #include "ash/wm/window_cycle_list.h" 13 #include "ash/wm/window_cycle_list.h"
13 #include "ash/wm/window_util.h" 14 #include "ash/wm/window_util.h"
14 #include "ui/aura/event.h" 15 #include "ui/aura/event.h"
15 #include "ui/aura/event_filter.h" 16 #include "ui/aura/event_filter.h"
16 #include "ui/aura/root_window.h" 17 #include "ui/aura/root_window.h"
17 18
18 namespace ash { 19 namespace ash {
19 20
20 namespace { 21 namespace {
21 22
23 // List of containers whose children we will cycle through.
24 const int kContainerIds[] = {
25 internal::kShellWindowId_DefaultContainer,
26 internal::kShellWindowId_AlwaysOnTopContainer
27 };
28
22 // Filter to watch for the termination of a keyboard gesture to cycle through 29 // Filter to watch for the termination of a keyboard gesture to cycle through
23 // multiple windows. 30 // multiple windows.
24 class WindowCycleEventFilter : public aura::EventFilter { 31 class WindowCycleEventFilter : public aura::EventFilter {
25 public: 32 public:
26 WindowCycleEventFilter(); 33 WindowCycleEventFilter();
27 virtual ~WindowCycleEventFilter(); 34 virtual ~WindowCycleEventFilter();
28 35
29 // Overridden from aura::EventFilter: 36 // Overridden from aura::EventFilter:
30 virtual bool PreHandleKeyEvent(aura::Window* target, 37 virtual bool PreHandleKeyEvent(aura::Window* target,
31 aura::KeyEvent* event) OVERRIDE; 38 aura::KeyEvent* event) OVERRIDE;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 aura::GestureEvent* event) { 83 aura::GestureEvent* event) {
77 return ui::GESTURE_STATUS_UNKNOWN; // Not handled. 84 return ui::GESTURE_STATUS_UNKNOWN; // Not handled.
78 } 85 }
79 86
80 } // namespace 87 } // namespace
81 88
82 ////////////////////////////////////////////////////////////////////////////// 89 //////////////////////////////////////////////////////////////////////////////
83 // WindowCycleController, public: 90 // WindowCycleController, public:
84 91
85 WindowCycleController::WindowCycleController() { 92 WindowCycleController::WindowCycleController() {
93 Shell::GetInstance()->activation_controller()->AddObserver(this);
86 } 94 }
87 95
88 WindowCycleController::~WindowCycleController() { 96 WindowCycleController::~WindowCycleController() {
97 Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
98 for (Shell::RootWindowList::const_iterator iter = root_windows.begin();
99 iter != root_windows.end(); ++iter) {
100 for (size_t i = 0; i < arraysize(kContainerIds); ++i) {
101 aura::Window* container = Shell::GetContainer(*iter, kContainerIds[i]);
102 if (container)
103 container->RemoveObserver(this);
104 }
105 }
106
107 Shell::GetInstance()->activation_controller()->RemoveObserver(this);
89 StopCycling(); 108 StopCycling();
90 } 109 }
91 110
92 // static 111 // static
93 bool WindowCycleController::CanCycle() { 112 bool WindowCycleController::CanCycle() {
94 // Don't allow window cycling if the screen is locked or a modal dialog is 113 // Don't allow window cycling if the screen is locked or a modal dialog is
95 // open. 114 // open.
96 return !Shell::GetInstance()->IsScreenLocked() && 115 return !Shell::GetInstance()->IsScreenLocked() &&
97 !Shell::GetInstance()->IsModalWindowOpen(); 116 !Shell::GetInstance()->IsModalWindowOpen();
98 } 117 }
(...skipping 20 matching lines...) Expand all
119 Step(direction); 138 Step(direction);
120 StopCycling(); 139 StopCycling();
121 } 140 }
122 } 141 }
123 142
124 void WindowCycleController::AltKeyReleased() { 143 void WindowCycleController::AltKeyReleased() {
125 StopCycling(); 144 StopCycling();
126 } 145 }
127 146
128 // static 147 // static
129 std::vector<aura::Window*> WindowCycleController::BuildWindowList() { 148 std::vector<aura::Window*> WindowCycleController::BuildWindowList(
149 const std::list<aura::Window*>* mru_windows) {
130 WindowCycleList::WindowList windows; 150 WindowCycleList::WindowList windows;
131 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 151 Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
132 152
133 for (Shell::RootWindowList::const_iterator iter = root_windows.begin(); 153 for (Shell::RootWindowList::const_iterator iter = root_windows.begin();
134 iter != root_windows.end(); ++iter) { 154 iter != root_windows.end(); ++iter) {
135 if (*iter == Shell::GetActiveRootWindow()) 155 if (*iter == Shell::GetActiveRootWindow())
136 continue; 156 continue;
137 aura::Window* default_container = Shell::GetContainer( 157 for (size_t i = 0; i < arraysize(kContainerIds); ++i) {
138 *iter, internal::kShellWindowId_DefaultContainer); 158 aura::Window* container = Shell::GetContainer(*iter, kContainerIds[i]);
139 WindowCycleList::WindowList children = default_container->children(); 159 WindowCycleList::WindowList children = container->children();
160 windows.insert(windows.end(), children.begin(), children.end());
161 }
162 }
163
164 for (size_t i = 0; i < arraysize(kContainerIds); ++i) {
165 aura::Window* container =
166 Shell::GetContainer(Shell::GetActiveRootWindow(), kContainerIds[i]);
167
168 WindowCycleList::WindowList children = container->children();
140 windows.insert(windows.end(), children.begin(), children.end()); 169 windows.insert(windows.end(), children.begin(), children.end());
141 } 170 }
142 // Add windows in the active root windows last so that the topmost window
sky 2012/08/02 21:18:00 Move this comment to 164ish new.
Zachary Kuznia 2012/08/06 05:56:03 Done.
143 // in the active root window becomes the front of the list.
144 aura::Window* default_container = Shell::GetContainer(
145 Shell::GetActiveRootWindow(),
146 internal::kShellWindowId_DefaultContainer);
147
148 WindowCycleList::WindowList children = default_container->children();
149 windows.insert(windows.end(), children.begin(), children.end());
150 171
151 // Removes unfocusable windows. 172 // Removes unfocusable windows.
152 WindowCycleList::WindowList::iterator last = 173 WindowCycleList::WindowList::iterator last =
153 std::remove_if( 174 std::remove_if(
154 windows.begin(), 175 windows.begin(),
155 windows.end(), 176 windows.end(),
156 std::not1(std::ptr_fun(ash::wm::CanActivateWindow))); 177 std::not1(std::ptr_fun(ash::wm::CanActivateWindow)));
157 windows.erase(last, windows.end()); 178 windows.erase(last, windows.end());
179
180 // Put the windows in the mru_windows list at the head, if it's available.
181 if (mru_windows) {
182 // Iterate through the list backwards, so that we can move each window to
183 // the front of the windows list as we find them.
184 for (std::list<aura::Window*>::const_reverse_iterator ix =
185 mru_windows->rbegin();
186 ix != mru_windows->rend(); ++ix) {
187 WindowCycleList::WindowList::iterator window =
188 std::find(windows.begin(), windows.end(), *ix);
189 if (window != windows.end()) {
190 windows.erase(window);
191 windows.push_back(*ix);
192 }
193 }
194 }
195
158 // Window cycling expects the topmost window at the front of the list. 196 // Window cycling expects the topmost window at the front of the list.
159 std::reverse(windows.begin(), windows.end()); 197 std::reverse(windows.begin(), windows.end());
198
160 return windows; 199 return windows;
161 } 200 }
162 201
202 void WindowCycleController::OnRootWindowAdded(aura::RootWindow* root_window) {
203 for (size_t i = 0; i < arraysize(kContainerIds); ++i) {
204 aura::Window* container =
205 Shell::GetContainer(root_window, kContainerIds[i]);
206 container->AddObserver(this);
207 }
208 }
209
163 ////////////////////////////////////////////////////////////////////////////// 210 //////////////////////////////////////////////////////////////////////////////
164 // WindowCycleController, private: 211 // WindowCycleController, private:
165 212
166 void WindowCycleController::StartCycling() { 213 void WindowCycleController::StartCycling() {
167 windows_.reset(new WindowCycleList(BuildWindowList())); 214 windows_.reset(new WindowCycleList(BuildWindowList(&mru_windows_)));
168 } 215 }
169 216
170 void WindowCycleController::Step(Direction direction) { 217 void WindowCycleController::Step(Direction direction) {
171 DCHECK(windows_.get()); 218 DCHECK(windows_.get());
172 windows_->Step(direction == FORWARD ? WindowCycleList::FORWARD : 219 windows_->Step(direction == FORWARD ? WindowCycleList::FORWARD :
173 WindowCycleList::BACKWARD); 220 WindowCycleList::BACKWARD);
174 } 221 }
175 222
176 void WindowCycleController::StopCycling() { 223 void WindowCycleController::StopCycling() {
177 windows_.reset(); 224 windows_.reset();
178 // Remove our key event filter. 225 // Remove our key event filter.
179 if (event_filter_.get()) { 226 if (event_filter_.get()) {
180 Shell::GetInstance()->RemoveEnvEventFilter(event_filter_.get()); 227 Shell::GetInstance()->RemoveEnvEventFilter(event_filter_.get());
181 event_filter_.reset(); 228 event_filter_.reset();
182 } 229 }
230
231 // Add the currently focused window to the MRU list
232 aura::Window* active_window = wm::GetActiveWindow();
233 mru_windows_.remove(active_window);
234 mru_windows_.push_front(active_window);
235 }
236
237 // static
238 bool WindowCycleController::IsTrackedContainer(aura::Window* window) {
239 if (!window)
240 return false;
241 for (size_t i = 0; i < arraysize(kContainerIds); ++i) {
242 if (window->id() == kContainerIds[i]) {
243 return true;
244 }
245 }
246 return false;
183 } 247 }
184 248
185 void WindowCycleController::InstallEventFilter() { 249 void WindowCycleController::InstallEventFilter() {
186 event_filter_.reset(new WindowCycleEventFilter()); 250 event_filter_.reset(new WindowCycleEventFilter());
187 Shell::GetInstance()->AddEnvEventFilter(event_filter_.get()); 251 Shell::GetInstance()->AddEnvEventFilter(event_filter_.get());
188 } 252 }
189 253
254 void WindowCycleController::OnWindowActivated(aura::Window* active,
255 aura::Window* old_active) {
256 if (active && !IsCycling() && IsTrackedContainer(active->parent())) {
257 mru_windows_.remove(active);
258 mru_windows_.push_front(active);
259 }
260 }
261
262 void WindowCycleController::OnWillRemoveWindow(aura::Window* window) {
263 mru_windows_.remove(window);
264 }
265
266 void WindowCycleController::OnWindowDestroying(aura::Window* window) {
267 window->RemoveObserver(this);
268 }
269
190 } // namespace ash 270 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698