summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorbruthig <bruthig@chromium.org>2015-01-20 11:32:27 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-20 19:33:23 +0000
commitd7cf765b7add6a32fa2bb90e27587913f95c2339 (patch)
treeb20d4acedca105ffa00d16d52f933b3fe6f3ca6e /ash
parent2c5531593fc0d9a3032d28dbafe09b82458ceac3 (diff)
downloadchromium_src-d7cf765b7add6a32fa2bb90e27587913f95c2339.zip
chromium_src-d7cf765b7add6a32fa2bb90e27587913f95c2339.tar.gz
chromium_src-d7cf765b7add6a32fa2bb90e27587913f95c2339.tar.bz2
Change overview mode to so that docked panel windows are not grouped together.
BUG=448381 TEST=Manual Review URL: https://codereview.chromium.org/844763006 Cr-Commit-Position: refs/heads/master@{#312246}
Diffstat (limited to 'ash')
-rw-r--r--ash/ash.gyp2
-rw-r--r--ash/shell.cc4
-rw-r--r--ash/shell.h5
-rw-r--r--ash/shell_observer.h5
-rw-r--r--ash/system/overview/overview_button_tray.cc2
-rw-r--r--ash/system/overview/overview_button_tray.h2
-rw-r--r--ash/wm/maximize_mode/maximize_mode_window_manager.cc2
-rw-r--r--ash/wm/maximize_mode/maximize_mode_window_manager.h2
-rw-r--r--ash/wm/overview/scoped_transform_overview_window.cc68
-rw-r--r--ash/wm/overview/scoped_transform_overview_window.h15
-rw-r--r--ash/wm/overview/scoped_window_copy.cc175
-rw-r--r--ash/wm/overview/scoped_window_copy.h45
-rw-r--r--ash/wm/overview/transparent_activate_window_button.cc8
-rw-r--r--ash/wm/overview/transparent_activate_window_button.h3
-rw-r--r--ash/wm/overview/window_grid.cc72
-rw-r--r--ash/wm/overview/window_selector.cc91
-rw-r--r--ash/wm/overview/window_selector.h21
-rw-r--r--ash/wm/overview/window_selector_controller.cc11
-rw-r--r--ash/wm/overview/window_selector_controller.h4
-rw-r--r--ash/wm/overview/window_selector_item.cc200
-rw-r--r--ash/wm/overview/window_selector_item.h58
-rw-r--r--ash/wm/overview/window_selector_unittest.cc196
-rw-r--r--ash/wm/panels/panel_layout_manager.cc15
-rw-r--r--ash/wm/panels/panel_layout_manager.h1
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