| Index: athena/wm/window_overview_mode.cc
|
| diff --git a/athena/wm/window_overview_mode.cc b/athena/wm/window_overview_mode.cc
|
| index 7b3c73e0fc77156a093cf49fe34945a4f3cc8441..31712eea93d9164da304ccf934dacba4a9f2f5aa 100644
|
| --- a/athena/wm/window_overview_mode.cc
|
| +++ b/athena/wm/window_overview_mode.cc
|
| @@ -22,6 +22,7 @@
|
| #include "ui/compositor/closure_animation_observer.h"
|
| #include "ui/compositor/compositor.h"
|
| #include "ui/compositor/compositor_animation_observer.h"
|
| +#include "ui/compositor/layer_animation_observer.h"
|
| #include "ui/compositor/scoped_layer_animation_settings.h"
|
| #include "ui/events/event_handler.h"
|
| #include "ui/events/gestures/fling_curve.h"
|
| @@ -68,38 +69,46 @@ void SetWindowProgress(aura::Window* window, float progress) {
|
| window->SetTransform(GetTransformForState(state));
|
| }
|
|
|
| -void HideWindowIfNotVisible(aura::Window* window,
|
| - SplitViewController* split_view_controller) {
|
| - bool should_hide = true;
|
| - if (split_view_controller->IsSplitViewModeActive()) {
|
| - should_hide = window != split_view_controller->left_window() &&
|
| - window != split_view_controller->right_window();
|
| - } else {
|
| - should_hide = !wm::IsActiveWindow(window);
|
| - }
|
| - if (should_hide)
|
| +void HideWindowIfTransparent(aura::Window* window) {
|
| + if (window->layer()->opacity() == 0.0f) {
|
| window->Hide();
|
| + window->layer()->SetOpacity(1.0f);
|
| + }
|
| }
|
|
|
| // Resets the overview-related state for |window|.
|
| -void RestoreWindowState(aura::Window* window,
|
| - SplitViewController* split_view_controller) {
|
| +void RestoreWindowState(aura::Window* window) {
|
| window->ClearProperty(kWindowOverviewState);
|
| + wm::SetShadowType(window, wm::SHADOW_TYPE_NONE);
|
|
|
| - ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
|
| - settings.SetPreemptionStrategy(
|
| - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
|
| - settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250));
|
| -
|
| - settings.AddObserver(new ui::ClosureAnimationObserver(
|
| - base::Bind(&HideWindowIfNotVisible, window, split_view_controller)));
|
| + {
|
| + ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
|
| + settings.SetPreemptionStrategy(
|
| + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
|
| + settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250));
|
| + window->SetTransform(gfx::Transform());
|
| + }
|
|
|
| - window->SetTransform(gfx::Transform());
|
| + {
|
| + ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
|
| + settings.SetPreemptionStrategy(
|
| + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
|
| + settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250));
|
| + settings.AddObserver(new ui::ClosureAnimationObserver(
|
| + base::Bind(&HideWindowIfTransparent, base::Unretained(window))));
|
|
|
| - // Reset the window opacity in case the user is dragging a window.
|
| - window->layer()->SetOpacity(1.0f);
|
| + // The window opacity may not be 1.0f if the user was dragging a window.
|
| + window->layer()->SetOpacity(1.0f);
|
|
|
| - wm::SetShadowType(window, wm::SHADOW_TYPE_NONE);
|
| + // Ideally we would animate the window's visibility. However, animating the
|
| + // window's visibility causes the web contents to hide before the animation
|
| + // completes. Enqueue a zero duration opacity animation and hide |window| if
|
| + // the opacity animation is not aborted.
|
| + settings.SetPreemptionStrategy(
|
| + ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
|
| + settings.SetTransitionDuration(base::TimeDelta());
|
| + window->layer()->SetOpacity(0.0f);
|
| + }
|
| }
|
|
|
| gfx::RectF GetTransformedBounds(aura::Window* window) {
|
| @@ -167,7 +176,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
|
| container,
|
| scoped_ptr<ui::EventTargeter>(
|
| new StaticWindowTargeter(container)))),
|
| - dragged_window_(NULL) {
|
| + dragged_window_(NULL),
|
| + selected_window_(false) {
|
| CHECK(delegate_);
|
| container_->set_target_handler(this);
|
|
|
| @@ -180,12 +190,22 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
|
| virtual ~WindowOverviewModeImpl() {
|
| container_->set_target_handler(container_->delegate());
|
| RemoveAnimationObserver();
|
| +
|
| + // Abort any in progress animations. This can have significant consequences
|
| + // such as deleting one of |windows|.
|
| aura::Window::Windows windows = window_list_provider_->GetWindowList();
|
| + for (size_t i = 0; i < windows.size(); ++i)
|
| + windows[i]->layer()->GetAnimator()->AbortAllAnimations();
|
| +
|
| + windows = window_list_provider_->GetWindowList();
|
| if (windows.empty())
|
| return;
|
| - std::for_each(windows.begin(), windows.end(),
|
| - std::bind2nd(std::ptr_fun(&RestoreWindowState),
|
| - split_view_controller_));
|
| + std::for_each(windows.begin(), windows.end(), &RestoreWindowState);
|
| +
|
| + if (!selected_window_) {
|
| + aura::Window* to_select = *windows.rbegin();
|
| + SelectWindow(to_select, GetDefaultSplitType(to_select));
|
| + }
|
| }
|
|
|
| private:
|
| @@ -571,7 +591,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
|
| OverviewToolbar::ActionType action = overview_toolbar_->current_action();
|
| overview_toolbar_.reset();
|
| if (action == OverviewToolbar::ACTION_TYPE_SPLIT) {
|
| - delegate_->OnSplitViewMode(NULL, dragged_window_);
|
| + SelectWindow(dragged_window_,
|
| + WindowOverviewModeDelegate::SPLIT_RIGHT);
|
| return;
|
| }
|
|
|
| @@ -579,13 +600,11 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
|
| // then switch that window.
|
| aura::Window* split_drop = GetSplitWindowDropTarget(gesture);
|
| if (split_drop) {
|
| - aura::Window* left = split_view_controller_->left_window();
|
| - aura::Window* right = split_view_controller_->right_window();
|
| - if (left == split_drop)
|
| - left = dragged_window_;
|
| - else
|
| - right = dragged_window_;
|
| - delegate_->OnSplitViewMode(left, right);
|
| + WindowOverviewModeDelegate::SplitType split_type =
|
| + (split_view_controller_->left_window() == split_drop)
|
| + ? WindowOverviewModeDelegate::SPLIT_LEFT
|
| + : WindowOverviewModeDelegate::SPLIT_RIGHT;
|
| + SelectWindow(dragged_window_, split_type);
|
| return;
|
| }
|
|
|
| @@ -595,20 +614,23 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
|
| RestoreDragWindow();
|
| }
|
|
|
| - void SelectWindow(aura::Window* window) {
|
| - if (!split_view_controller_->IsSplitViewModeActive()) {
|
| - delegate_->OnSelectWindow(window);
|
| - } else {
|
| - // If the selected window is one of the left/right windows, then keep the
|
| - // current state.
|
| - if (window == split_view_controller_->left_window() ||
|
| - window == split_view_controller_->right_window()) {
|
| - delegate_->OnSplitViewMode(split_view_controller_->left_window(),
|
| - split_view_controller_->right_window());
|
| - } else {
|
| - delegate_->OnSelectWindow(window);
|
| - }
|
| + WindowOverviewModeDelegate::SplitType GetDefaultSplitType(
|
| + aura::Window* window) {
|
| + if (split_view_controller_->IsSplitViewModeActive()) {
|
| + // Do not exit split view if the split view's left/right window was
|
| + // selected.
|
| + if (window == split_view_controller_->left_window())
|
| + return WindowOverviewModeDelegate::SPLIT_LEFT;
|
| + else if (window == split_view_controller_->right_window())
|
| + return WindowOverviewModeDelegate::SPLIT_RIGHT;
|
| }
|
| + return WindowOverviewModeDelegate::SPLIT_NONE;
|
| + }
|
| +
|
| + void SelectWindow(aura::Window* window,
|
| + WindowOverviewModeDelegate::SplitType split_type) {
|
| + selected_window_ = true;
|
| + delegate_->OnSelectWindow(window, split_type);
|
| }
|
|
|
| // ui::EventHandler:
|
| @@ -617,7 +639,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
|
| aura::Window* select = SelectWindowAt(mouse);
|
| if (select) {
|
| mouse->SetHandled();
|
| - SelectWindow(select);
|
| + SelectWindow(select, GetDefaultSplitType(select));
|
| }
|
| } else if (mouse->type() == ui::ET_MOUSEWHEEL) {
|
| DoScroll(static_cast<ui::MouseWheelEvent*>(mouse)->y_offset());
|
| @@ -634,7 +656,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
|
| aura::Window* select = SelectWindowAt(gesture);
|
| if (select) {
|
| gesture->SetHandled();
|
| - SelectWindow(select);
|
| + SelectWindow(select, GetDefaultSplitType(select));
|
| }
|
| } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) {
|
| if (std::abs(gesture->details().scroll_x_hint()) >
|
| @@ -724,6 +746,9 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
|
| gfx::Point dragged_start_location_;
|
| scoped_ptr<OverviewToolbar> overview_toolbar_;
|
|
|
| + // Whether a window was selected.
|
| + bool selected_window_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl);
|
| };
|
|
|
|
|