Index: ash/wm/mru_window_tracker.cc |
diff --git a/ash/wm/window_cycle_controller.cc b/ash/wm/mru_window_tracker.cc |
similarity index 54% |
copy from ash/wm/window_cycle_controller.cc |
copy to ash/wm/mru_window_tracker.cc |
index 89af6c1836f8548ee56c5c4ded9f0eed40dabd9c..06d5bf05eb7d331eda0d8335d765d1f59e773168 100644 |
--- a/ash/wm/window_cycle_controller.cc |
+++ b/ash/wm/mru_window_tracker.cc |
@@ -1,8 +1,8 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "ash/wm/window_cycle_controller.h" |
+#include "ash/wm/mru_window_tracker.h" |
#include <algorithm> |
@@ -21,60 +21,31 @@ namespace ash { |
namespace { |
-// List of containers whose children we will cycle through. |
+// List of containers whose children we will allow switching to. |
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 ui::EventHandler { |
- public: |
- WindowCycleEventFilter(); |
- virtual ~WindowCycleEventFilter(); |
- |
- // Overridden from ui::EventHandler: |
- virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE; |
- private: |
- DISALLOW_COPY_AND_ASSIGN(WindowCycleEventFilter); |
-}; |
- |
-// Watch for all keyboard events by filtering the root window. |
-WindowCycleEventFilter::WindowCycleEventFilter() { |
-} |
- |
-WindowCycleEventFilter::~WindowCycleEventFilter() { |
-} |
- |
-void WindowCycleEventFilter::OnKeyEvent(ui::KeyEvent* event) { |
- // Views uses VKEY_MENU for both left and right Alt keys. |
- if (event->key_code() == ui::VKEY_MENU && |
- event->type() == ui::ET_KEY_RELEASED) { |
- Shell::GetInstance()->window_cycle_controller()->AltKeyReleased(); |
- // Warning: |this| will be deleted from here on. |
- } |
-} |
- |
// Adds all the children of |window| to |windows|. |
void AddAllChildren(aura::Window* window, |
- WindowCycleList::WindowList* windows) { |
- const WindowCycleList::WindowList& children(window->children()); |
+ MruWindowTracker::WindowList* windows) { |
+ const MruWindowTracker::WindowList& children(window->children()); |
windows->insert(windows->end(), children.begin(), children.end()); |
} |
// Adds all the children of all of |window|s children to |windows|. |
void AddWorkspaceChildren(aura::Window* window, |
- WindowCycleList::WindowList* windows) { |
+ MruWindowTracker::WindowList* windows) { |
for (size_t i = 0; i < window->children().size(); ++i) |
AddAllChildren(window->children()[i], windows); |
} |
// Adds the windows that can be cycled through for the specified window id to |
// |windows|. |
-void AddCycleWindows(aura::RootWindow* root, |
+void AddTrackedWindows(aura::RootWindow* root, |
int container_id, |
- WindowCycleList::WindowList* windows) { |
+ MruWindowTracker::WindowList* windows) { |
aura::Window* container = Shell::GetContainer(root, container_id); |
if (container_id == internal::kShellWindowId_DefaultContainer) |
AddWorkspaceChildren(container, windows); |
@@ -82,93 +53,14 @@ void AddCycleWindows(aura::RootWindow* root, |
AddAllChildren(container, windows); |
} |
-} // namespace |
- |
-////////////////////////////////////////////////////////////////////////////// |
-// WindowCycleController, public: |
- |
-WindowCycleController::WindowCycleController( |
- aura::client::ActivationClient* activation_client) |
- : activation_client_(activation_client) { |
- activation_client_->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); |
- } |
- aura::Window* default_container = |
- Shell::GetContainer(*iter, internal::kShellWindowId_DefaultContainer); |
- if (default_container) { |
- for (size_t i = 0; i < default_container->children().size(); ++i) { |
- aura::Window* workspace_window = default_container->children()[i]; |
- DCHECK_EQ(internal::kShellWindowId_WorkspaceContainer, |
- workspace_window->id()); |
- workspace_window->RemoveObserver(this); |
- } |
- } |
- } |
- |
- activation_client_->RemoveObserver(this); |
- StopCycling(); |
-} |
- |
-// static |
-bool WindowCycleController::CanCycle() { |
- // Don't allow window cycling if the screen is locked or a modal dialog is |
- // open. |
- return !Shell::GetInstance()->session_state_delegate()->IsScreenLocked() && |
- !Shell::GetInstance()->IsSystemModalWindowOpen(); |
-} |
- |
-void WindowCycleController::HandleCycleWindow(Direction direction, |
- bool is_alt_down) { |
- if (!CanCycle()) |
- return; |
- |
- if (is_alt_down) { |
- if (!IsCycling()) { |
- // This is the start of an alt-tab cycle through multiple windows, so |
- // listen for the alt key being released to stop cycling. |
- StartCycling(); |
- Step(direction); |
- InstallEventFilter(); |
- } else { |
- // We're in the middle of an alt-tab cycle, just step forward. |
- Step(direction); |
- } |
- } else { |
- // This is a simple, single-step window cycle. |
- StartCycling(); |
- Step(direction); |
- StopCycling(); |
- } |
-} |
- |
-void WindowCycleController::HandleLinearCycleWindow() { |
- if (!CanCycle() || IsCycling()) |
- return; |
- |
- // Use the reversed list of windows to prevent a 2-cycle of the most recent |
- // windows occurring. |
- WindowCycleList cycle_list(BuildWindowList(NULL,true)); |
- cycle_list.Step(WindowCycleList::FORWARD); |
-} |
- |
-void WindowCycleController::AltKeyReleased() { |
- StopCycling(); |
-} |
- |
-// static |
-std::vector<aura::Window*> WindowCycleController::BuildWindowList( |
+// Returns a list of windows ordered by their stacking order. |
+// If |mru_windows| is passed, these windows are moved to the front of the list. |
+// If |top_most_at_end|, the list is returned in descending (bottom-most / least |
+// recently used) order. |
+MruWindowTracker::WindowList BuildWindowListInternal( |
const std::list<aura::Window*>* mru_windows, |
bool top_most_at_end) { |
- WindowCycleList::WindowList windows; |
+ MruWindowTracker::WindowList windows; |
Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
aura::RootWindow* active_root = Shell::GetActiveRootWindow(); |
@@ -177,16 +69,16 @@ std::vector<aura::Window*> WindowCycleController::BuildWindowList( |
if (*iter == active_root) |
continue; |
for (size_t i = 0; i < arraysize(kContainerIds); ++i) |
- AddCycleWindows(*iter, kContainerIds[i], &windows); |
+ AddTrackedWindows(*iter, kContainerIds[i], &windows); |
} |
// Add windows in the active root windows last so that the topmost window |
// in the active root window becomes the front of the list. |
for (size_t i = 0; i < arraysize(kContainerIds); ++i) |
- AddCycleWindows(active_root, kContainerIds[i], &windows); |
+ AddTrackedWindows(active_root, kContainerIds[i], &windows); |
// Removes unfocusable windows. |
- WindowCycleList::WindowList::iterator last = |
+ MruWindowTracker::WindowList::iterator last = |
std::remove_if( |
windows.begin(), |
windows.end(), |
@@ -200,7 +92,7 @@ std::vector<aura::Window*> WindowCycleController::BuildWindowList( |
for (std::list<aura::Window*>::const_reverse_iterator ix = |
mru_windows->rbegin(); |
ix != mru_windows->rend(); ++ix) { |
- WindowCycleList::WindowList::iterator window = |
+ MruWindowTracker::WindowList::iterator window = |
std::find(windows.begin(), windows.end(), *ix); |
if (window != windows.end()) { |
windows.erase(window); |
@@ -216,7 +108,53 @@ std::vector<aura::Window*> WindowCycleController::BuildWindowList( |
return windows; |
} |
-void WindowCycleController::OnRootWindowAdded(aura::RootWindow* root_window) { |
+} // namespace |
+ |
+////////////////////////////////////////////////////////////////////////////// |
+// MruWindowTracker, public: |
+ |
+MruWindowTracker::MruWindowTracker( |
+ aura::client::ActivationClient* activation_client) |
+ : activation_client_(activation_client), |
+ ignore_window_activations_(false) { |
+ activation_client_->AddObserver(this); |
+} |
+ |
+MruWindowTracker::~MruWindowTracker() { |
+ 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); |
+ } |
+ aura::Window* default_container = |
+ Shell::GetContainer(*iter, internal::kShellWindowId_DefaultContainer); |
+ if (default_container) { |
+ for (size_t i = 0; i < default_container->children().size(); ++i) { |
+ aura::Window* workspace_window = default_container->children()[i]; |
+ DCHECK_EQ(internal::kShellWindowId_WorkspaceContainer, |
+ workspace_window->id()); |
+ workspace_window->RemoveObserver(this); |
+ } |
+ } |
+ } |
+ |
+ activation_client_->RemoveObserver(this); |
+} |
+ |
+// static |
+MruWindowTracker::WindowList MruWindowTracker::BuildWindowList( |
+ bool top_most_at_end) { |
+ return BuildWindowListInternal(NULL, top_most_at_end); |
+} |
+ |
+MruWindowTracker::WindowList MruWindowTracker::BuildMruWindowList() { |
+ return BuildWindowListInternal(&mru_windows_, false); |
+} |
+ |
+void MruWindowTracker::OnRootWindowAdded(aura::RootWindow* root_window) { |
for (size_t i = 0; i < arraysize(kContainerIds); ++i) { |
aura::Window* container = |
Shell::GetContainer(root_window, kContainerIds[i]); |
@@ -234,35 +172,23 @@ void WindowCycleController::OnRootWindowAdded(aura::RootWindow* root_window) { |
} |
} |
-////////////////////////////////////////////////////////////////////////////// |
-// WindowCycleController, private: |
- |
-void WindowCycleController::StartCycling() { |
- windows_.reset(new WindowCycleList(BuildWindowList(&mru_windows_, false))); |
-} |
- |
-void WindowCycleController::Step(Direction direction) { |
- DCHECK(windows_.get()); |
- windows_->Step(direction == FORWARD ? WindowCycleList::FORWARD : |
- WindowCycleList::BACKWARD); |
-} |
+void MruWindowTracker::SetIgnoreActivations(bool ignore) { |
+ ignore_window_activations_ = ignore; |
-void WindowCycleController::StopCycling() { |
- windows_.reset(); |
- // Remove our key event filter. |
- if (event_handler_) { |
- Shell::GetInstance()->RemovePreTargetHandler(event_handler_.get()); |
- event_handler_.reset(); |
+ // If no longer ignoring window activations, move currently active window |
+ // to front. |
+ if (!ignore) { |
+ aura::Window* active_window = wm::GetActiveWindow(); |
+ mru_windows_.remove(active_window); |
+ mru_windows_.push_front(active_window); |
} |
- |
- // 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); |
} |
+////////////////////////////////////////////////////////////////////////////// |
+// MruWindowTracker, private: |
+ |
// static |
-bool WindowCycleController::IsTrackedContainer(aura::Window* window) { |
+bool MruWindowTracker::IsTrackedContainer(aura::Window* window) { |
if (!window) |
return false; |
for (size_t i = 0; i < arraysize(kContainerIds); ++i) { |
@@ -273,32 +199,27 @@ bool WindowCycleController::IsTrackedContainer(aura::Window* window) { |
return window->id() == internal::kShellWindowId_WorkspaceContainer; |
} |
-void WindowCycleController::InstallEventFilter() { |
- event_handler_.reset(new WindowCycleEventFilter()); |
- Shell::GetInstance()->AddPreTargetHandler(event_handler_.get()); |
-} |
- |
-void WindowCycleController::OnWindowActivated(aura::Window* gained_active, |
- aura::Window* lost_active) { |
- if (gained_active && !IsCycling() && |
+void MruWindowTracker::OnWindowActivated(aura::Window* gained_active, |
+ aura::Window* lost_active) { |
+ if (gained_active && !ignore_window_activations_ && |
IsTrackedContainer(gained_active->parent())) { |
mru_windows_.remove(gained_active); |
mru_windows_.push_front(gained_active); |
} |
} |
-void WindowCycleController::OnWindowAdded(aura::Window* window) { |
+void MruWindowTracker::OnWindowAdded(aura::Window* window) { |
if (window->id() == internal::kShellWindowId_WorkspaceContainer) |
window->AddObserver(this); |
} |
-void WindowCycleController::OnWillRemoveWindow(aura::Window* window) { |
+void MruWindowTracker::OnWillRemoveWindow(aura::Window* window) { |
mru_windows_.remove(window); |
if (window->id() == internal::kShellWindowId_WorkspaceContainer) |
window->RemoveObserver(this); |
} |
-void WindowCycleController::OnWindowDestroying(aura::Window* window) { |
+void MruWindowTracker::OnWindowDestroying(aura::Window* window) { |
window->RemoveObserver(this); |
} |