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

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: Rebase 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..81a72430eaa4f52763990cc71d9f36cc7d2ed42f 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 {
@@ -82,10 +89,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();
sky 2012/07/24 03:53:31 Doesn't this need to remove observers from all the
Zachary Kuznia 2012/07/30 07:49:48 No. The containers get the OnWindowDestroying not
}
@@ -104,6 +113,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();
sky 2012/07/24 03:53:31 Wouldn't it make more sense to set mru_ignore_ in
Zachary Kuznia 2012/07/30 07:49:48 Done.
@@ -123,10 +133,19 @@ 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) {
sky 2012/07/24 03:53:31 const std::list&
Zachary Kuznia 2012/07/30 07:49:48 Changed to const. It needs to be a pointer, thoug
+
sky 2012/07/24 03:53:31 remove newline
Zachary Kuznia 2012/07/30 07:49:48 Done.
WindowCycleList::WindowList windows;
Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
@@ -134,19 +153,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,16 +175,40 @@ 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.
sky 2012/07/24 03:53:31 Document why this uses a reverse iterator.
Zachary Kuznia 2012/07/30 07:49:48 Done.
+ 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;
}
+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) {
@@ -187,4 +231,35 @@ void WindowCycleController::InstallEventFilter() {
Shell::GetInstance()->AddEnvEventFilter(event_filter_.get());
}
+void WindowCycleController::OnWindowActivated(aura::Window* active,
+ aura::Window* old_active) {
+ if (active) {
+ if (!active->parent())
sky 2012/07/24 03:53:31 This code would be easier to read if you made a fu
Zachary Kuznia 2012/07/30 07:49:48 Done.
+ return;
+
+ bool ignore = true;
+ for (size_t i = 0; i < arraysize(kContainerIds); ++i) {
+ if (active->parent()->id() == kContainerIds[i]) {
+ ignore = false;
+ break;
+ }
+ }
+ if (ignore)
+ return;
+
+ if (!mru_ignore_) {
sky 2012/07/24 03:53:31 Move this check early on.
Zachary Kuznia 2012/07/30 07:49:48 Done.
+ 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