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); |
}; |