summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-11 03:56:09 +0000
committerdbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-11 03:56:09 +0000
commit456b003a7a0d4c7621b20c92c3ee28e87ec57ee8 (patch)
treed12f23ac14b9ce9e9f326d84c10f7bbf4ba5764c
parentb0b5519b6b692908f11584db8820294bb3663934 (diff)
downloadchromium_src-456b003a7a0d4c7621b20c92c3ee28e87ec57ee8.zip
chromium_src-456b003a7a0d4c7621b20c92c3ee28e87ec57ee8.tar.gz
chromium_src-456b003a7a0d4c7621b20c92c3ee28e87ec57ee8.tar.bz2
Revert 216874 - Use overview mode for alt-tab cycling.
BUG=263481,264289 TEST=WindowSelectorTest.BasicCycle TEST=Enable --ash-enable-overview-mode and use alt-tab to cycle through MRU windows. Cycling is done in overview mode on active display. Review URL: https://chromiumcodereview.appspot.com/22715005 TBR=flackr@chromium.org Review URL: https://chromiumcodereview.appspot.com/22778002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216890 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/accelerators/accelerator_controller.cc14
-rw-r--r--ash/wm/window_selector.cc494
-rw-r--r--ash/wm/window_selector.h83
-rw-r--r--ash/wm/window_selector_controller.cc63
-rw-r--r--ash/wm/window_selector_controller.h15
-rw-r--r--ash/wm/window_selector_unittest.cc52
6 files changed, 107 insertions, 614 deletions
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index 3d669bb..2a75415 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -94,12 +94,6 @@ bool HandleCycleWindowMRU(WindowCycleController::Direction direction,
return true;
}
-bool HandleCycleWindowOverviewMRU(WindowSelector::Direction direction) {
- Shell::GetInstance()->
- window_selector_controller()->HandleCycleWindow(direction);
- return true;
-}
-
void HandleCycleWindowLinear(CycleDirection direction) {
Shell::GetInstance()->
window_cycle_controller()->HandleLinearCycleWindow();
@@ -524,19 +518,11 @@ bool AcceleratorController::PerformAction(int action,
case CYCLE_BACKWARD_MRU:
if (key_code == ui::VKEY_TAB)
shell->delegate()->RecordUserMetricsAction(UMA_ACCEL_PREVWINDOW_TAB);
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAshEnableOverviewMode)) {
- return HandleCycleWindowOverviewMRU(WindowSelector::BACKWARD);
- }
return HandleCycleWindowMRU(WindowCycleController::BACKWARD,
accelerator.IsAltDown());
case CYCLE_FORWARD_MRU:
if (key_code == ui::VKEY_TAB)
shell->delegate()->RecordUserMetricsAction(UMA_ACCEL_NEXTWINDOW_TAB);
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAshEnableOverviewMode)) {
- return HandleCycleWindowOverviewMRU(WindowSelector::FORWARD);
- }
return HandleCycleWindowMRU(WindowCycleController::FORWARD,
accelerator.IsAltDown());
case CYCLE_BACKWARD_LINEAR:
diff --git a/ash/wm/window_selector.cc b/ash/wm/window_selector.cc
index 9ba9bfe..f9de84c 100644
--- a/ash/wm/window_selector.cc
+++ b/ash/wm/window_selector.cc
@@ -12,273 +12,29 @@
#include "ash/wm/window_selector_delegate.h"
#include "ash/wm/window_util.h"
#include "base/memory/scoped_ptr.h"
-#include "third_party/skia/include/core/SkColor.h"
#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/base/events/event.h"
-#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
-#include "ui/gfx/display.h"
#include "ui/gfx/interpolated_transform.h"
#include "ui/gfx/transform_util.h"
-#include "ui/views/corewm/shadow_types.h"
#include "ui/views/corewm/window_animations.h"
-#include "ui/views/corewm/window_util.h"
-#include "ui/views/widget/widget.h"
namespace ash {
namespace {
const float kCardAspectRatio = 4.0f / 3.0f;
-const int kWindowMargin = 30;
+const int kWindowMargin = 20;
const int kMinCardsMajor = 3;
const int kOverviewTransitionMilliseconds = 100;
-const SkColor kWindowSelectorSelectionColor = SK_ColorBLACK;
-const float kWindowSelectorSelectionOpacity = 0.5f;
-const int kWindowSelectorSelectionPadding = 15;
-// Creates a copy of |window| with |recreated_layer| in the |target_root|.
-views::Widget* CreateCopyOfWindow(aura::RootWindow* target_root,
- aura::Window* src_window,
- ui::Layer* recreated_layer) {
- views::Widget* widget = new views::Widget;
- views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
- params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
- params.parent = src_window->parent();
- params.can_activate = false;
- params.keep_on_top = true;
- widget->set_focus_on_creation(false);
- widget->Init(params);
- widget->SetVisibilityChangedAnimationsEnabled(false);
- std::string name = src_window->name() + " (Copy)";
- widget->GetNativeWindow()->SetName(name);
- views::corewm::SetShadowType(widget->GetNativeWindow(),
- views::corewm::SHADOW_TYPE_RECTANGULAR);
-
- // Set the bounds in the target root window.
- gfx::Display target_display =
- Shell::GetScreen()->GetDisplayNearestWindow(target_root);
- aura::client::ScreenPositionClient* screen_position_client =
- aura::client::GetScreenPositionClient(src_window->GetRootWindow());
- if (screen_position_client && target_display.is_valid()) {
- screen_position_client->SetBounds(widget->GetNativeWindow(),
- src_window->GetBoundsInScreen(), target_display);
- } else {
- widget->SetBounds(src_window->GetBoundsInScreen());
- }
- widget->StackAbove(src_window);
-
- // Move the |recreated_layer| to the newly created window.
- recreated_layer->set_delegate(src_window->layer()->delegate());
- gfx::Rect layer_bounds = recreated_layer->bounds();
- layer_bounds.set_origin(gfx::Point(0, 0));
- recreated_layer->SetBounds(layer_bounds);
- recreated_layer->SetVisible(false);
- recreated_layer->parent()->Remove(recreated_layer);
-
- aura::Window* window = widget->GetNativeWindow();
- recreated_layer->SetVisible(true);
- window->layer()->Add(recreated_layer);
- window->layer()->StackAtTop(recreated_layer);
- window->layer()->SetOpacity(1);
- window->Show();
- return widget;
-}
-
-// An observer which closes the widget and deletes the layer after an
-// animation finishes.
-class CleanupWidgetAfterAnimationObserver : public ui::LayerAnimationObserver {
- public:
- CleanupWidgetAfterAnimationObserver(views::Widget* widget, ui::Layer* layer);
-
- virtual void OnLayerAnimationEnded(
- ui::LayerAnimationSequence* sequence) OVERRIDE;
- virtual void OnLayerAnimationAborted(
- ui::LayerAnimationSequence* sequence) OVERRIDE;
- virtual void OnLayerAnimationScheduled(
- ui::LayerAnimationSequence* sequence) OVERRIDE;
-
- protected:
- virtual ~CleanupWidgetAfterAnimationObserver();
-
- private:
- views::Widget* widget_;
- ui::Layer* layer_;
-
- DISALLOW_COPY_AND_ASSIGN(CleanupWidgetAfterAnimationObserver);
-};
-
-CleanupWidgetAfterAnimationObserver::CleanupWidgetAfterAnimationObserver(
- views::Widget* widget,
- ui::Layer* layer)
- : widget_(widget),
- layer_(layer) {
- widget_->GetNativeWindow()->layer()->GetAnimator()->AddObserver(this);
-}
-
-void CleanupWidgetAfterAnimationObserver::OnLayerAnimationEnded(
- ui::LayerAnimationSequence* sequence) {
- delete this;
-}
-
-void CleanupWidgetAfterAnimationObserver::OnLayerAnimationAborted(
- ui::LayerAnimationSequence* sequence) {
- delete this;
-}
-
-void CleanupWidgetAfterAnimationObserver::OnLayerAnimationScheduled(
- ui::LayerAnimationSequence* sequence) {
-}
-
-CleanupWidgetAfterAnimationObserver::~CleanupWidgetAfterAnimationObserver() {
- widget_->GetNativeWindow()->layer()->GetAnimator()->RemoveObserver(this);
- widget_->Close();
- widget_ = NULL;
- if (layer_) {
- views::corewm::DeepDeleteLayers(layer_);
- layer_ = NULL;
- }
-}
-
-// The animation settings used for window selector animations.
-class WindowSelectorAnimationSettings
- : public ui::ScopedLayerAnimationSettings {
- public:
- WindowSelectorAnimationSettings(aura::Window* window) :
- ui::ScopedLayerAnimationSettings(window->layer()->GetAnimator()) {
- SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- SetTransitionDuration(
- base::TimeDelta::FromMilliseconds(kOverviewTransitionMilliseconds));
- }
-
- virtual ~WindowSelectorAnimationSettings() {
- }
-};
-
-} // namespace
-
-// TODO(flackr): Split up into separate file under subdirectory in ash/wm.
-class WindowSelectorWindow {
- public:
- explicit WindowSelectorWindow(aura::Window* window);
- virtual ~WindowSelectorWindow();
-
- aura::Window* window() { return window_; }
- const aura::Window* window() const { return window_; }
-
- // Returns true if this window selector window contains the |target|. This is
- // used to determine if an event targetted this window.
- bool Contains(const aura::Window* target) const;
-
- // Restores this window on exit rather than returning it to a minimized state
- // if it was minimized on entering overview mode.
- void RestoreWindowOnExit();
-
- // Informs the WindowSelectorWindow that the window being watched was
- // destroyed. This resets the internal window pointer to avoid calling
- // anything on the window at destruction time.
- void OnWindowDestroyed();
-
- // Applies a transform to the window to fit within |target_bounds| while
- // maintaining its aspect ratio.
- void TransformToFitBounds(aura::RootWindow* root_window,
- const gfx::Rect& target_bounds);
-
- gfx::Rect bounds() { return fit_bounds_; }
-
- private:
- // A weak pointer to the real window in the overview.
- aura::Window* window_;
-
- // A copy of the window used to transition the window to another root.
- views::Widget* window_copy_;
-
- // A weak pointer to a deep copy of the window's layers.
- ui::Layer* layer_;
-
- // If true, the window was minimized and should be restored if the window
- // was not selected.
- bool minimized_;
-
- // The original transform of the window before entering overview mode.
- gfx::Transform original_transform_;
-
- // The bounds this window is fit to.
- gfx::Rect fit_bounds_;
-
- DISALLOW_COPY_AND_ASSIGN(WindowSelectorWindow);
-};
-
-WindowSelectorWindow::WindowSelectorWindow(aura::Window* window)
- : window_(window),
- window_copy_(NULL),
- layer_(NULL),
- minimized_(window->GetProperty(aura::client::kShowStateKey) ==
- ui::SHOW_STATE_MINIMIZED),
- original_transform_(window->layer()->transform()) {
- if (minimized_)
- window_->Show();
-}
-
-WindowSelectorWindow::~WindowSelectorWindow() {
- if (window_) {
- WindowSelectorAnimationSettings animation_settings(window_);
- gfx::Transform transform;
- window_->SetTransform(original_transform_);
- if (minimized_) {
- // Setting opacity 0 and visible false ensures that the property change
- // to SHOW_STATE_MINIMIZED will not animate the window from its original
- // bounds to the minimized position.
- window_->layer()->SetOpacity(0);
- window_->layer()->SetVisible(false);
- window_->SetProperty(aura::client::kShowStateKey,
- ui::SHOW_STATE_MINIMIZED);
- }
- }
- // If a copy of the window was created, clean it up.
- if (window_copy_) {
- if (window_) {
- // If the initial window wasn't destroyed, the copy needs to be animated
- // out. CleanupWidgetAfterAnimationObserver will destroy the widget and
- // layer after the animation is complete.
- new CleanupWidgetAfterAnimationObserver(window_copy_, layer_);
- WindowSelectorAnimationSettings animation_settings(
- window_copy_->GetNativeWindow());
- window_copy_->GetNativeWindow()->SetTransform(original_transform_);
- } else {
- window_copy_->Close();
- if (layer_)
- views::corewm::DeepDeleteLayers(layer_);
- }
- window_copy_ = NULL;
- layer_ = NULL;
- }
-}
-
-bool WindowSelectorWindow::Contains(const aura::Window* window) const {
- if (window_copy_ && window_copy_->GetNativeWindow()->Contains(window))
- return true;
- return window_->Contains(window);
-}
-
-void WindowSelectorWindow::RestoreWindowOnExit() {
- minimized_ = false;
- original_transform_ = gfx::Transform();
-}
-
-void WindowSelectorWindow::OnWindowDestroyed() {
- window_ = NULL;
-}
-
-void WindowSelectorWindow::TransformToFitBounds(
- aura::RootWindow* root_window,
- const gfx::Rect& target_bounds) {
- fit_bounds_ = target_bounds;
- const gfx::Rect bounds = window_->GetBoundsInScreen();
+// Applies a transform to |window| to fit within |target_bounds| while
+// maintaining its aspect ratio.
+void TransformWindowToFitBounds(aura::Window* window,
+ const gfx::Rect& target_bounds) {
+ const gfx::Rect bounds = window->bounds();
float scale = std::min(1.0f,
std::min(static_cast<float>(target_bounds.width()) / bounds.width(),
static_cast<float>(target_bounds.height()) / bounds.height()));
@@ -289,186 +45,137 @@ void WindowSelectorWindow::TransformToFitBounds(
transform.Translate(target_bounds.x() - bounds.x() + offset.x(),
target_bounds.y() - bounds.y() + offset.y());
transform.Scale(scale, scale);
- if (root_window != window_->GetRootWindow()) {
- if (!window_copy_) {
- DCHECK(!layer_);
- layer_ = views::corewm::RecreateWindowLayers(window_, true);
- window_copy_ = CreateCopyOfWindow(root_window, window_, layer_);
- }
- WindowSelectorAnimationSettings animation_settings(
- window_copy_->GetNativeWindow());
- window_copy_->GetNativeWindow()->SetTransform(transform);
- }
- WindowSelectorAnimationSettings animation_settings(window_);
- window_->SetTransform(transform);
+ // TODO(flackr): The window bounds or transform could change during overview
+ // mode. WindowSelector should create a copy of the window so that the
+ // displayed windows are not affected by changes happening in the background.
+ // This will be necessary for alt-tab cycling as well, as some windows will
+ // be coming from other displays: http://crbug.com/263481.
+ window->SetTransform(transform);
}
-// A comparator for locating a given target window.
-struct WindowSelectorWindowComparator
- : public std::unary_function<WindowSelectorWindow*, bool> {
- explicit WindowSelectorWindowComparator(const aura::Window* target_window)
- : target(target_window) {
- }
-
- bool operator()(const WindowSelectorWindow* window) const {
- return target == window->window();
- }
-
- const aura::Window* target;
-};
+} // namespace
WindowSelector::WindowSelector(const WindowList& windows,
- WindowSelector::Mode mode,
WindowSelectorDelegate* delegate)
- : mode_(mode),
- delegate_(delegate),
- selected_window_(0),
- selection_root_(NULL) {
+ : delegate_(delegate) {
DCHECK(delegate_);
for (size_t i = 0; i < windows.size(); ++i) {
windows[i]->AddObserver(this);
- windows_.push_back(new WindowSelectorWindow(windows[i]));
+ WindowDetails details;
+ details.window = windows[i];
+ details.minimized = windows[i]->GetProperty(aura::client::kShowStateKey) ==
+ ui::SHOW_STATE_MINIMIZED;
+ details.original_transform = windows[i]->layer()->transform();
+ if (details.minimized) {
+ windows[i]->Show();
+ }
+ windows_.push_back(details);
}
- if (mode == WindowSelector::CYCLE)
- selection_root_ = ash::Shell::GetActiveRootWindow();
PositionWindows();
ash::Shell::GetInstance()->AddPreTargetHandler(this);
}
WindowSelector::~WindowSelector() {
for (size_t i = 0; i < windows_.size(); i++) {
- windows_[i]->window()->RemoveObserver(this);
+ ui::ScopedLayerAnimationSettings animation_settings(
+ windows_[i].window->layer()->GetAnimator());
+ animation_settings.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ animation_settings.SetTransitionDuration(
+ base::TimeDelta::FromMilliseconds(kOverviewTransitionMilliseconds));
+ windows_[i].window->RemoveObserver(this);
+ gfx::Transform transform;
+ windows_[i].window->SetTransform(windows_[i].original_transform);
+ if (windows_[i].minimized) {
+ // Setting opacity 0 and visible false ensures that the property change
+ // to SHOW_STATE_MINIMIZED will not animate the window from its original
+ // bounds to the minimized position.
+ windows_[i].window->layer()->SetOpacity(0);
+ windows_[i].window->layer()->SetVisible(false);
+ windows_[i].window->SetProperty(aura::client::kShowStateKey,
+ ui::SHOW_STATE_MINIMIZED);
+ }
}
ash::Shell::GetInstance()->RemovePreTargetHandler(this);
}
-void WindowSelector::Step(WindowSelector::Direction direction) {
- DCHECK(windows_.size() > 0);
- if (!selection_widget_)
- InitializeSelectionWidget();
- selected_window_ = (selected_window_ + windows_.size() +
- (direction == WindowSelector::FORWARD ? 1 : -1)) % windows_.size();
- UpdateSelectionLocation(true);
-}
-
-void WindowSelector::SelectWindow() {
- delegate_->OnWindowSelected(windows_[selected_window_]->window());
-}
-
void WindowSelector::OnEvent(ui::Event* event) {
- ui::EventHandler::OnEvent(event);
-
- // If the event is targetted at any of the windows in the overview, then
- // prevent it from propagating.
- aura::Window* target = static_cast<aura::Window*>(event->target());
- for (size_t i = 0; i < windows_.size(); ++i) {
- if (windows_[i]->Contains(target)) {
- event->StopPropagation();
- break;
- }
- }
+ // TODO(flackr): This will prevent anything else from working while overview
+ // mode is active. This should only stop events from being sent to the windows
+ // in the overview but still allow interaction with the launcher / tray and
+ // hotkeys http://crbug.com/264289.
+ EventHandler::OnEvent(event);
+ event->StopPropagation();
}
void WindowSelector::OnMouseEvent(ui::MouseEvent* event) {
if (event->type() != ui::ET_MOUSE_RELEASED)
return;
- WindowSelectorWindow* target = GetEventTarget(event);
- if (!target)
+ aura::Window* target = static_cast<aura::Window*>(event->target());
+ if (!target->HitTest(event->location()))
return;
- HandleSelectionEvent(target);
+ HandleSelectionEvent(event);
}
void WindowSelector::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() != ui::ET_GESTURE_TAP)
return;
- WindowSelectorWindow* target = GetEventTarget(event);
- if (!target)
- return;
-
- HandleSelectionEvent(target);
+ HandleSelectionEvent(event);
}
void WindowSelector::OnWindowDestroyed(aura::Window* window) {
- ScopedVector<WindowSelectorWindow>::iterator iter =
- std::find_if(windows_.begin(), windows_.end(),
- WindowSelectorWindowComparator(window));
+ std::vector<WindowDetails>::iterator iter =
+ std::find(windows_.begin(), windows_.end(), window);
DCHECK(iter != windows_.end());
- size_t deleted_index = iter - windows_.begin();
- (*iter)->OnWindowDestroyed();
windows_.erase(iter);
if (windows_.empty()) {
delegate_->OnSelectionCanceled();
return;
}
- if (selected_window_ >= deleted_index) {
- if (selected_window_ > deleted_index)
- selected_window_--;
- selected_window_ = selected_window_ % windows_.size();
- UpdateSelectionLocation(true);
- }
PositionWindows();
}
-WindowSelectorWindow* WindowSelector::GetEventTarget(ui::LocatedEvent* event) {
+void WindowSelector::HandleSelectionEvent(ui::Event* event) {
aura::Window* target = static_cast<aura::Window*>(event->target());
- // If the target window doesn't actually contain the event location (i.e.
- // mouse down over the window and mouse up elsewhere) then do not select the
- // window.
- if (!target->HitTest(event->location()))
- return NULL;
for (size_t i = 0; i < windows_.size(); i++) {
- if (windows_[i]->Contains(target))
- return windows_[i];
+ if (windows_[i].window->Contains(target)) {
+ // The selected window should not be minimized when window selection is
+ // ended.
+ windows_[i].minimized = false;
+ windows_[i].original_transform = gfx::Transform();
+
+ // The delegate may delete the WindowSelector, assume the object may no
+ // longer valid after calling this.
+ delegate_->OnWindowSelected(windows_[i].window);
+ return;
+ }
}
- return NULL;
-}
-
-void WindowSelector::HandleSelectionEvent(WindowSelectorWindow* target) {
- // The selected window should not be minimized when window selection is
- // ended.
- target->RestoreWindowOnExit();
- delegate_->OnWindowSelected(target->window());
}
void WindowSelector::PositionWindows() {
- if (selection_root_) {
- DCHECK_EQ(mode_, CYCLE);
- std::vector<WindowSelectorWindow*> windows;
- for (size_t i = 0; i < windows_.size(); ++i)
- windows.push_back(windows_[i]);
- PositionWindowsOnRoot(selection_root_, windows);
- } else {
- DCHECK_EQ(mode_, OVERVIEW);
- Shell::RootWindowList root_window_list = Shell::GetAllRootWindows();
- for (size_t i = 0; i < root_window_list.size(); ++i)
- PositionWindowsFromRoot(root_window_list[i]);
+ Shell::RootWindowList root_window_list = Shell::GetAllRootWindows();
+ for (size_t i = 0; i < root_window_list.size(); ++i) {
+ PositionWindowsOnRoot(root_window_list[i]);
}
}
-void WindowSelector::PositionWindowsFromRoot(aura::RootWindow* root_window) {
- std::vector<WindowSelectorWindow*> windows;
+void WindowSelector::PositionWindowsOnRoot(aura::RootWindow* root_window) {
+ gfx::Size window_size;
+ gfx::Rect total_bounds = ScreenAsh::GetDisplayWorkAreaBoundsInParent(
+ Shell::GetContainer(root_window,
+ internal::kShellWindowId_DefaultContainer));
+
+ std::vector<WindowDetails> windows;
for (size_t i = 0; i < windows_.size(); ++i) {
- if (windows_[i]->window()->GetRootWindow() == root_window)
+ if (windows_[i].window->GetRootWindow() == root_window)
windows.push_back(windows_[i]);
}
- PositionWindowsOnRoot(root_window, windows);
-}
-
-void WindowSelector::PositionWindowsOnRoot(
- aura::RootWindow* root_window,
- const std::vector<WindowSelectorWindow*>& windows) {
if (windows.empty())
return;
- gfx::Size window_size;
- gfx::Rect total_bounds = ScreenAsh::ConvertRectToScreen(root_window,
- ScreenAsh::GetDisplayWorkAreaBoundsInParent(
- Shell::GetContainer(root_window,
- internal::kShellWindowId_DefaultContainer)));
-
// Find the minimum number of windows per row that will fit all of the
// windows on screen.
size_t columns = std::max(
@@ -488,6 +195,12 @@ void WindowSelector::PositionWindowsOnRoot(
int y_offset = total_bounds.y() + (total_bounds.height() -
rows * window_size.height()) / 2;
for (size_t i = 0; i < windows.size(); ++i) {
+ ui::ScopedLayerAnimationSettings animation_settings(
+ windows[i].window->layer()->GetAnimator());
+ animation_settings.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ animation_settings.SetTransitionDuration(
+ base::TimeDelta::FromMilliseconds(kOverviewTransitionMilliseconds));
gfx::Transform transform;
int column = i % columns;
int row = i / columns;
@@ -496,48 +209,7 @@ void WindowSelector::PositionWindowsOnRoot(
window_size.width(),
window_size.height());
target_bounds.Inset(kWindowMargin, kWindowMargin);
- windows[i]->TransformToFitBounds(root_window, target_bounds);
- }
-}
-
-void WindowSelector::InitializeSelectionWidget() {
- selection_widget_.reset(new views::Widget);
- views::Widget::InitParams params;
- params.type = views::Widget::InitParams::TYPE_POPUP;
- params.can_activate = false;
- params.keep_on_top = false;
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
- params.parent = Shell::GetContainer(
- selection_root_,
- internal::kShellWindowId_DefaultContainer);
- params.accept_events = false;
- selection_widget_->set_focus_on_creation(false);
- selection_widget_->Init(params);
- views::View* content_view = new views::View;
- content_view->set_background(
- views::Background::CreateSolidBackground(kWindowSelectorSelectionColor));
- selection_widget_->SetContentsView(content_view);
- UpdateSelectionLocation(false);
- selection_widget_->GetNativeWindow()->parent()->StackChildAtBottom(
- selection_widget_->GetNativeWindow());
- selection_widget_->Show();
- selection_widget_->GetNativeWindow()->layer()->SetOpacity(
- kWindowSelectorSelectionOpacity);
-}
-
-void WindowSelector::UpdateSelectionLocation(bool animate) {
- if (!selection_widget_)
- return;
- gfx::Rect target_bounds = windows_[selected_window_]->bounds();
- target_bounds.Inset(-kWindowSelectorSelectionPadding,
- -kWindowSelectorSelectionPadding);
- if (animate) {
- WindowSelectorAnimationSettings animation_settings(
- selection_widget_->GetNativeWindow());
- selection_widget_->SetBounds(target_bounds);
- } else {
- selection_widget_->SetBounds(target_bounds);
+ TransformWindowToFitBounds(windows[i].window, target_bounds);
}
}
diff --git a/ash/wm/window_selector.h b/ash/wm/window_selector.h
index 92ed607..900787d 100644
--- a/ash/wm/window_selector.h
+++ b/ash/wm/window_selector.h
@@ -8,8 +8,6 @@
#include <vector>
#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
#include "ui/aura/window_observer.h"
#include "ui/base/events/event_handler.h"
#include "ui/gfx/transform.h"
@@ -18,49 +16,21 @@ namespace aura {
class RootWindow;
}
-namespace ui {
-class LocatedEvent;
-}
-
-namespace views {
-class Widget;
-}
-
namespace ash {
class WindowSelectorDelegate;
-class WindowSelectorWindow;
// The WindowSelector shows a grid of all of your windows and allows selecting
-// a window by clicking or tapping on it (OVERVIEW mode) or by alt-tabbing to
-// it (CYCLE mode).
+// a window by clicking or tapping on it.
class WindowSelector : public ui::EventHandler,
public aura::WindowObserver {
public:
- enum Direction {
- FORWARD,
- BACKWARD
- };
- enum Mode {
- CYCLE,
- OVERVIEW
- };
-
typedef std::vector<aura::Window*> WindowList;
WindowSelector(const WindowList& windows,
- Mode mode,
WindowSelectorDelegate* delegate);
virtual ~WindowSelector();
- // Step to the next window in |direction|.
- void Step(Direction direction);
-
- // Select the current window.
- void SelectWindow();
-
- Mode mode() { return mode_; }
-
// ui::EventHandler:
virtual void OnEvent(ui::Event* event) OVERRIDE;
virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
@@ -70,48 +40,37 @@ class WindowSelector : public ui::EventHandler,
virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
private:
- // Returns the target of |event| or NULL if the event is not targeted at
- // any of the windows in the selector.
- WindowSelectorWindow* GetEventTarget(ui::LocatedEvent* event);
+ struct WindowDetails {
+ WindowDetails() : window(NULL), minimized(false) {}
- // Handles a selection event for |target|.
- void HandleSelectionEvent(WindowSelectorWindow* target);
+ bool operator==(const aura::Window* other_window) const {
+ return window == other_window;
+ }
- // Position all of the windows based on the current selection mode.
- void PositionWindows();
- // Position all of the windows from |root_window| on |root_window|.
- void PositionWindowsFromRoot(aura::RootWindow* root_window);
- // Position all of the |windows| to fit on the |root_window|.
- void PositionWindowsOnRoot(aura::RootWindow* root_window,
- const std::vector<WindowSelectorWindow*>& windows);
+ // A weak pointer to the window.
+ aura::Window* window;
- void InitializeSelectionWidget();
+ // If true, the window was minimized and this should be restored if the
+ // window was not selected.
+ bool minimized;
+
+ // The original transform of the window before entering overview mode.
+ gfx::Transform original_transform;
+ };
- // Updates the selection widget's location to the currently selected window.
- // If |animate| the transition to the new location is animated.
- void UpdateSelectionLocation(bool animate);
+ void HandleSelectionEvent(ui::Event* event);
+ void PositionWindows();
+ void PositionWindowsOnRoot(aura::RootWindow* root_window);
- // The collection of windows in the overview wrapped by a helper class which
- // restores their state and helps transform them to other root windows.
- ScopedVector<WindowSelectorWindow> windows_;
+ void SelectWindow(aura::Window*);
- // The window selection mode.
- Mode mode_;
+ // List of weak pointers of windows to select from.
+ std::vector<WindowDetails> windows_;
// Weak pointer to the selector delegate which will be called when a
// selection is made.
WindowSelectorDelegate* delegate_;
- // Index of the currently selected window if the mode is CYCLE.
- size_t selected_window_;
-
- // Widget indicating which window is currently selected.
- scoped_ptr<views::Widget> selection_widget_;
-
- // In CYCLE mode, the root window in which selection is taking place.
- // NULL otherwise.
- aura::RootWindow* selection_root_;
-
DISALLOW_COPY_AND_ASSIGN(WindowSelector);
};
diff --git a/ash/wm/window_selector_controller.cc b/ash/wm/window_selector_controller.cc
index e6cd383..c7fe696 100644
--- a/ash/wm/window_selector_controller.cc
+++ b/ash/wm/window_selector_controller.cc
@@ -9,47 +9,9 @@
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/window_selector.h"
#include "ash/wm/window_util.h"
-#include "ui/base/events/event.h"
-#include "ui/base/events/event_handler.h"
namespace ash {
-namespace {
-
-// Filter to watch for the termination of a keyboard gesture to cycle through
-// multiple windows.
-class WindowSelectorEventFilter : public ui::EventHandler {
- public:
- WindowSelectorEventFilter();
- virtual ~WindowSelectorEventFilter();
-
- // Overridden from ui::EventHandler:
- virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WindowSelectorEventFilter);
-};
-
-// Watch for all keyboard events by filtering the root window.
-WindowSelectorEventFilter::WindowSelectorEventFilter() {
- Shell::GetInstance()->AddPreTargetHandler(this);
-}
-
-WindowSelectorEventFilter::~WindowSelectorEventFilter() {
- Shell::GetInstance()->RemovePreTargetHandler(this);
-}
-
-void WindowSelectorEventFilter::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_selector_controller()->AltKeyReleased();
- // Warning: |this| will be deleted from here on.
- }
-}
-
-} // namespace
-
WindowSelectorController::WindowSelectorController() {
}
@@ -79,33 +41,10 @@ void WindowSelectorController::ToggleOverview() {
aura::Window* active_window = wm::GetActiveWindow();
if (active_window)
wm::DeactivateWindow(active_window);
- window_selector_.reset(
- new WindowSelector(windows, WindowSelector::OVERVIEW, this));
- }
-}
-
-void WindowSelectorController::HandleCycleWindow(
- WindowSelector::Direction direction) {
- if (!CanSelect())
- return;
-
- if (!IsSelecting()) {
- event_handler_.reset(new WindowSelectorEventFilter());
- std::vector<aura::Window*> windows = ash::Shell::GetInstance()->
- mru_window_tracker()->BuildMruWindowList();
- window_selector_.reset(
- new WindowSelector(windows, WindowSelector::CYCLE, this));
- window_selector_->Step(direction);
- } else if (window_selector_->mode() == WindowSelector::CYCLE) {
- window_selector_->Step(direction);
+ window_selector_.reset(new WindowSelector(windows, this));
}
}
-void WindowSelectorController::AltKeyReleased() {
- event_handler_.reset();
- window_selector_->SelectWindow();
-}
-
bool WindowSelectorController::IsSelecting() {
return window_selector_.get() != NULL;
}
diff --git a/ash/wm/window_selector_controller.h b/ash/wm/window_selector_controller.h
index 385c30e..8b11005 100644
--- a/ash/wm/window_selector_controller.h
+++ b/ash/wm/window_selector_controller.h
@@ -9,7 +9,6 @@
#include <vector>
#include "ash/ash_export.h"
-#include "ash/wm/window_selector.h"
#include "ash/wm/window_selector_delegate.h"
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
@@ -19,10 +18,6 @@ namespace aura {
class Window;
}
-namespace ui {
-class EventHandler;
-}
-
namespace ash {
class WindowSelector;
@@ -44,15 +39,6 @@ class ASH_EXPORT WindowSelectorController
// or touch rather than keypresses.
void ToggleOverview();
- // Cycles between windows in the given |direction|. It is assumed that the
- // alt key is held down and a key filter is installed to watch for alt being
- // released.
- void HandleCycleWindow(WindowSelector::Direction direction);
-
- // Informs the controller that the Alt key has been released and it can
- // terminate the existing multi-step cycle.
- void AltKeyReleased();
-
// Returns true if window selection mode is active.
bool IsSelecting();
@@ -62,7 +48,6 @@ class ASH_EXPORT WindowSelectorController
private:
scoped_ptr<WindowSelector> window_selector_;
- scoped_ptr<ui::EventHandler> event_handler_;
DISALLOW_COPY_AND_ASSIGN(WindowSelectorController);
};
diff --git a/ash/wm/window_selector_unittest.cc b/ash/wm/window_selector_unittest.cc
index 9ac15d6..01a96bf 100644
--- a/ash/wm/window_selector_unittest.cc
+++ b/ash/wm/window_selector_unittest.cc
@@ -107,27 +107,6 @@ class WindowSelectorTest : public test::AshTestBase {
}
}
- void Cycle(WindowSelector::Direction direction) {
- if (!IsSelecting()) {
- std::vector<aura::Window*> windows = ash::Shell::GetInstance()->
- mru_window_tracker()->BuildMruWindowList();
- ScopedVector<LayerAnimationObserver> animations;
- for (size_t i = 0; i < windows.size(); ++i)
- animations.push_back(new LayerAnimationObserver(windows[i]->layer()));
- ash::Shell::GetInstance()->window_selector_controller()->
- HandleCycleWindow(direction);
- for (size_t i = 0; i < animations.size(); ++i)
- animations[i]->WaitUntilDone();
- } else {
- ash::Shell::GetInstance()->window_selector_controller()->
- HandleCycleWindow(direction);
- }
- }
-
- void StopCycling() {
- ash::Shell::GetInstance()->window_selector_controller()->AltKeyReleased();
- }
-
gfx::RectF GetTransformedBounds(aura::Window* window) {
gfx::RectF bounds(window->layer()->bounds());
window->layer()->transform().TransformRect(&bounds);
@@ -146,11 +125,6 @@ class WindowSelectorTest : public test::AshTestBase {
event_generator.ClickLeftButton();
}
- bool IsSelecting() {
- return ash::Shell::GetInstance()->window_selector_controller()->
- IsSelecting();
- }
-
private:
aura::test::TestWindowDelegate wd;
@@ -177,29 +151,6 @@ TEST_F(WindowSelectorTest, Basic) {
EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
}
-// Tests entering overview mode with three windows and cycling through them.
-TEST_F(WindowSelectorTest, BasicCycle) {
- gfx::Rect bounds(0, 0, 400, 400);
- scoped_ptr<aura::Window> window1(CreateWindow(bounds));
- scoped_ptr<aura::Window> window2(CreateWindow(bounds));
- scoped_ptr<aura::Window> window3(CreateWindow(bounds));
- wm::ActivateWindow(window3.get());
- wm::ActivateWindow(window2.get());
- wm::ActivateWindow(window1.get());
- EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
- EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
- EXPECT_FALSE(wm::IsActiveWindow(window3.get()));
-
- Cycle(WindowSelector::FORWARD);
- EXPECT_TRUE(IsSelecting());
- Cycle(WindowSelector::FORWARD);
- StopCycling();
- EXPECT_FALSE(IsSelecting());
- EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
- EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
- EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
-}
-
// Tests that overview mode is exited if the last remaining window is destroyed.
TEST_F(WindowSelectorTest, LastWindowDestroyed) {
gfx::Rect bounds(0, 0, 400, 400);
@@ -209,7 +160,8 @@ TEST_F(WindowSelectorTest, LastWindowDestroyed) {
window1.reset();
window2.reset();
- EXPECT_FALSE(IsSelecting());
+ EXPECT_FALSE(ash::Shell::GetInstance()->window_selector_controller()->
+ IsSelecting());
}
// Tests that windows remain on the display they are currently on in overview