diff options
author | dbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-11 03:56:09 +0000 |
---|---|---|
committer | dbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-11 03:56:09 +0000 |
commit | 456b003a7a0d4c7621b20c92c3ee28e87ec57ee8 (patch) | |
tree | d12f23ac14b9ce9e9f326d84c10f7bbf4ba5764c | |
parent | b0b5519b6b692908f11584db8820294bb3663934 (diff) | |
download | chromium_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.cc | 14 | ||||
-rw-r--r-- | ash/wm/window_selector.cc | 494 | ||||
-rw-r--r-- | ash/wm/window_selector.h | 83 | ||||
-rw-r--r-- | ash/wm/window_selector_controller.cc | 63 | ||||
-rw-r--r-- | ash/wm/window_selector_controller.h | 15 | ||||
-rw-r--r-- | ash/wm/window_selector_unittest.cc | 52 |
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 |