Index: ash/wm/window_cycle_controller.cc |
diff --git a/ash/wm/window_cycle_controller.cc b/ash/wm/window_cycle_controller.cc |
index f48ee76afa8f92f3d4aca34ba119b474c003141b..a683659a33919ecc8d81650fa7f812b58bdb73ac 100644 |
--- a/ash/wm/window_cycle_controller.cc |
+++ b/ash/wm/window_cycle_controller.cc |
@@ -9,6 +9,7 @@ |
#include "ash/shell.h" |
#include "ash/shell_delegate.h" |
#include "ash/shell_window_ids.h" |
+#include "ash/wm/activation_controller.h" |
#include "ash/wm/window_cycle_list.h" |
#include "ash/wm/window_util.h" |
#include "ui/aura/event.h" |
@@ -82,10 +83,12 @@ ui::GestureStatus WindowCycleEventFilter::PreHandleGestureEvent( |
////////////////////////////////////////////////////////////////////////////// |
// WindowCycleController, public: |
-WindowCycleController::WindowCycleController() { |
+WindowCycleController::WindowCycleController() : mru_ignore_(false) { |
+ Shell::GetInstance()->activation_controller()->AddObserver(this); |
} |
WindowCycleController::~WindowCycleController() { |
+ Shell::GetInstance()->activation_controller()->RemoveObserver(this); |
StopCycling(); |
} |
@@ -104,6 +107,7 @@ void WindowCycleController::HandleCycleWindow(Direction direction, |
if (is_alt_down) { |
if (!IsCycling()) { |
+ mru_ignore_ = true; |
// This is the start of an alt-tab cycle through multiple windows, so |
// listen for the alt key being released to stop cycling. |
StartCycling(); |
@@ -123,10 +127,23 @@ void WindowCycleController::HandleCycleWindow(Direction direction, |
void WindowCycleController::AltKeyReleased() { |
StopCycling(); |
+ |
+ // Add the currently focused window to the MRU list, and stop ignoring |
+ // activations. |
+ mru_ignore_ = false; |
+ aura::Window* active_window = wm::GetActiveWindow(); |
+ mru_windows_.remove(active_window); |
+ mru_windows_.push_front(active_window); |
} |
// static |
-std::vector<aura::Window*> WindowCycleController::BuildWindowList() { |
+std::vector<aura::Window*> WindowCycleController::BuildWindowList( |
+ std::list<aura::Window*>* mru_windows) { |
+ const int kContainerIds[] = { |
+ internal::kShellWindowId_DefaultContainer, |
+ internal::kShellWindowId_AlwaysOnTopContainer |
+ }; |
+ |
WindowCycleList::WindowList windows; |
Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
@@ -134,19 +151,20 @@ std::vector<aura::Window*> WindowCycleController::BuildWindowList() { |
iter != root_windows.end(); ++iter) { |
if (*iter == Shell::GetActiveRootWindow()) |
continue; |
- aura::Window* default_container = Shell::GetContainer( |
- *iter, internal::kShellWindowId_DefaultContainer); |
- WindowCycleList::WindowList children = default_container->children(); |
- windows.insert(windows.end(), children.begin(), children.end()); |
+ for (size_t i = 0; i < arraysize(kContainerIds); ++i) { |
+ aura::Window* container = Shell::GetContainer(*iter, kContainerIds[i]); |
+ WindowCycleList::WindowList children = container->children(); |
+ windows.insert(windows.end(), children.begin(), children.end()); |
+ } |
} |
- // Add windows in the active root windows last so that the topmost window |
- // in the active root window becomes the front of the list. |
- aura::Window* default_container = Shell::GetContainer( |
- Shell::GetActiveRootWindow(), |
- internal::kShellWindowId_DefaultContainer); |
- WindowCycleList::WindowList children = default_container->children(); |
- windows.insert(windows.end(), children.begin(), children.end()); |
+ for (size_t i = 0; i < arraysize(kContainerIds); ++i) { |
+ aura::Window* container = |
+ Shell::GetContainer(Shell::GetActiveRootWindow(), kContainerIds[i]); |
+ |
+ WindowCycleList::WindowList children = container->children(); |
+ windows.insert(windows.end(), children.begin(), children.end()); |
+ } |
// Removes unfocusable windows. |
WindowCycleList::WindowList::iterator last = |
@@ -155,8 +173,24 @@ std::vector<aura::Window*> WindowCycleController::BuildWindowList() { |
windows.end(), |
std::not1(std::ptr_fun(ash::wm::CanActivateWindow))); |
windows.erase(last, windows.end()); |
+ |
+ // Put the windows in the mru_windows list at the head, if it's available. |
+ if (mru_windows) { |
+ for (std::list<aura::Window*>::const_reverse_iterator ix = |
+ mru_windows->rbegin(); |
+ ix != mru_windows->rend(); ++ix) { |
+ WindowCycleList::WindowList::iterator window = |
+ std::find(windows.begin(), windows.end(), *ix); |
+ if (window != windows.end()) { |
+ windows.erase(window); |
+ windows.push_back(*ix); |
+ } |
+ } |
+ } |
+ |
// Window cycling expects the topmost window at the front of the list. |
std::reverse(windows.begin(), windows.end()); |
+ |
return windows; |
} |
@@ -164,7 +198,7 @@ std::vector<aura::Window*> WindowCycleController::BuildWindowList() { |
// WindowCycleController, private: |
void WindowCycleController::StartCycling() { |
- windows_.reset(new WindowCycleList(BuildWindowList())); |
+ windows_.reset(new WindowCycleList(BuildWindowList(&mru_windows_))); |
} |
void WindowCycleController::Step(Direction direction) { |
@@ -187,4 +221,16 @@ void WindowCycleController::InstallEventFilter() { |
Shell::GetInstance()->AddEnvEventFilter(event_filter_.get()); |
} |
+void WindowCycleController::OnWindowActivated(aura::Window* active, |
+ aura::Window* old_active) { |
+ 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.
|
+ if (!mru_ignore_) { |
+ mru_windows_.remove(active); |
+ mru_windows_.push_front(active); |
+ } |
+ } else { |
+ mru_windows_.remove(old_active); |
+ } |
+} |
+ |
} // namespace ash |