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

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: Use most recently used windows. Created 8 years, 5 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
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 aura::Window* target, 76 aura::Window* target,
76 aura::GestureEvent* event) { 77 aura::GestureEvent* event) {
77 return ui::GESTURE_STATUS_UNKNOWN; // Not handled. 78 return ui::GESTURE_STATUS_UNKNOWN; // Not handled.
78 } 79 }
79 80
80 } // namespace 81 } // namespace
81 82
82 ////////////////////////////////////////////////////////////////////////////// 83 //////////////////////////////////////////////////////////////////////////////
83 // WindowCycleController, public: 84 // WindowCycleController, public:
84 85
85 WindowCycleController::WindowCycleController() { 86 WindowCycleController::WindowCycleController() : mru_ignore_(false) {
87 Shell::GetInstance()->activation_controller()->AddObserver(this);
86 } 88 }
87 89
88 WindowCycleController::~WindowCycleController() { 90 WindowCycleController::~WindowCycleController() {
91 Shell::GetInstance()->activation_controller()->RemoveObserver(this);
89 StopCycling(); 92 StopCycling();
90 } 93 }
91 94
92 // static 95 // static
93 bool WindowCycleController::CanCycle() { 96 bool WindowCycleController::CanCycle() {
94 // Don't allow window cycling if the screen is locked or a modal dialog is 97 // Don't allow window cycling if the screen is locked or a modal dialog is
95 // open. 98 // open.
96 return !Shell::GetInstance()->IsScreenLocked() && 99 return !Shell::GetInstance()->IsScreenLocked() &&
97 !Shell::GetInstance()->IsModalWindowOpen(); 100 !Shell::GetInstance()->IsModalWindowOpen();
98 } 101 }
99 102
100 void WindowCycleController::HandleCycleWindow(Direction direction, 103 void WindowCycleController::HandleCycleWindow(Direction direction,
101 bool is_alt_down) { 104 bool is_alt_down) {
102 if (!CanCycle()) 105 if (!CanCycle())
103 return; 106 return;
104 107
105 if (is_alt_down) { 108 if (is_alt_down) {
106 if (!IsCycling()) { 109 if (!IsCycling()) {
110 mru_ignore_ = true;
107 // This is the start of an alt-tab cycle through multiple windows, so 111 // This is the start of an alt-tab cycle through multiple windows, so
108 // listen for the alt key being released to stop cycling. 112 // listen for the alt key being released to stop cycling.
109 StartCycling(); 113 StartCycling();
110 Step(direction); 114 Step(direction);
111 InstallEventFilter(); 115 InstallEventFilter();
112 } else { 116 } else {
113 // We're in the middle of an alt-tab cycle, just step forward. 117 // We're in the middle of an alt-tab cycle, just step forward.
114 Step(direction); 118 Step(direction);
115 } 119 }
116 } else { 120 } else {
117 // This is a simple, single-step window cycle. 121 // This is a simple, single-step window cycle.
118 StartCycling(); 122 StartCycling();
119 Step(direction); 123 Step(direction);
120 StopCycling(); 124 StopCycling();
121 } 125 }
122 } 126 }
123 127
124 void WindowCycleController::AltKeyReleased() { 128 void WindowCycleController::AltKeyReleased() {
125 StopCycling(); 129 StopCycling();
130
131 // Add the currently focused window to the MRU list, and stop ignoring
132 // activations.
133 mru_ignore_ = false;
134 aura::Window* active_window = wm::GetActiveWindow();
135 mru_windows_.remove(active_window);
136 mru_windows_.push_front(active_window);
126 } 137 }
127 138
128 // static 139 // static
129 std::vector<aura::Window*> WindowCycleController::BuildWindowList() { 140 std::vector<aura::Window*> WindowCycleController::BuildWindowList(
141 std::list<aura::Window*>* mru_windows) {
142 const int kContainerIds[] = {
143 internal::kShellWindowId_DefaultContainer,
144 internal::kShellWindowId_AlwaysOnTopContainer
145 };
146
130 WindowCycleList::WindowList windows; 147 WindowCycleList::WindowList windows;
131 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 148 Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
132 149
133 for (Shell::RootWindowList::const_iterator iter = root_windows.begin(); 150 for (Shell::RootWindowList::const_iterator iter = root_windows.begin();
134 iter != root_windows.end(); ++iter) { 151 iter != root_windows.end(); ++iter) {
135 if (*iter == Shell::GetActiveRootWindow()) 152 if (*iter == Shell::GetActiveRootWindow())
136 continue; 153 continue;
137 aura::Window* default_container = Shell::GetContainer( 154 for (size_t i = 0; i < arraysize(kContainerIds); ++i) {
138 *iter, internal::kShellWindowId_DefaultContainer); 155 aura::Window* container = Shell::GetContainer(*iter, kContainerIds[i]);
139 WindowCycleList::WindowList children = default_container->children(); 156 WindowCycleList::WindowList children = container->children();
157 windows.insert(windows.end(), children.begin(), children.end());
158 }
159 }
160
161 for (size_t i = 0; i < arraysize(kContainerIds); ++i) {
162 aura::Window* container =
163 Shell::GetContainer(Shell::GetActiveRootWindow(), kContainerIds[i]);
164
165 WindowCycleList::WindowList children = container->children();
140 windows.insert(windows.end(), children.begin(), children.end()); 166 windows.insert(windows.end(), children.begin(), children.end());
141 } 167 }
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 168
151 // Removes unfocusable windows. 169 // Removes unfocusable windows.
152 WindowCycleList::WindowList::iterator last = 170 WindowCycleList::WindowList::iterator last =
153 std::remove_if( 171 std::remove_if(
154 windows.begin(), 172 windows.begin(),
155 windows.end(), 173 windows.end(),
156 std::not1(std::ptr_fun(ash::wm::CanActivateWindow))); 174 std::not1(std::ptr_fun(ash::wm::CanActivateWindow)));
157 windows.erase(last, windows.end()); 175 windows.erase(last, windows.end());
176
177 // Put the windows in the mru_windows list at the head, if it's available.
178 if (mru_windows) {
179 for (std::list<aura::Window*>::const_reverse_iterator ix =
180 mru_windows->rbegin();
181 ix != mru_windows->rend(); ++ix) {
182 WindowCycleList::WindowList::iterator window =
183 std::find(windows.begin(), windows.end(), *ix);
184 if (window != windows.end()) {
185 windows.erase(window);
186 windows.push_back(*ix);
187 }
188 }
189 }
190
158 // Window cycling expects the topmost window at the front of the list. 191 // Window cycling expects the topmost window at the front of the list.
159 std::reverse(windows.begin(), windows.end()); 192 std::reverse(windows.begin(), windows.end());
193
160 return windows; 194 return windows;
161 } 195 }
162 196
163 ////////////////////////////////////////////////////////////////////////////// 197 //////////////////////////////////////////////////////////////////////////////
164 // WindowCycleController, private: 198 // WindowCycleController, private:
165 199
166 void WindowCycleController::StartCycling() { 200 void WindowCycleController::StartCycling() {
167 windows_.reset(new WindowCycleList(BuildWindowList())); 201 windows_.reset(new WindowCycleList(BuildWindowList(&mru_windows_)));
168 } 202 }
169 203
170 void WindowCycleController::Step(Direction direction) { 204 void WindowCycleController::Step(Direction direction) {
171 DCHECK(windows_.get()); 205 DCHECK(windows_.get());
172 windows_->Step(direction == FORWARD ? WindowCycleList::FORWARD : 206 windows_->Step(direction == FORWARD ? WindowCycleList::FORWARD :
173 WindowCycleList::BACKWARD); 207 WindowCycleList::BACKWARD);
174 } 208 }
175 209
176 void WindowCycleController::StopCycling() { 210 void WindowCycleController::StopCycling() {
177 windows_.reset(); 211 windows_.reset();
178 // Remove our key event filter. 212 // Remove our key event filter.
179 if (event_filter_.get()) { 213 if (event_filter_.get()) {
180 Shell::GetInstance()->RemoveEnvEventFilter(event_filter_.get()); 214 Shell::GetInstance()->RemoveEnvEventFilter(event_filter_.get());
181 event_filter_.reset(); 215 event_filter_.reset();
182 } 216 }
183 } 217 }
184 218
185 void WindowCycleController::InstallEventFilter() { 219 void WindowCycleController::InstallEventFilter() {
186 event_filter_.reset(new WindowCycleEventFilter()); 220 event_filter_.reset(new WindowCycleEventFilter());
187 Shell::GetInstance()->AddEnvEventFilter(event_filter_.get()); 221 Shell::GetInstance()->AddEnvEventFilter(event_filter_.get());
188 } 222 }
189 223
224 void WindowCycleController::OnWindowActivated(aura::Window* active,
225 aura::Window* old_active) {
226 if (active) {
sky 2012/07/19 16:41:15 Only add windows that are children of the containe
Zachary Kuznia 2012/07/23 22:44:33 Done.
227 if (!mru_ignore_) {
228 mru_windows_.remove(active);
229 mru_windows_.push_front(active);
230 }
231 } else {
232 mru_windows_.remove(old_active);
233 }
234 }
235
190 } // namespace ash 236 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698