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

Unified 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: Fix clang 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 side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698