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

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

Powered by Google App Engine
This is Rietveld 408576698