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..ff99800adf30e32dd2d5a4e138558f6303f57583 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" |
@@ -19,6 +20,12 @@ namespace ash { |
namespace { |
+// List of containers whose children we will cycle through. |
+const int kContainerIds[] = { |
+ internal::kShellWindowId_DefaultContainer, |
+ internal::kShellWindowId_AlwaysOnTopContainer |
+}; |
+ |
// Filter to watch for the termination of a keyboard gesture to cycle through |
// multiple windows. |
class WindowCycleEventFilter : public aura::EventFilter { |
@@ -83,9 +90,21 @@ ui::GestureStatus WindowCycleEventFilter::PreHandleGestureEvent( |
// WindowCycleController, public: |
WindowCycleController::WindowCycleController() { |
+ Shell::GetInstance()->activation_controller()->AddObserver(this); |
} |
WindowCycleController::~WindowCycleController() { |
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
+ for (Shell::RootWindowList::const_iterator iter = root_windows.begin(); |
+ iter != root_windows.end(); ++iter) { |
+ for (size_t i = 0; i < arraysize(kContainerIds); ++i) { |
+ aura::Window* container = Shell::GetContainer(*iter, kContainerIds[i]); |
+ if (container) |
+ container->RemoveObserver(this); |
+ } |
+ } |
+ |
+ Shell::GetInstance()->activation_controller()->RemoveObserver(this); |
StopCycling(); |
} |
@@ -126,7 +145,8 @@ void WindowCycleController::AltKeyReleased() { |
} |
// static |
-std::vector<aura::Window*> WindowCycleController::BuildWindowList() { |
+std::vector<aura::Window*> WindowCycleController::BuildWindowList( |
+ const std::list<aura::Window*>* mru_windows) { |
WindowCycleList::WindowList windows; |
Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
@@ -134,19 +154,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 |
sky
2012/08/02 21:18:00
Move this comment to 164ish new.
Zachary Kuznia
2012/08/06 05:56:03
Done.
|
- // 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,16 +176,42 @@ 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) { |
+ // Iterate through the list backwards, so that we can move each window to |
+ // the front of the windows list as we find them. |
+ 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; |
} |
+void WindowCycleController::OnRootWindowAdded(aura::RootWindow* root_window) { |
+ for (size_t i = 0; i < arraysize(kContainerIds); ++i) { |
+ aura::Window* container = |
+ Shell::GetContainer(root_window, kContainerIds[i]); |
+ container->AddObserver(this); |
+ } |
+} |
+ |
////////////////////////////////////////////////////////////////////////////// |
// WindowCycleController, private: |
void WindowCycleController::StartCycling() { |
- windows_.reset(new WindowCycleList(BuildWindowList())); |
+ windows_.reset(new WindowCycleList(BuildWindowList(&mru_windows_))); |
} |
void WindowCycleController::Step(Direction direction) { |
@@ -180,6 +227,23 @@ void WindowCycleController::StopCycling() { |
Shell::GetInstance()->RemoveEnvEventFilter(event_filter_.get()); |
event_filter_.reset(); |
} |
+ |
+ // Add the currently focused window to the MRU list |
+ aura::Window* active_window = wm::GetActiveWindow(); |
+ mru_windows_.remove(active_window); |
+ mru_windows_.push_front(active_window); |
+} |
+ |
+// static |
+bool WindowCycleController::IsTrackedContainer(aura::Window* window) { |
+ if (!window) |
+ return false; |
+ for (size_t i = 0; i < arraysize(kContainerIds); ++i) { |
+ if (window->id() == kContainerIds[i]) { |
+ return true; |
+ } |
+ } |
+ return false; |
} |
void WindowCycleController::InstallEventFilter() { |
@@ -187,4 +251,20 @@ void WindowCycleController::InstallEventFilter() { |
Shell::GetInstance()->AddEnvEventFilter(event_filter_.get()); |
} |
+void WindowCycleController::OnWindowActivated(aura::Window* active, |
+ aura::Window* old_active) { |
+ if (active && !IsCycling() && IsTrackedContainer(active->parent())) { |
+ mru_windows_.remove(active); |
+ mru_windows_.push_front(active); |
+ } |
+} |
+ |
+void WindowCycleController::OnWillRemoveWindow(aura::Window* window) { |
+ mru_windows_.remove(window); |
+} |
+ |
+void WindowCycleController::OnWindowDestroying(aura::Window* window) { |
+ window->RemoveObserver(this); |
+} |
+ |
} // namespace ash |