diff options
Diffstat (limited to 'ash')
24 files changed, 245 insertions, 762 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index 5e6a4dc..a93aa58 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -543,8 +543,6 @@ 'wm/overview/scoped_overview_animation_settings.cc', 'wm/overview/scoped_transform_overview_window.cc', 'wm/overview/scoped_transform_overview_window.h', - 'wm/overview/scoped_window_copy.cc', - 'wm/overview/scoped_window_copy.h', 'wm/overview/window_grid.cc', 'wm/overview/window_grid.h', 'wm/overview/window_selector.cc', diff --git a/ash/shell.cc b/ash/shell.cc index 0bdaeda..75bc428 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -419,8 +419,8 @@ void Shell::OnOverviewModeStarting() { FOR_EACH_OBSERVER(ShellObserver, observers_, OnOverviewModeStarting()); } -void Shell::OnOverviewModeEnding() { - FOR_EACH_OBSERVER(ShellObserver, observers_, OnOverviewModeEnding()); +void Shell::OnOverviewModeEnded() { + FOR_EACH_OBSERVER(ShellObserver, observers_, OnOverviewModeEnded()); } void Shell::OnMaximizeModeStarted() { diff --git a/ash/shell.h b/ash/shell.h index 15c3997..155d339 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -298,9 +298,8 @@ class ASH_EXPORT Shell : public SystemModalContainerEventFilterDelegate, // get re-arranged). void OnOverviewModeStarting(); - // Called before the overview mode is ending (before the windows get arranged - // to their final position). - void OnOverviewModeEnding(); + // Called after overview mode has ended. + void OnOverviewModeEnded(); // Called after maximize mode has started, windows might still animate though. void OnMaximizeModeStarted(); diff --git a/ash/shell_observer.h b/ash/shell_observer.h index 35b2555..901c25a 100644 --- a/ash/shell_observer.h +++ b/ash/shell_observer.h @@ -49,9 +49,8 @@ class ASH_EXPORT ShellObserver { // get re-arranged). virtual void OnOverviewModeStarting() {} - // Called before the overview mode is ending (before the windows get arranged - // to their final position). - virtual void OnOverviewModeEnding() {} + // Called after overview mode has ended. + virtual void OnOverviewModeEnded() {} // Called when the always maximize mode has started. Windows might still // animate though. diff --git a/ash/system/overview/overview_button_tray.cc b/ash/system/overview/overview_button_tray.cc index 7c8a920..ec2912f 100644 --- a/ash/system/overview/overview_button_tray.cc +++ b/ash/system/overview/overview_button_tray.cc @@ -69,7 +69,7 @@ void OverviewButtonTray::OnMaximizeModeEnded() { UpdateIconVisibility(); } -void OverviewButtonTray::OnOverviewModeEnding() { +void OverviewButtonTray::OnOverviewModeEnded() { SetDrawBackgroundAsActive(false); } diff --git a/ash/system/overview/overview_button_tray.h b/ash/system/overview/overview_button_tray.h index 1aca24a..a58bae1 100644 --- a/ash/system/overview/overview_button_tray.h +++ b/ash/system/overview/overview_button_tray.h @@ -37,7 +37,7 @@ class ASH_EXPORT OverviewButtonTray : public TrayBackgroundView, // ShellObserver: void OnMaximizeModeStarted() override; void OnMaximizeModeEnded() override; - void OnOverviewModeEnding() override; + void OnOverviewModeEnded() override; // TrayBackgroundView: bool ClickedOutsideBubble() override; diff --git a/ash/wm/maximize_mode/maximize_mode_window_manager.cc b/ash/wm/maximize_mode/maximize_mode_window_manager.cc index 231fdae..d9eab72 100644 --- a/ash/wm/maximize_mode/maximize_mode_window_manager.cc +++ b/ash/wm/maximize_mode/maximize_mode_window_manager.cc @@ -85,7 +85,7 @@ void MaximizeModeWindowManager::OnOverviewModeStarting() { backdrops_hidden_ = true; } -void MaximizeModeWindowManager::OnOverviewModeEnding() { +void MaximizeModeWindowManager::OnOverviewModeEnded() { if (!backdrops_hidden_) return; diff --git a/ash/wm/maximize_mode/maximize_mode_window_manager.h b/ash/wm/maximize_mode/maximize_mode_window_manager.h index c6cba66..b29bd6d 100644 --- a/ash/wm/maximize_mode/maximize_mode_window_manager.h +++ b/ash/wm/maximize_mode/maximize_mode_window_manager.h @@ -53,7 +53,7 @@ class ASH_EXPORT MaximizeModeWindowManager : public aura::WindowObserver, // ShellObserver overrides: void OnOverviewModeStarting() override; - void OnOverviewModeEnding() override; + void OnOverviewModeEnded() override; // Overridden from WindowObserver: void OnWindowDestroying(aura::Window* window) override; diff --git a/ash/wm/overview/scoped_transform_overview_window.cc b/ash/wm/overview/scoped_transform_overview_window.cc index 41205bf..5d2734d 100644 --- a/ash/wm/overview/scoped_transform_overview_window.cc +++ b/ash/wm/overview/scoped_transform_overview_window.cc @@ -10,7 +10,6 @@ #include "ash/screen_util.h" #include "ash/shell_window_ids.h" #include "ash/wm/overview/scoped_overview_animation_settings.h" -#include "ash/wm/overview/scoped_window_copy.h" #include "ash/wm/overview/window_selector_item.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" @@ -175,36 +174,37 @@ ScopedTransformOverviewWindow::ScopedTransformOverviewWindow( overview_started_(false), original_transform_(window->layer()->GetTargetTransform()), original_opacity_(window->layer()->GetTargetOpacity()) { + DCHECK(window_); } ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() { - if (window_) { - ScopedAnimationSettings animation_settings_list; - BeginScopedAnimation( - OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, - &animation_settings_list); - SetTransform(window()->GetRootWindow(), original_transform_); - - ScopedOverviewAnimationSettings animation_settings( - OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, - window_); - gfx::Transform transform; - if (minimized_ && window_->GetProperty(aura::client::kShowStateKey) != - ui::SHOW_STATE_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. - // Hiding the window needs to be done before the target opacity is 0, - // otherwise the layer's visibility will not be updated - // (See VisibilityController::UpdateLayerVisibility). - window_->Hide(); - window_->layer()->SetOpacity(0); - window_->SetProperty(aura::client::kShowStateKey, - ui::SHOW_STATE_MINIMIZED); - } - wm::GetWindowState(window_)->set_ignored_by_shelf(ignored_by_shelf_); - SetOpacity(original_opacity_); +} + +void ScopedTransformOverviewWindow::RestoreWindow() { + ScopedAnimationSettings animation_settings_list; + BeginScopedAnimation( + OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, + &animation_settings_list); + SetTransform(window()->GetRootWindow(), original_transform_); + + ScopedOverviewAnimationSettings animation_settings( + OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, + window_); + gfx::Transform transform; + if (minimized_ && window_->GetProperty(aura::client::kShowStateKey) != + ui::SHOW_STATE_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. + // Hiding the window needs to be done before the target opacity is 0, + // otherwise the layer's visibility will not be updated + // (See VisibilityController::UpdateLayerVisibility). + window_->Hide(); + window_->layer()->SetOpacity(0); + window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); } + wm::GetWindowState(window_)->set_ignored_by_shelf(ignored_by_shelf_); + SetOpacity(original_opacity_); } void ScopedTransformOverviewWindow::BeginScopedAnimation( @@ -233,17 +233,19 @@ gfx::Rect ScopedTransformOverviewWindow::GetTargetBoundsInScreen() const { return bounds; } -void ScopedTransformOverviewWindow::RestoreWindow() { +void ScopedTransformOverviewWindow::ShowWindowIfMinimized() { if (minimized_ && window_->GetProperty(aura::client::kShowStateKey) == ui::SHOW_STATE_MINIMIZED) { window_->Show(); } } -void ScopedTransformOverviewWindow::RestoreWindowOnExit() { - minimized_ = false; - original_transform_ = gfx::Transform(); - original_opacity_ = kRestoreWindowOpacity; +void ScopedTransformOverviewWindow::ShowWindowOnExit() { + if (minimized_) { + minimized_ = false; + original_transform_ = gfx::Transform(); + original_opacity_ = kRestoreWindowOpacity; + } } void ScopedTransformOverviewWindow::OnWindowDestroyed() { @@ -315,7 +317,7 @@ void ScopedTransformOverviewWindow::PrepareForOverview() { DCHECK(!overview_started_); overview_started_ = true; wm::GetWindowState(window_)->set_ignored_by_shelf(true); - RestoreWindow(); + ShowWindowIfMinimized(); } } // namespace ash diff --git a/ash/wm/overview/scoped_transform_overview_window.h b/ash/wm/overview/scoped_transform_overview_window.h index daa25dee..99ad658 100644 --- a/ash/wm/overview/scoped_transform_overview_window.h +++ b/ash/wm/overview/scoped_transform_overview_window.h @@ -63,7 +63,6 @@ class ScopedTransformOverviewWindow return activate_button_.get(); } - // Starts an animation sequence which will use animation settings specified by // |animation_type|. The |animation_settings| container is populated with // scoped entities and the container should be destroyed at the end of the @@ -89,16 +88,15 @@ class ScopedTransformOverviewWindow // Returns the original target bounds of all transformed windows. gfx::Rect GetTargetBoundsInScreen() const; - // Restores the window if it was minimized. + // Restores and animates the managed window to it's non overview mode state. void RestoreWindow(); - // Restores this window on exit rather than returning it to a minimized state - // if it was minimized on entering overview mode. - void RestoreWindowOnExit(); + // Forces the managed window to be shown (ie not hidden or minimized) when + // calling RestoreWindow(). + void ShowWindowOnExit(); // Informs the ScopedTransformOverviewWindow that the window being watched was - // destroyed. This resets the internal window pointer to avoid calling - // anything on the window at destruction time. + // destroyed. This resets the internal window pointer. void OnWindowDestroyed(); // Prepares for overview mode by doing any necessary actions before entering. @@ -121,6 +119,9 @@ class ScopedTransformOverviewWindow void Select() override; private: + // Shows the window if it was minimized. + void ShowWindowIfMinimized(); + // A weak pointer to the real window in the overview. aura::Window* window_; diff --git a/ash/wm/overview/scoped_window_copy.cc b/ash/wm/overview/scoped_window_copy.cc deleted file mode 100644 index 40f156b..0000000 --- a/ash/wm/overview/scoped_window_copy.cc +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 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/overview/scoped_window_copy.h" - -#include "ash/screen_util.h" -#include "ash/shell.h" -#include "ui/aura/client/aura_constants.h" -#include "ui/aura/client/screen_position_client.h" -#include "ui/aura/window.h" -#include "ui/aura/window_event_dispatcher.h" -#include "ui/compositor/layer_animation_observer.h" -#include "ui/compositor/layer_tree_owner.h" -#include "ui/gfx/display.h" -#include "ui/views/widget/widget.h" -#include "ui/wm/core/shadow_types.h" -#include "ui/wm/core/window_util.h" - -namespace ash { - -namespace { - -// Creates a copy of |window| with |recreated_layer| in the |target_root|. -views::Widget* CreateCopyOfWindow(aura::Window* target_root, - aura::Window* src_window, - ui::Layer* recreated_layer) { - // Save and remove the transform from the layer to later reapply to both the - // source and newly created copy window. - gfx::Transform transform = recreated_layer->transform(); - recreated_layer->SetTransform(gfx::Transform()); - - src_window->SetTransform(transform); - 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.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); - ::wm::SetShadowType(widget->GetNativeWindow(), - ::wm::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->SetTransform(transform); - window->Show(); - return widget; -} - -} // namespace - -// An observer which closes the widget and deletes the layer after an -// animation finishes. -class CleanupWidgetAfterAnimationObserver : public ui::LayerAnimationObserver { - public: - CleanupWidgetAfterAnimationObserver( - views::Widget* widget, - scoped_ptr<ui::LayerTreeOwner> layer_owner); - - // Takes ownership of the widget. At this point the class will delete itself - // and clean up the layer when there are no pending animations. - void TakeOwnershipOfWidget(); - - // ui::LayerAnimationObserver: - void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override; - void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override; - void OnLayerAnimationScheduled(ui::LayerAnimationSequence* sequence) override; - - private: - ~CleanupWidgetAfterAnimationObserver() override; - - // If the necessary conditions have been satisfied to destruct this - // class, deletes itself and cleans up the widget and layer. - void MaybeDestruct(); - - views::Widget* widget_; - scoped_ptr<ui::LayerTreeOwner> layer_owner_; - bool owns_widget_; - int pending_animations_; - - DISALLOW_COPY_AND_ASSIGN(CleanupWidgetAfterAnimationObserver); -}; - -CleanupWidgetAfterAnimationObserver::CleanupWidgetAfterAnimationObserver( - views::Widget* widget, - scoped_ptr<ui::LayerTreeOwner> layer_owner) - : widget_(widget), - layer_owner_(layer_owner.Pass()), - owns_widget_(false), - pending_animations_(0) { - widget_->GetNativeWindow()->layer()->GetAnimator()->AddObserver(this); -} - -void CleanupWidgetAfterAnimationObserver::TakeOwnershipOfWidget() { - owns_widget_ = true; - MaybeDestruct(); -} - -void CleanupWidgetAfterAnimationObserver::OnLayerAnimationEnded( - ui::LayerAnimationSequence* sequence) { - pending_animations_--; - MaybeDestruct(); -} - -void CleanupWidgetAfterAnimationObserver::OnLayerAnimationAborted( - ui::LayerAnimationSequence* sequence) { - pending_animations_--; - MaybeDestruct(); -} - -void CleanupWidgetAfterAnimationObserver::OnLayerAnimationScheduled( - ui::LayerAnimationSequence* sequence) { - pending_animations_++; -} - -CleanupWidgetAfterAnimationObserver::~CleanupWidgetAfterAnimationObserver() { - widget_->GetNativeWindow()->layer()->GetAnimator()->RemoveObserver(this); - widget_->Close(); - widget_ = NULL; -} - -void CleanupWidgetAfterAnimationObserver::MaybeDestruct() { - if (pending_animations_ || !owns_widget_) - return; - delete this; -} - -ScopedWindowCopy::ScopedWindowCopy(aura::Window* target_root, - aura::Window* src_window) { - scoped_ptr<ui::LayerTreeOwner> layer_owner = - ::wm::RecreateLayers(src_window); - widget_ = CreateCopyOfWindow(target_root, src_window, layer_owner->root()); - cleanup_observer_ = - new CleanupWidgetAfterAnimationObserver(widget_, layer_owner.Pass()); -} - -ScopedWindowCopy::~ScopedWindowCopy() { - // The cleanup observer will delete itself and the window when any pending - // animations have completed. - cleanup_observer_->TakeOwnershipOfWidget(); -} - -aura::Window* ScopedWindowCopy::GetWindow() { - return widget_->GetNativeWindow(); -} - -} // namespace ash diff --git a/ash/wm/overview/scoped_window_copy.h b/ash/wm/overview/scoped_window_copy.h deleted file mode 100644 index babc890..0000000 --- a/ash/wm/overview/scoped_window_copy.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 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. - -#ifndef ASH_WM_OVERVIEW_SCOPED_WINDOW_COPY_H_ -#define ASH_WM_OVERVIEW_SCOPED_WINDOW_COPY_H_ - -#include "base/basictypes.h" - -namespace aura { -class Window; -} - -namespace views { -class Widget; -} - -namespace ash { - -class CleanupWidgetAfterAnimationObserver; - -// ScopedWindowCopy copies a window and will clean up the copied layers after -// the class goes out of scope and the last animation has finished. -class ScopedWindowCopy { - public: - ScopedWindowCopy(aura::Window* target_root, aura::Window* src_window); - ~ScopedWindowCopy(); - - aura::Window* GetWindow(); - - private: - // A weak pointer to a copy of the source window owned by cleanup_observer_. - views::Widget* widget_; - - // A weak pointer to an animation observer which owns itself. When the - // ScopedWindowCopy is destroyed The animation observer will clean up the - // widget, layer and itself once any pending animations have completed. - CleanupWidgetAfterAnimationObserver* cleanup_observer_; - - DISALLOW_COPY_AND_ASSIGN(ScopedWindowCopy); -}; - -} // namespace ash - -#endif // ASH_WM_OVERVIEW_SCOPED_WINDOW_COPY_H_ diff --git a/ash/wm/overview/transparent_activate_window_button.cc b/ash/wm/overview/transparent_activate_window_button.cc index 212b57c..4189bf1 100644 --- a/ash/wm/overview/transparent_activate_window_button.cc +++ b/ash/wm/overview/transparent_activate_window_button.cc @@ -133,12 +133,4 @@ void TransparentActivateWindowButton::SendFocusAlert() const { NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true); } -void TransparentActivateWindowButton::StackAbove( - TransparentActivateWindowButton* activate_button) { - aura::Window* this_window = event_handler_widget_->GetNativeWindow(); - aura::Window* other_window = activate_button->event_handler_widget_-> - GetNativeWindow(); - this_window->parent()->StackChildAbove(this_window, other_window); -} - } // namespace ash diff --git a/ash/wm/overview/transparent_activate_window_button.h b/ash/wm/overview/transparent_activate_window_button.h index 0fe3747..9dac693 100644 --- a/ash/wm/overview/transparent_activate_window_button.h +++ b/ash/wm/overview/transparent_activate_window_button.h @@ -42,9 +42,6 @@ class TransparentActivateWindowButton { // window title is read. void SendFocusAlert() const; - // Stacks |this| above |activate_button| in the window z-ordering. - void StackAbove(TransparentActivateWindowButton* activate_button); - private: // The transparent window event handler widget itself. scoped_ptr<views::Widget> event_handler_widget_; diff --git a/ash/wm/overview/window_grid.cc b/ash/wm/overview/window_grid.cc index defc09b..b605ad5 100644 --- a/ash/wm/overview/window_grid.cc +++ b/ash/wm/overview/window_grid.cc @@ -74,21 +74,7 @@ struct WindowSelectorItemComparator } bool operator()(WindowSelectorItem* window) const { - return window->HasSelectableWindow(target); - } - - const aura::Window* target; -}; - -// A comparator for locating a WindowSelectorItem given a targeted window. -struct WindowSelectorItemTargetComparator - : public std::unary_function<WindowSelectorItem*, bool> { - explicit WindowSelectorItemTargetComparator(const aura::Window* target_window) - : target(target_window) { - } - - bool operator()(WindowSelectorItem* window) const { - return window->Contains(target); + return window->GetWindow() == target; } const aura::Window* target; @@ -141,10 +127,6 @@ WindowGrid::WindowGrid(aura::Window* root_window, WindowSelector* window_selector) : root_window_(root_window), window_selector_(window_selector) { - WindowSelectorItem* panels_item = nullptr; - - std::set<aura::Window*> panels_item_windows; - aura::Window* panels_parent = nullptr; for (aura::Window::Windows::const_iterator iter = windows.begin(); iter != windows.end(); ++iter) { @@ -153,36 +135,7 @@ WindowGrid::WindowGrid(aura::Window* root_window, (*iter)->AddObserver(this); observed_windows_.insert(*iter); - if ((*iter)->type() == ui::wm::WINDOW_TYPE_PANEL && - wm::GetWindowState(*iter)->panel_attached()) { - // Attached panel windows are grouped into a single overview item per - // grid. - if (!panels_item) { - panels_item = new WindowSelectorItem(root_window_); - window_list_.push_back(panels_item); - } - DCHECK(panels_parent == nullptr || panels_parent == (*iter)->parent()); - panels_parent = (*iter)->parent(); - panels_item_windows.insert(*iter); - } else { - WindowSelectorItem* selector_item = new WindowSelectorItem(root_window_); - window_list_.push_back(selector_item); - selector_item->AddWindow(*iter); - } - } - - if (panels_item) { - // Sort and add panel windows in reverse z order to the WindowSelectorItem - // so that the transparent overlays are in the proper order. - - CHECK_GT(panels_item_windows.size(), 0u); - - const Windows& children = panels_parent->children(); - for (Windows::const_reverse_iterator iter = children.rbegin(); - iter != children.rend(); ++iter) { - if (panels_item_windows.find(*iter) != panels_item_windows.end()) - panels_item->AddWindow(*iter); - } + window_list_.push_back(new WindowSelectorItem(*iter)); } } @@ -247,7 +200,7 @@ void WindowGrid::PositionWindows(bool animate) { window_size.height() * row + y_offset, window_size.width(), window_size.height()); - window_list_[i]->SetBounds(root_window_, target_bounds, animate ? + window_list_[i]->SetBounds(target_bounds, animate ? OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS : OverviewAnimationType::OVERVIEW_ANIMATION_NONE); } @@ -333,16 +286,18 @@ WindowSelectorItem* WindowGrid::SelectedWindow() const { } bool WindowGrid::Contains(const aura::Window* window) const { - return std::find_if(window_list_.begin(), window_list_.end(), - WindowSelectorItemTargetComparator(window)) != - window_list_.end(); + for (const WindowSelectorItem* window_item : window_list_) { + if (window_item->Contains(window)) + return true; + } + return false; } void WindowGrid::FilterItems(const base::string16& pattern) { base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents finder(pattern); for (ScopedVector<WindowSelectorItem>::iterator iter = window_list_.begin(); iter != window_list_.end(); iter++) { - if (finder.Search((*iter)->SelectionWindow()->title(), nullptr, nullptr)) { + if (finder.Search((*iter)->GetWindow()->title(), nullptr, nullptr)) { (*iter)->SetDimmed(false); } else { (*iter)->SetDimmed(true); @@ -361,13 +316,6 @@ void WindowGrid::OnWindowDestroying(aura::Window* window) { DCHECK(iter != window_list_.end()); - (*iter)->RemoveWindow(window); - - // If there are still windows in this selector entry then the overview is - // still active and the active selection remains the same. - if (!(*iter)->empty()) - return; - size_t removed_index = iter - window_list_.begin(); window_list_.erase(iter); @@ -395,7 +343,7 @@ void WindowGrid::OnWindowBoundsChanged(aura::Window* window, const gfx::Rect& new_bounds) { ScopedVector<WindowSelectorItem>::const_iterator iter = std::find_if(window_list_.begin(), window_list_.end(), - WindowSelectorItemTargetComparator(window)); + WindowSelectorItemComparator(window)); DCHECK(iter != window_list_.end()); // Immediately finish any active bounds animation. diff --git a/ash/wm/overview/window_selector.cc b/ash/wm/overview/window_selector.cc index 76eb46a..0a63e8f 100644 --- a/ash/wm/overview/window_selector.cc +++ b/ash/wm/overview/window_selector.cc @@ -92,7 +92,7 @@ struct WindowSelectorItemTargetComparator } bool operator()(WindowSelectorItem* window) const { - return window->Contains(target); + return window->GetWindow() == target; } const aura::Window* target; @@ -217,8 +217,7 @@ views::Widget* CreateTextFilter(views::TextfieldController* controller, const int WindowSelector::kTextFilterBottomEdge = kTextFilterDistanceFromTop + kTextFilterHeight; -WindowSelector::WindowSelector(const WindowList& windows, - WindowSelectorDelegate* delegate) +WindowSelector::WindowSelector(WindowSelectorDelegate* delegate) : delegate_(delegate), restore_focus_window_(aura::client::GetFocusClient( Shell::GetPrimaryRootWindow())->GetFocusedWindow()), @@ -229,11 +228,19 @@ WindowSelector::WindowSelector(const WindowList& windows, num_items_(0), showing_selection_widget_(false), text_filter_string_length_(0), - num_times_textfield_cleared_(0) { + num_times_textfield_cleared_(0), + restoring_minimized_windows_(false) { DCHECK(delegate_); - Shell* shell = Shell::GetInstance(); - shell->OnOverviewModeStarting(); +} +WindowSelector::~WindowSelector() { + RemoveAllObservers(); +} + +// NOTE: The work done in Init() is not done in the constructor because it may +// cause other, unrelated classes, (ie PanelLayoutManager) to make indirect +// calls to restoring_minimized_windows() on a partially constructed object. +void WindowSelector::Init(const WindowList& windows) { if (restore_focus_window_) restore_focus_window_->AddObserver(this); @@ -262,20 +269,33 @@ WindowSelector::WindowSelector(const WindowList& windows, grid_list_.push_back(grid.release()); } - // Do not call PrepareForOverview until all items are added to window_list_ as - // we don't want to cause any window updates until all windows in overview - // are observed. See http://crbug.com/384495. - for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); - iter != grid_list_.end(); ++iter) { - (*iter)->PrepareForOverview(); - (*iter)->PositionWindows(true); + { + // The calls to WindowGrid::PrepareForOverview() and CreateTextFilter(...) + // requires some LayoutManagers (ie PanelLayoutManager) to perform layouts + // so that windows are correctly visible and properly animated in overview + // mode. Otherwise these layouts should be suppressed during overview mode + // so they don't conflict with overview mode animations. The + // |restoring_minimized_windows_| flag enables the PanelLayoutManager to + // make this decision. + base::AutoReset<bool> auto_restoring_minimized_windows( + &restoring_minimized_windows_, true); + + // Do not call PrepareForOverview until all items are added to window_list_ + // as we don't want to cause any window updates until all windows in + // overview are observed. See http://crbug.com/384495. + for (WindowGrid* window_grid : grid_list_) { + window_grid->PrepareForOverview(); + window_grid->PositionWindows(true); + } + + text_filter_widget_.reset( + CreateTextFilter(this, Shell::GetPrimaryRootWindow())); } DCHECK(!grid_list_.empty()); UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); - text_filter_widget_.reset( - CreateTextFilter(this, Shell::GetPrimaryRootWindow())); + Shell* shell = Shell::GetInstance(); shell->activation_client()->AddObserver(this); @@ -289,15 +309,12 @@ WindowSelector::WindowSelector(const WindowList& windows, UpdateShelfVisibility(); } -WindowSelector::~WindowSelector() { - Shell* shell = Shell::GetInstance(); - +// NOTE: The work done in Shutdown() is not done in the destructor because it +// may cause other, unrelated classes, (ie PanelLayoutManager) to make indirect +// calls to restoring_minimized_windows() on a partially destructed object. +void WindowSelector::Shutdown() { ResetFocusRestoreWindow(true); - for (std::set<aura::Window*>::iterator iter = observed_windows_.begin(); - iter != observed_windows_.end(); ++iter) { - (*iter)->RemoveObserver(this); - } - shell->activation_client()->RemoveObserver(this); + RemoveAllObservers(); aura::Window::Windows root_windows = Shell::GetAllRootWindows(); for (aura::Window::Windows::const_iterator iter = root_windows.begin(); @@ -319,12 +336,11 @@ WindowSelector::~WindowSelector() { (*iter)->Show(); } - shell->GetScreen()->RemoveObserver(this); - size_t remaining_items = 0; - for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); - iter != grid_list_.end(); iter++) { - remaining_items += (*iter)->size(); + for (WindowGrid* window_grid : grid_list_) { + for (WindowSelectorItem* window_selector_item : window_grid->window_list()) + window_selector_item->RestoreWindow(); + remaining_items += window_grid->size(); } DCHECK(num_items_ >= remaining_items); @@ -347,15 +363,22 @@ WindowSelector::~WindowSelector() { remaining_items); } - // TODO(flackr): Change this to OnOverviewModeEnded and move it to when - // everything is done. - shell->OnOverviewModeEnding(); - // Clearing the window list resets the ignored_by_shelf flag on the windows. grid_list_.clear(); UpdateShelfVisibility(); } +void WindowSelector::RemoveAllObservers() { + Shell* shell = Shell::GetInstance(); + for (aura::Window* window : observed_windows_) + window->RemoveObserver(this); + + shell->activation_client()->RemoveObserver(this); + shell->GetScreen()->RemoveObserver(this); + if (restore_focus_window_) + restore_focus_window_->RemoveObserver(this); +} + void WindowSelector::CancelSelection() { delegate_->OnSelectionEnded(); } @@ -409,7 +432,7 @@ bool WindowSelector::HandleKeyEvent(views::Textfield* sender, Shell::GetInstance()->metrics()->RecordUserMetricsAction( UMA_WINDOW_OVERVIEW_ENTER_KEY); wm::GetWindowState(grid_list_[selected_grid_index_]-> - SelectedWindow()->SelectionWindow())->Activate(); + SelectedWindow()->GetWindow())->Activate(); break; default: // Not a key we are interested in, allow the textfield to handle it. @@ -474,7 +497,7 @@ void WindowSelector::OnWindowActivated(aura::Window* gained_active, WindowSelectorItemTargetComparator(gained_active)); if (iter != windows.end()) - (*iter)->RestoreWindowOnExit(gained_active); + (*iter)->ShowWindowOnExit(); // Don't restore focus on exit if a window was just activated. ResetFocusRestoreWindow(false); diff --git a/ash/wm/overview/window_selector.h b/ash/wm/overview/window_selector.h index a270b48..c8e25a3 100644 --- a/ash/wm/overview/window_selector.h +++ b/ash/wm/overview/window_selector.h @@ -66,16 +66,25 @@ class ASH_EXPORT WindowSelector typedef std::vector<aura::Window*> WindowList; typedef ScopedVector<WindowSelectorItem> WindowSelectorItemList; - WindowSelector(const WindowList& windows, - WindowSelectorDelegate* delegate); + explicit WindowSelector(WindowSelectorDelegate* delegate); ~WindowSelector() override; + // Initialize with the windows that can be selected. + void Init(const WindowList& windows); + + // Perform cleanup that cannot be done in the destructor. + void Shutdown(); + // Cancels window selection. void CancelSelection(); // Called when the last window selector item from a grid is deleted. void OnGridEmpty(WindowGrid* grid); + bool restoring_minimized_windows() const { + return restoring_minimized_windows_; + } + // gfx::DisplayObserver: void OnDisplayAdded(const gfx::Display& display) override; void OnDisplayRemoved(const gfx::Display& display) override; @@ -117,6 +126,10 @@ class ASH_EXPORT WindowSelector // corresponding window grid. void Move(Direction direction, bool animate); + // Removes all observers that were registered during construction and/or + // initialization. + void RemoveAllObservers(); + // Tracks observed windows. std::set<aura::Window*> observed_windows_; @@ -169,6 +182,10 @@ class ASH_EXPORT WindowSelector // during this overview mode session. size_t num_times_textfield_cleared_; + // Tracks whether minimized windows are currently being restored for overview + // mode. + bool restoring_minimized_windows_; + DISALLOW_COPY_AND_ASSIGN(WindowSelector); }; diff --git a/ash/wm/overview/window_selector_controller.cc b/ash/wm/overview/window_selector_controller.cc index 6fbe0da..df14d27 100644 --- a/ash/wm/overview/window_selector_controller.cc +++ b/ash/wm/overview/window_selector_controller.cc @@ -52,7 +52,9 @@ void WindowSelectorController::ToggleOverview() { if (windows.empty()) return; - window_selector_.reset(new WindowSelector(windows, this)); + Shell::GetInstance()->OnOverviewModeStarting(); + window_selector_.reset(new WindowSelector(this)); + window_selector_->Init(windows); OnSelectionStarted(); } } @@ -61,11 +63,18 @@ bool WindowSelectorController::IsSelecting() { return window_selector_.get() != NULL; } +bool WindowSelectorController::IsRestoringMinimizedWindows() const { + return window_selector_.get() != NULL && + window_selector_->restoring_minimized_windows(); +} + // TODO(flackr): Make WindowSelectorController observe the activation of // windows, so we can remove WindowSelectorDelegate. void WindowSelectorController::OnSelectionEnded() { + window_selector_->Shutdown(); window_selector_.reset(); last_selection_time_ = base::Time::Now(); + Shell::GetInstance()->OnOverviewModeEnded(); } void WindowSelectorController::OnSelectionStarted() { diff --git a/ash/wm/overview/window_selector_controller.h b/ash/wm/overview/window_selector_controller.h index 7ccf768..8d4a625 100644 --- a/ash/wm/overview/window_selector_controller.h +++ b/ash/wm/overview/window_selector_controller.h @@ -44,6 +44,10 @@ class ASH_EXPORT WindowSelectorController // Returns true if window selection mode is active. bool IsSelecting(); + // Returns true if overview mode is restoring minimized windows so that they + // are visible during overview mode. + bool IsRestoringMinimizedWindows() const; + // WindowSelectorDelegate: void OnSelectionEnded() override; diff --git a/ash/wm/overview/window_selector_item.cc b/ash/wm/overview/window_selector_item.cc index 7350ebd..4ab47e9 100644 --- a/ash/wm/overview/window_selector_item.cc +++ b/ash/wm/overview/window_selector_item.cc @@ -113,19 +113,20 @@ OverviewCloseButton::~OverviewCloseButton() { } // namespace -WindowSelectorItem::WindowSelectorItem(aura::Window* root_window) +WindowSelectorItem::WindowSelectorItem(aura::Window* window) : dimmed_(false), - root_window_(root_window), + root_window_(window->GetRootWindow()), + transform_window_(window), in_bounds_update_(false), window_label_view_(nullptr), close_button_(new OverviewCloseButton(this)), selector_item_activate_window_button_( - new TransparentActivateWindowButton(root_window, this)) { + new TransparentActivateWindowButton(root_window_, this)) { views::Widget::InitParams params; params.type = views::Widget::InitParams::TYPE_POPUP; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; - params.parent = Shell::GetContainer(root_window, + params.parent = Shell::GetContainer(root_window_, kShellWindowId_OverlayContainer); close_button_widget_.set_focus_on_creation(false); close_button_widget_.Init(params); @@ -141,102 +142,37 @@ WindowSelectorItem::WindowSelectorItem(aura::Window* root_window) close_button_rect.set_x(-close_button_rect.width() / 2); close_button_rect.set_y(-close_button_rect.height() / 2); close_button_widget_.GetNativeWindow()->SetBounds(close_button_rect); -} -WindowSelectorItem::~WindowSelectorItem() { - for (auto* transform_window : transform_windows_) { - transform_window->window()->RemoveObserver(this); - } -} + GetWindow()->AddObserver(this); -void WindowSelectorItem::AddWindow(aura::Window* window) { - DCHECK(window->GetRootWindow() == root_window_); - window->AddObserver(this); - ScopedTransformOverviewWindow* transform_window = - new ScopedTransformOverviewWindow(window); - transform_windows_.push_back(transform_window); - // The transparent overlays are added at the front of the z-order when - // created so make sure the selector item's transparent overlay is behind the - // overlay for the window that was just added. - transform_window->activate_button()->StackAbove( - selector_item_activate_window_button_.get()); - - UpdateSelectorButtons(); UpdateCloseButtonAccessibilityName(); } -bool WindowSelectorItem::HasSelectableWindow(const aura::Window* window) const { - for (auto* transform_window : transform_windows_) { - if (transform_window->window() == window) - return true; - } - return false; -} - -bool WindowSelectorItem::Contains(const aura::Window* target) const { - for (auto* transform_window : transform_windows_) { - if (transform_window->Contains(target)) - return true; - } - return false; +WindowSelectorItem::~WindowSelectorItem() { + GetWindow()->RemoveObserver(this); } -void WindowSelectorItem::RestoreWindowOnExit(aura::Window* window) { - for (auto* transform_window : transform_windows_) { - if (transform_window->Contains(window)) { - transform_window->RestoreWindowOnExit(); - break; - } - } +aura::Window* WindowSelectorItem::GetWindow() { + return transform_window_.window(); } -aura::Window* WindowSelectorItem::SelectionWindow() const { - return SelectionTransformWindow()->window(); +void WindowSelectorItem::RestoreWindow() { + transform_window_.RestoreWindow(); } -void WindowSelectorItem::RemoveWindow(const aura::Window* window) { - bool window_found = false; - - for (TransformWindows::iterator iter = transform_windows_.begin(); - iter != transform_windows_.end(); - ++iter) { - ScopedTransformOverviewWindow* transform_window = *iter; - - if (transform_window->window() == window) { - transform_window->window()->RemoveObserver(this); - transform_window->OnWindowDestroyed(); - transform_windows_.erase(iter); - window_found = true; - break; - } - } - CHECK(window_found); - - - // If empty WindowSelectorItem will be destroyed immediately after this by - // its owner. - if (empty()) - return; - - UpdateCloseButtonAccessibilityName(); - window_label_.reset(); - UpdateWindowLabels(target_bounds_, - OverviewAnimationType::OVERVIEW_ANIMATION_NONE); - UpdateCloseButtonLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE); - UpdateSelectorButtons(); +void WindowSelectorItem::ShowWindowOnExit() { + transform_window_.ShowWindowOnExit(); } -bool WindowSelectorItem::empty() const { - return transform_windows_.empty(); +void WindowSelectorItem::PrepareForOverview() { + transform_window_.PrepareForOverview(); } -void WindowSelectorItem::PrepareForOverview() { - for (auto* transform_window : transform_windows_) - transform_window->PrepareForOverview(); +bool WindowSelectorItem::Contains(const aura::Window* target) const { + return transform_window_.Contains(target); } -void WindowSelectorItem::SetBounds(aura::Window* root_window, - const gfx::Rect& target_bounds, +void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds, OverviewAnimationType animation_type) { if (in_bounds_update_) return; @@ -247,7 +183,7 @@ void WindowSelectorItem::SetBounds(aura::Window* root_window, gfx::Rect inset_bounds(target_bounds); inset_bounds.Inset(kWindowMargin, kWindowMargin); - SetItemBounds(root_window, inset_bounds, animation_type); + SetItemBounds(inset_bounds, animation_type); // SetItemBounds is called before UpdateCloseButtonLayout so the close button // can properly use the updated windows bounds. @@ -258,12 +194,10 @@ void WindowSelectorItem::SetBounds(aura::Window* root_window, void WindowSelectorItem::RecomputeWindowTransforms() { if (in_bounds_update_ || target_bounds_.IsEmpty()) return; - DCHECK(root_window_); base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true); gfx::Rect inset_bounds(target_bounds_); inset_bounds.Inset(kWindowMargin, kWindowMargin); - SetItemBounds(root_window_, inset_bounds, - OverviewAnimationType::OVERVIEW_ANIMATION_NONE); + SetItemBounds(inset_bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE); UpdateCloseButtonLayout(OverviewAnimationType::OVERVIEW_ANIMATION_NONE); UpdateSelectorButtons(); @@ -280,14 +214,18 @@ void WindowSelectorItem::SetDimmed(bool dimmed) { void WindowSelectorItem::ButtonPressed(views::Button* sender, const ui::Event& event) { - CHECK(!transform_windows_.empty()); - SelectionTransformWindow()->Close(); + transform_window_.Close(); +} + +void WindowSelectorItem::OnWindowDestroying(aura::Window* window) { + window->RemoveObserver(this); + transform_window_.OnWindowDestroyed(); } void WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) { // TODO(flackr): Maybe add the new title to a vector of titles so that we can // filter any of the titles the window had while in the overview session. - if (window == SelectionWindow()) { + if (window == GetWindow()) { window_label_view_->SetText(window->title()); UpdateCloseButtonAccessibilityName(); } @@ -296,59 +234,40 @@ void WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) { } void WindowSelectorItem::Select() { - aura::Window* selection_window = SelectionWindow(); + aura::Window* selection_window = GetWindow(); if (selection_window) wm::GetWindowState(selection_window)->Activate(); } -void WindowSelectorItem::SetItemBounds(aura::Window* root_window, - const gfx::Rect& target_bounds, +void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds, OverviewAnimationType animation_type) { - gfx::Rect bounding_rect; - for (auto* transform_window : transform_windows_) { - bounding_rect.Union( - transform_window->GetTargetBoundsInScreen()); - } - gfx::Rect bounds = + DCHECK(root_window_ == GetWindow()->GetRootWindow()); + gfx::Rect screen_bounds = transform_window_.GetTargetBoundsInScreen(); + gfx::Rect selector_item_bounds = ScopedTransformOverviewWindow::ShrinkRectToFitPreservingAspectRatio( - bounding_rect, target_bounds); - gfx::Transform bounding_transform = - ScopedTransformOverviewWindow::GetTransformForRect(bounding_rect, bounds); - for (auto* transform_window : transform_windows_) { - gfx::Rect target_bounds = transform_window->GetTargetBoundsInScreen(); - gfx::Transform transform = TransformAboutPivot( - gfx::Point(bounding_rect.x() - target_bounds.x(), - bounding_rect.y() - target_bounds.y()), - bounding_transform); - - ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings; - transform_window->BeginScopedAnimation(animation_type, &animation_settings); - transform_window->SetTransform(root_window, transform); - transform_window->set_overview_transform(transform); - } + screen_bounds, target_bounds); + gfx::Transform transform = + ScopedTransformOverviewWindow::GetTransformForRect(screen_bounds, + selector_item_bounds); + ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings; + transform_window_.BeginScopedAnimation(animation_type, &animation_settings); + transform_window_.SetTransform(root_window_, transform); + transform_window_.set_overview_transform(transform); } void WindowSelectorItem::SetOpacity(float opacity) { window_label_->GetNativeWindow()->layer()->SetOpacity(opacity); close_button_widget_.GetNativeWindow()->layer()->SetOpacity(opacity); - // TODO(flackr): find a way to make panels that are hidden behind other panels - // look nice. - for (auto* transform_window : transform_windows_) { - transform_window->SetOpacity(opacity); - } + transform_window_.SetOpacity(opacity); } void WindowSelectorItem::UpdateWindowLabels( const gfx::Rect& window_bounds, OverviewAnimationType animation_type) { - // If the root window has changed, force the window label to be recreated - // and faded in on the new root window. - DCHECK(!window_label_ || - window_label_->GetNativeWindow()->GetRootWindow() == root_window_); if (!window_label_) { - CreateWindowLabel(SelectionWindow()->title()); + CreateWindowLabel(GetWindow()->title()); SetupFadeInAfterLayout(window_label_->GetNativeWindow()); } @@ -402,24 +321,15 @@ void WindowSelectorItem::CreateWindowLabel(const base::string16& title) { } void WindowSelectorItem::UpdateSelectorButtons() { - CHECK(!transform_windows_.empty()); + aura::Window* window = GetWindow(); selector_item_activate_window_button_->SetBounds(target_bounds()); - selector_item_activate_window_button_->SetAccessibleName( - transform_windows_.front()->window()->title()); - - for (auto* transform_window : transform_windows_) { - TransparentActivateWindowButton* activate_button = - transform_window->activate_button(); - - // If there is only one window in this, then expand the transparent overlay - // so that touch exploration in ChromVox only provides spoken feedback once - // within |this| selector item's bounds. - gfx::Rect bounds = transform_windows_.size() == 1 - ? target_bounds() : GetTransformedBounds(transform_window->window()); - activate_button->SetBounds(bounds); - activate_button->SetAccessibleName(transform_window->window()->title()); - } + selector_item_activate_window_button_->SetAccessibleName(window->title()); + + TransparentActivateWindowButton* activate_button = + transform_window_.activate_button(); + activate_button->SetBounds(target_bounds()); + activate_button->SetAccessibleName(window->title()); } void WindowSelectorItem::UpdateCloseButtonLayout( @@ -433,7 +343,7 @@ void WindowSelectorItem::UpdateCloseButtonLayout( gfx::Rect transformed_window_bounds = ScreenUtil::ConvertRectFromScreen( close_button_widget_.GetNativeWindow()->GetRootWindow(), - GetTransformedBounds(SelectionWindow())); + GetTransformedBounds(GetWindow())); gfx::Transform close_button_transform; close_button_transform.Translate(transformed_window_bounds.right(), @@ -445,13 +355,7 @@ void WindowSelectorItem::UpdateCloseButtonLayout( void WindowSelectorItem::UpdateCloseButtonAccessibilityName() { close_button_->SetAccessibleName(l10n_util::GetStringFUTF16( IDS_ASH_OVERVIEW_CLOSE_ITEM_BUTTON_ACCESSIBLE_NAME, - SelectionWindow()->title())); -} - -ScopedTransformOverviewWindow* - WindowSelectorItem::SelectionTransformWindow() const { - CHECK(!transform_windows_.empty()); - return transform_windows_.front(); + GetWindow()->title())); } } // namespace ash diff --git a/ash/wm/overview/window_selector_item.h b/ash/wm/overview/window_selector_item.h index 584d275..2af8c56 100644 --- a/ash/wm/overview/window_selector_item.h +++ b/ash/wm/overview/window_selector_item.h @@ -27,57 +27,38 @@ class Widget; namespace ash { -// This class represents an item in overview mode. An item can have one or more -// windows, of which only one can be activated by keyboard (i.e. alt+tab) but -// any can be selected with a pointer (touch or mouse). +// This class represents an item in overview mode. class ASH_EXPORT WindowSelectorItem : public views::ButtonListener, public aura::WindowObserver, public TransparentActivateWindowButtonDelegate { public: - explicit WindowSelectorItem(aura::Window* root_window); + explicit WindowSelectorItem(aura::Window* window); ~WindowSelectorItem() override; + aura::Window* GetWindow(); + // Returns the root window on which this item is shown. aura::Window* root_window() { return root_window_; } - // Adds a window to this selector item. Windows should be added in reverse - // visible order so that the transparent overlay ordering matches the visible - // ordering. Each |window| should have the same root window as |this| was - // instantiated with. - void AddWindow(aura::Window* window); - - // Returns true if the window selector item has |window| as a selectable - // window. - bool HasSelectableWindow(const aura::Window* window) const; - // Returns true if |target| is contained in this WindowSelectorItem. bool Contains(const aura::Window* target) const; - // Restores |window| on exiting window overview rather than returning it - // to its previous state. - void RestoreWindowOnExit(aura::Window* window); - - // Returns the |window| to activate on selecting of this item. - aura::Window* SelectionWindow() const; - - // Removes |window| from this item. Check empty() after calling this to see - // if the entire item is now empty. - void RemoveWindow(const aura::Window* window); + // Restores and animates the managed window to it's non overview mode state. + void RestoreWindow(); - // Returns true if this item has no more selectable windows (i.e. after - // calling RemoveWindow for the last contained window). - bool empty() const; + // Forces the managed window to be shown (ie not hidden or minimized) when + // calling RestoreWindow(). + void ShowWindowOnExit(); // Dispatched before beginning window overview. This will do any necessary // one time actions such as restoring minimized windows. void PrepareForOverview(); // Sets the bounds of this window selector item to |target_bounds| in the - // |root_window| root window. The bounds change will be animated as specified + // |root_window_| root window. The bounds change will be animated as specified // by |animation_type|. - void SetBounds(aura::Window* root_window, - const gfx::Rect& target_bounds, + void SetBounds(const gfx::Rect& target_bounds, OverviewAnimationType animation_type); // Recomputes the positions for the windows in this selection item. This is @@ -99,6 +80,7 @@ class ASH_EXPORT WindowSelectorItem void ButtonPressed(views::Button* sender, const ui::Event& event) override; // aura::WindowObserver: + void OnWindowDestroying(aura::Window* window) override; void OnWindowTitleChanged(aura::Window* window) override; // ash::TransparentActivateWindowButtonDelegate: @@ -107,13 +89,10 @@ class ASH_EXPORT WindowSelectorItem private: friend class WindowSelectorTest; - typedef ScopedVector<ScopedTransformOverviewWindow> TransformWindows; - // Sets the bounds of this selector's items to |target_bounds| in - // |root_window|. The bounds change will be animated as specified + // |root_window_|. The bounds change will be animated as specified // by |animation_type|. - void SetItemBounds(aura::Window* root_window, - const gfx::Rect& target_bounds, + void SetItemBounds(const gfx::Rect& target_bounds, OverviewAnimationType animation_type); // Changes the opacity of all the windows the item owns. @@ -139,9 +118,6 @@ class ASH_EXPORT WindowSelectorItem // Updates the close buttons accessibility name. void UpdateCloseButtonAccessibilityName(); - // Returns the ScopedTransformOverviewWindow to activate or close. - ScopedTransformOverviewWindow* SelectionTransformWindow() const; - // True if the item is being shown in the overview, false if it's being // filtered. bool dimmed_; @@ -149,6 +125,9 @@ class ASH_EXPORT WindowSelectorItem // The root window this item is being displayed on. aura::Window* root_window_; + // The contained Window's wrapper. + ScopedTransformOverviewWindow transform_window_; + // The target bounds this selector item is fit within. gfx::Rect target_bounds_; @@ -176,9 +155,6 @@ class ASH_EXPORT WindowSelectorItem scoped_ptr<TransparentActivateWindowButton> selector_item_activate_window_button_; - // List of all Windows added to this and their associated helper classes. - TransformWindows transform_windows_; - DISALLOW_COPY_AND_ASSIGN(WindowSelectorItem); }; diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index cd25675..c3eb4f8 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc @@ -55,9 +55,6 @@ namespace ash { namespace { -typedef std::vector<aura::Window*> WindowList; -typedef std::map<const aura::Window*, int> WindowIndexMap; - class NonActivatableActivationDelegate : public aura::client::ActivationDelegate { public: @@ -71,17 +68,6 @@ void CancelDrag(DragDropController* controller, bool* canceled) { } } -// Fills the |index_map| with (window*, list index) entries based on each -// windows index in the |windows| list. -void GetWindowIndexMap(const WindowList& windows, - WindowIndexMap* index_map) { - int index = 0; - for (auto window : windows) { - (*index_map)[window] = index; - ++index; - } -} - } // namespace class WindowSelectorTest : public test::AshTestBase { @@ -208,7 +194,7 @@ class WindowSelectorTest : public test::AshTestBase { WindowSelector* ws = ash::Shell::GetInstance()-> window_selector_controller()->window_selector_.get(); return ws->grid_list_[ws->selected_grid_index_]-> - SelectedWindow()->SelectionWindow(); + SelectedWindow()->GetWindow(); } bool selection_widget_active() { @@ -306,9 +292,7 @@ TEST_F(WindowSelectorTest, Basic) { EXPECT_EQ(text_filter_widget()->GetNativeWindow(), GetFocusedWindow()); EXPECT_FALSE(WindowsOverlapping(window1.get(), window2.get())); EXPECT_FALSE(WindowsOverlapping(window1.get(), panel1.get())); - // Panels 1 and 2 should still be overlapping being in a single selector - // item. - EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get())); + EXPECT_FALSE(WindowsOverlapping(panel1.get(), panel2.get())); // Clicking window 1 should activate it. ClickWindow(window1.get()); @@ -834,19 +818,15 @@ TEST_F(WindowSelectorTest, MultipleDisplays) { GetWindowItemsForRoot(1); // Window indices are based on top-down order. The reverse of our creation. - IsWindowAndCloseButtonInScreen(window1.get(), primary_window_items[2]); - IsWindowAndCloseButtonInScreen(window2.get(), primary_window_items[1]); - IsWindowAndCloseButtonInScreen(window3.get(), secondary_window_items[2]); - IsWindowAndCloseButtonInScreen(window4.get(), secondary_window_items[1]); + IsWindowAndCloseButtonInScreen(window1.get(), primary_window_items[3]); + IsWindowAndCloseButtonInScreen(window2.get(), primary_window_items[2]); + IsWindowAndCloseButtonInScreen(window3.get(), secondary_window_items[3]); + IsWindowAndCloseButtonInScreen(window4.get(), secondary_window_items[2]); - IsWindowAndCloseButtonInScreen(panel1.get(), primary_window_items[0]); + IsWindowAndCloseButtonInScreen(panel1.get(), primary_window_items[1]); IsWindowAndCloseButtonInScreen(panel2.get(), primary_window_items[0]); - IsWindowAndCloseButtonInScreen(panel3.get(), secondary_window_items[0]); + IsWindowAndCloseButtonInScreen(panel3.get(), secondary_window_items[1]); IsWindowAndCloseButtonInScreen(panel4.get(), secondary_window_items[0]); - - EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get())); - EXPECT_TRUE(WindowsOverlapping(panel3.get(), panel4.get())); - EXPECT_FALSE(WindowsOverlapping(panel1.get(), panel3.get())); } // Tests shutting down during overview. @@ -954,38 +934,6 @@ TEST_F(WindowSelectorTest, CreateLabelUnderWindow) { EXPECT_EQ(real_label_bounds, expected_label_bounds); } -// Tests that a label is created for the active panel in a group of panels in -// overview mode. -TEST_F(WindowSelectorTest, CreateLabelUnderPanel) { - scoped_ptr<aura::Window> panel1(CreatePanelWindow(gfx::Rect(0, 0, 100, 100))); - scoped_ptr<aura::Window> panel2(CreatePanelWindow(gfx::Rect(0, 0, 100, 100))); - base::string16 panel1_title = base::UTF8ToUTF16("My panel"); - base::string16 panel2_title = base::UTF8ToUTF16("Another panel"); - base::string16 updated_panel1_title = base::UTF8ToUTF16("WebDriver Torso"); - base::string16 updated_panel2_title = base::UTF8ToUTF16("Da panel"); - panel1->SetTitle(panel1_title); - panel2->SetTitle(panel2_title); - wm::ActivateWindow(panel1.get()); - ToggleOverview(); - WindowSelectorItem* window_item = GetWindowItemsForRoot(0).back(); - views::Label* label = GetLabelView(window_item); - // Has the label view been created? - ASSERT_TRUE(label); - - // Verify the label matches the active window title. - EXPECT_EQ(label->text(), panel1_title); - // Verify that updating the title also updates the label. - panel1->SetTitle(updated_panel1_title); - EXPECT_EQ(label->text(), updated_panel1_title); - // After destroying the first panel, the label should match the second panel. - panel1.reset(); - label = GetLabelView(window_item); - EXPECT_EQ(label->text(), panel2_title); - // Also test updating the title on the second panel. - panel2->SetTitle(updated_panel2_title); - EXPECT_EQ(label->text(), updated_panel2_title); -} - // Tests that overview updates the window positions if the display orientation // changes. TEST_F(WindowSelectorTest, DisplayOrientationChanged) { @@ -1164,53 +1112,6 @@ TEST_F(WindowSelectorTest, WindowOverviewHidesCalloutWidgets) { panel_manager->GetCalloutWidgetForPanel(panel2.get())->IsVisible()); } -// Tests that when panels are grouped that the close button only closes the -// currently active panel. After the removal window selection should still be -// active, and the label should have changed. Removing the last panel should -// cause selection to end. -TEST_F(WindowSelectorTest, CloseButtonOnPanels) { - scoped_ptr<views::Widget> widget1(CreatePanelWindowWidget( - gfx::Rect(0, 0, 300, 100))); - scoped_ptr<views::Widget> widget2(CreatePanelWindowWidget( - gfx::Rect(100, 0, 100, 100))); - aura::Window* window1 = widget1->GetNativeWindow(); - aura::Window* window2 = widget2->GetNativeWindow(); - base::string16 panel1_title = base::UTF8ToUTF16("Panel 1"); - base::string16 panel2_title = base::UTF8ToUTF16("Panel 2"); - window1->SetTitle(panel1_title); - window2->SetTitle(panel2_title); - wm::ActivateWindow(window1); - ToggleOverview(); - - gfx::RectF bounds1 = GetTransformedBoundsInRootWindow(window1); - gfx::Point point1(bounds1.top_right().x() - 1, bounds1.top_right().y() - 1); - ui::test::EventGenerator event_generator1(window1->GetRootWindow(), point1); - - EXPECT_FALSE(widget1->IsClosed()); - event_generator1.ClickLeftButton(); - EXPECT_TRUE(widget1->IsClosed()); - RunAllPendingInMessageLoop(); - EXPECT_TRUE(IsSelecting()); - WindowSelectorItem* window_item = GetWindowItemsForRoot(0).front(); - EXPECT_FALSE(window_item->empty()); - EXPECT_TRUE(window_item->Contains(window2)); - EXPECT_TRUE(GetCloseButton(window_item)->IsVisible()); - - - views::Label* label = GetLabelView(window_item); - EXPECT_EQ(label->text(), panel2_title); - - gfx::RectF bounds2 = GetTransformedBoundsInRootWindow(window2); - gfx::Point point2(bounds2.top_right().x() - 1, bounds2.top_right().y() - 1); - ui::test::EventGenerator event_generator2(window2->GetRootWindow(), point2); - - EXPECT_FALSE(widget2->IsClosed()); - event_generator2.ClickLeftButton(); - EXPECT_TRUE(widget2->IsClosed()); - RunAllPendingInMessageLoop(); - EXPECT_FALSE(IsSelecting()); -} - // Creates three windows and tests filtering them by title. TEST_F(WindowSelectorTest, BasicTextFiltering) { gfx::Rect bounds(0, 0, 100, 100); @@ -1349,85 +1250,4 @@ TEST_F(WindowSelectorTest, CancelOverviewOnTap) { EXPECT_FALSE(IsSelecting()); } -// Tests that the transparent overlays z-order matches the windows z-order. -TEST_F(WindowSelectorTest, PanelStackOrdering) { - gfx::Rect bounds1(0, 0, 100, 100); - gfx::Rect bounds2(10, 0, 100, 100); - gfx::Rect bounds3(20, 0, 100, 100); - scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds1)); - scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds2)); - scoped_ptr<aura::Window> panel3(CreatePanelWindow(bounds3)); - - wm::ActivateWindow(panel2.get()); - wm::ActivateWindow(panel3.get()); - wm::ActivateWindow(panel1.get()); - - WindowIndexMap z_order; - GetWindowIndexMap(panel1->parent()->children(), &z_order); - ASSERT_GT(z_order[panel1.get()], z_order[panel2.get()]); - ASSERT_GT(z_order[panel2.get()], z_order[panel3.get()]); - - WindowList mru_windows = ash::Shell::GetInstance()->mru_window_tracker()-> - BuildMruWindowList(); - WindowIndexMap mru_rank; - GetWindowIndexMap(mru_windows, &mru_rank); - ASSERT_LT(mru_rank[panel1.get()], mru_rank[panel3.get()]); - ASSERT_LT(mru_rank[panel3.get()], mru_rank[panel2.get()]); - - ToggleOverview(); - - gfx::Rect panel1_transformed_bounds( - gfx::ToEnclosingRect(GetTransformedTargetBounds(panel1.get()))); - gfx::Rect panel2_transformed_bounds( - gfx::ToEnclosingRect(GetTransformedTargetBounds(panel2.get()))); - gfx::Rect panel3_transformed_bounds( - gfx::ToEnclosingRect(GetTransformedTargetBounds(panel3.get()))); - - gfx::Rect target_rect(panel2_transformed_bounds); - target_rect.Intersect(panel3_transformed_bounds); - target_rect.Subtract(panel1_transformed_bounds); - gfx::Point tap_target(target_rect.CenterPoint()); - - ASSERT_TRUE(panel3_transformed_bounds.Contains(tap_target)); - - ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); - generator.GestureTapAt(tap_target); - EXPECT_EQ(panel2.get(), GetFocusedWindow()); -} - -// Tests that individual panels can be selected on a secondary display. -TEST_F(WindowSelectorTest, PanelSelectionOnSecondaryDisplay) { - if (!SupportsMultipleDisplays()) - return; - - UpdateDisplay("600x400,600x400"); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); - - gfx::Rect bounds1(700, 0, 100, 100); - gfx::Rect bounds2(710, 0, 100, 100); - scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds1)); - scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds2)); - - wm::ActivateWindow(panel2.get()); - wm::ActivateWindow(panel1.get()); - - WindowList mru_windows = ash::Shell::GetInstance()->mru_window_tracker()-> - BuildMruWindowList(); - WindowIndexMap mru_rank; - GetWindowIndexMap(mru_windows, &mru_rank); - ASSERT_LT(mru_rank[panel1.get()], mru_rank[panel2.get()]); - ASSERT_EQ(panel1.get(), GetFocusedWindow()); - - ToggleOverview(); - - gfx::Rect panel2_transformed_bounds( - gfx::ToEnclosingRect(GetTransformedBoundsInRootWindow(panel2.get()))); - gfx::Point tap_target(panel2_transformed_bounds.right() - 2, - panel2_transformed_bounds.bottom() - 2); - - ui::test::EventGenerator generator(root_windows[1]); - generator.GestureTapAt(tap_target); - EXPECT_EQ(panel2.get(), GetFocusedWindow()); -} - } // namespace ash diff --git a/ash/wm/panels/panel_layout_manager.cc b/ash/wm/panels/panel_layout_manager.cc index ccbf450..35219d5 100644 --- a/ash/wm/panels/panel_layout_manager.cc +++ b/ash/wm/panels/panel_layout_manager.cc @@ -15,6 +15,7 @@ #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" #include "ash/shell_window_ids.h" +#include "ash/wm/overview/window_selector_controller.h" #include "ash/wm/window_animations.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" @@ -464,6 +465,10 @@ void PanelLayoutManager::OnShelfIconPositionsChanged() { //////////////////////////////////////////////////////////////////////////////// // PanelLayoutManager, ash::ShellObserver implementation: +void PanelLayoutManager::OnOverviewModeEnded() { + Relayout(); +} + void PanelLayoutManager::OnShelfAlignmentChanged(aura::Window* root_window) { if (panel_container_->GetRootWindow() == root_window) Relayout(); @@ -599,7 +604,15 @@ void PanelLayoutManager::Relayout() { if (!shelf_ || !shelf_->shelf_widget()) return; - if (in_layout_) + // Suppress layouts during overview mode because changing window bounds + // interfered with overview mode animations. However, layouts need to be done + // when the WindowSelectorController is restoring minimized windows so that + // they actually become visible. + WindowSelectorController* window_selector_controller = + Shell::GetInstance()->window_selector_controller(); + if (in_layout_ || !window_selector_controller || + (window_selector_controller->IsSelecting() && + !window_selector_controller->IsRestoringMinimizedWindows())) return; base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); diff --git a/ash/wm/panels/panel_layout_manager.h b/ash/wm/panels/panel_layout_manager.h index dc258da..1a2dadb 100644 --- a/ash/wm/panels/panel_layout_manager.h +++ b/ash/wm/panels/panel_layout_manager.h @@ -95,6 +95,7 @@ class ASH_EXPORT PanelLayoutManager void OnShelfIconPositionsChanged() override; // Overridden from ShellObserver + void OnOverviewModeEnded() override; void OnShelfAlignmentChanged(aura::Window* root_window) override; // Overridden from aura::WindowObserver |