diff options
| author | Sadrul Habib Chowdhury <sadrul@chromium.org> | 2014-08-28 17:41:02 -0400 |
|---|---|---|
| committer | Sadrul Habib Chowdhury <sadrul@chromium.org> | 2014-08-28 21:45:06 +0000 |
| commit | 35e2f0861aa93d71fe5b59626f63088100635a40 (patch) | |
| tree | 1792e23bf4f081c94735b4bf47506b497a38a3f7 /athena/wm | |
| parent | 04e05b5d2a783d3e9a260db685b51e39a51039f2 (diff) | |
| download | chromium_src-35e2f0861aa93d71fe5b59626f63088100635a40.zip chromium_src-35e2f0861aa93d71fe5b59626f63088100635a40.tar.gz chromium_src-35e2f0861aa93d71fe5b59626f63088100635a40.tar.bz2 | |
athena: Fix overview mode for split-view mode.
The changes in this patch:
. If in split-view mode, the left and right windows remain fixed in the overview
state.
. Selecting either of the left/right windows returns to the split-view mode with
the same windows.
. Selecting one of the other windows in the stack gets out of split-view mode,
and switches to the selected window.
In subsequent patches:
. Allow dragging a window from the stack on top of the left/right windows to
switch that window and remain in split-view mode.
. Allow dragging one of the left/right windows to get out of split-view mode and
switch to that window.
BUG=404119
R=oshima@chromium.org
Review URL: https://codereview.chromium.org/495193003
Cr-Commit-Position: refs/heads/master@{#292468}
Diffstat (limited to 'athena/wm')
| -rw-r--r-- | athena/wm/test/window_manager_impl_test_api.h | 1 | ||||
| -rw-r--r-- | athena/wm/window_manager_impl.cc | 32 | ||||
| -rw-r--r-- | athena/wm/window_manager_unittest.cc | 20 | ||||
| -rw-r--r-- | athena/wm/window_overview_mode.cc | 73 | ||||
| -rw-r--r-- | athena/wm/window_overview_mode.h | 2 |
5 files changed, 113 insertions, 15 deletions
diff --git a/athena/wm/test/window_manager_impl_test_api.h b/athena/wm/test/window_manager_impl_test_api.h index 1876df3..77536ed 100644 --- a/athena/wm/test/window_manager_impl_test_api.h +++ b/athena/wm/test/window_manager_impl_test_api.h @@ -19,6 +19,7 @@ class WindowManagerImplTestApi { WindowManagerImplTestApi(); ~WindowManagerImplTestApi(); + athena::WindowManagerImpl* wm() { return wm_; } athena::WindowListProvider* GetWindowListProvider(); athena::SplitViewController* GetSplitViewController(); diff --git a/athena/wm/window_manager_impl.cc b/athena/wm/window_manager_impl.cc index 2131bc2..2b53961 100644 --- a/athena/wm/window_manager_impl.cc +++ b/athena/wm/window_manager_impl.cc @@ -182,7 +182,6 @@ void WindowManagerImpl::SetInOverview(bool active) { bezel_controller_->set_left_right_delegate( active ? NULL : split_view_controller_.get()); if (active) { - split_view_controller_->DeactivateSplitMode(); FOR_EACH_OBSERVER(WindowManagerObserver, observers_, OnOverviewModeEnter()); // Re-stack all windows in the order defined by window_list_provider_. @@ -191,9 +190,9 @@ void WindowManagerImpl::SetInOverview(bool active) { for (it = window_list.begin(); it != window_list.end(); ++it) container_->StackChildAtTop(*it); overview_ = WindowOverviewMode::Create( - container_.get(), window_list_provider_.get(), this); + container_.get(), window_list_provider_.get(), + split_view_controller_.get(), this); } else { - CHECK(!split_view_controller_->IsSplitViewModeActive()); overview_.reset(); FOR_EACH_OBSERVER(WindowManagerObserver, observers_, OnOverviewModeExit()); } @@ -219,8 +218,33 @@ void WindowManagerImpl::RemoveObserver(WindowManagerObserver* observer) { } void WindowManagerImpl::OnSelectWindow(aura::Window* window) { + if (split_view_controller_->IsSplitViewModeActive()) + split_view_controller_->DeactivateSplitMode(); wm::ActivateWindow(window); SetInOverview(false); + // If |window| does not have the size of the work-area, then make sure it is + // resized. + const gfx::Size work_area = + gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area().size(); + if (window->GetTargetBounds().size() != work_area) { + const gfx::Rect& window_bounds = window->bounds(); + const gfx::Rect desired_bounds(work_area); + gfx::Transform transform; + transform.Translate(desired_bounds.x() - window_bounds.x(), + desired_bounds.y() - window_bounds.y()); + transform.Scale(desired_bounds.width() / window_bounds.width(), + desired_bounds.height() / window_bounds.height()); + window->layer()->GetAnimator()->AbortAllAnimations(); + ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); + settings.SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + settings.AddObserver( + new ui::ClosureAnimationObserver(base::Bind(&SetWindowState, + base::Unretained(window), + desired_bounds, + gfx::Transform()))); + window->SetTransform(transform); + } } void WindowManagerImpl::OnSplitViewMode(aura::Window* left, @@ -347,7 +371,7 @@ void WindowManagerImpl::OnTitleDragCompleted(aura::Window* window) { transform.Translate(window->bounds().x() - next_window->bounds().x(), 0); next_window->SetTransform(transform); - OnSelectWindow(next_window); + wm::ActivateWindow(next_window); } window->Hide(); } diff --git a/athena/wm/window_manager_unittest.cc b/athena/wm/window_manager_unittest.cc index 8a331ca..54f22a5 100644 --- a/athena/wm/window_manager_unittest.cc +++ b/athena/wm/window_manager_unittest.cc @@ -315,4 +315,24 @@ TEST_F(WindowManagerTest, SplitModeActivationByShortcut) { EXPECT_EQ(width, w2->bounds().width()); } +TEST_F(WindowManagerTest, OverviewModeFromSplitMode) { + test::WindowManagerImplTestApi wm_api; + + aura::test::TestWindowDelegate delegate; + scoped_ptr<aura::Window> w1(CreateTestWindow(&delegate, gfx::Rect())); + scoped_ptr<aura::Window> w2(CreateTestWindow(&delegate, gfx::Rect())); + scoped_ptr<aura::Window> w3(CreateTestWindow(&delegate, gfx::Rect())); + + // Get into split-view mode, and then turn on overview mode. + wm_api.GetSplitViewController()->ActivateSplitMode(NULL, NULL); + WindowManager::GetInstance()->ToggleOverview(); + EXPECT_TRUE(wm_api.GetSplitViewController()->IsSplitViewModeActive()); + EXPECT_EQ(w3.get(), wm_api.GetSplitViewController()->left_window()); + EXPECT_EQ(w2.get(), wm_api.GetSplitViewController()->right_window()); + + WindowOverviewModeDelegate* overview_delegate = wm_api.wm(); + overview_delegate->OnSelectWindow(w1.get()); + EXPECT_FALSE(wm_api.GetSplitViewController()->IsSplitViewModeActive()); +} + } // namespace athena diff --git a/athena/wm/window_overview_mode.cc b/athena/wm/window_overview_mode.cc index b342293..080567f 100644 --- a/athena/wm/window_overview_mode.cc +++ b/athena/wm/window_overview_mode.cc @@ -10,6 +10,7 @@ #include "athena/wm/overview_toolbar.h" #include "athena/wm/public/window_list_provider.h" +#include "athena/wm/split_view_controller.h" #include "base/bind.h" #include "base/macros.h" #include "ui/aura/scoped_window_targeter.h" @@ -107,6 +108,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode, public: WindowOverviewModeImpl(aura::Window* container, const WindowListProvider* window_list_provider, + SplitViewController* split_view_controller, WindowOverviewModeDelegate* delegate) : container_(container), window_list_provider_(window_list_provider), @@ -115,9 +117,17 @@ class WindowOverviewModeImpl : public WindowOverviewMode, container, scoped_ptr<ui::EventTargeter>( new StaticWindowTargeter(container)))), - dragged_window_(NULL) { + dragged_window_(NULL), + split_({false, NULL, NULL}) { + CHECK(delegate_); container_->set_target_handler(this); + split_.enabled = split_view_controller->IsSplitViewModeActive(); + if (split_.enabled) { + split_.left = split_view_controller->left_window(); + split_.right = split_view_controller->right_window(); + } + // Prepare the desired transforms for all the windows, and set the initial // state on the windows. ComputeTerminalStatesForAllWindows(); @@ -149,6 +159,15 @@ class WindowOverviewModeImpl : public WindowOverviewMode, WindowOverviewState* state = new WindowOverviewState; window->SetProperty(kWindowOverviewState, state); + if (split_.enabled && (window == split_.left || window == split_.right)) { + // Do not let the left/right windows be scrolled. + int x_translate = window->bounds().width() * (1 - kMaxScale) / 2; + state->top.Translate(x_translate, window->bounds().height() * 0.65); + state->top.Scale(kMaxScale, kMaxScale); + state->bottom = state->top; + --index; + continue; + } UpdateTerminalStateForWindowAtIndex(window, index, windows.size()); } } @@ -185,14 +204,21 @@ class WindowOverviewModeImpl : public WindowOverviewMode, // Sets the initial position for the windows for the overview mode. void SetInitialWindowStates() { aura::Window::Windows windows = window_list_provider_->GetWindowList(); - size_t window_count = windows.size(); // The initial overview state of the topmost three windows. const float kInitialProgress[] = { 0.5f, 0.05f, 0.01f }; - for (size_t i = 0; i < window_count; ++i) { + size_t index = 0; + for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); + iter != windows.rend(); + ++iter) { float progress = 0.f; - aura::Window* window = windows[window_count - 1 - i]; - if (i < arraysize(kInitialProgress)) - progress = kInitialProgress[i]; + aura::Window* window = *iter; + if (split_.enabled && (window == split_.left || window == split_.right)) { + progress = 1; + } else { + if (index < arraysize(kInitialProgress)) + progress = kInitialProgress[index]; + ++index; + } scoped_refptr<ui::LayerAnimator> animator = window->layer()->GetAnimator(); @@ -273,7 +299,10 @@ class WindowOverviewModeImpl : public WindowOverviewMode, int GetScrollableHeight() const { const float kScrollableFraction = 0.65f; - return container_->bounds().height() * kScrollableFraction; + const float kScrollableFractionInSplit = 0.5f; + const float fraction = + split_.enabled ? kScrollableFractionInSplit : kScrollableFraction; + return container_->bounds().height() * fraction; } void CreateFlingerFor(const ui::GestureEvent& event) { @@ -441,13 +470,27 @@ class WindowOverviewModeImpl : public WindowOverviewMode, RestoreDragWindow(); } + void SelectWindow(aura::Window* window) { + if (!split_.enabled) { + delegate_->OnSelectWindow(window); + } else { + // If the selected window is one of the left/right windows, then keep the + // current state. + if (window == split_.left || window == split_.right) { + delegate_->OnSplitViewMode(split_.left, split_.right); + } else { + delegate_->OnSelectWindow(window); + } + } + } + // ui::EventHandler: virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE { if (mouse->type() == ui::ET_MOUSE_PRESSED) { aura::Window* select = SelectWindowAt(mouse); if (select) { mouse->SetHandled(); - delegate_->OnSelectWindow(select); + SelectWindow(select); } } else if (mouse->type() == ui::ET_MOUSEWHEEL) { DoScroll(static_cast<ui::MouseWheelEvent*>(mouse)->y_offset()); @@ -464,7 +507,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode, aura::Window* select = SelectWindowAt(gesture); if (select) { gesture->SetHandled(); - delegate_->OnSelectWindow(select); + SelectWindow(select); } } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) { if (std::abs(gesture->details().scroll_x_hint()) > @@ -518,7 +561,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode, const int kMinDistanceForDismissal = 300; const float kMinScale = 0.6f; - const float kMaxScale = 0.95f; + const float kMaxScale = 0.75f; const float kMaxOpacity = 1.0f; const float kMinOpacity = 0.2f; @@ -533,6 +576,12 @@ class WindowOverviewModeImpl : public WindowOverviewMode, gfx::Point dragged_start_location_; scoped_ptr<OverviewToolbar> overview_toolbar_; + struct { + bool enabled; + aura::Window* left; + aura::Window* right; + } split_; + DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); }; @@ -542,9 +591,11 @@ class WindowOverviewModeImpl : public WindowOverviewMode, scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( aura::Window* container, const WindowListProvider* window_list_provider, + SplitViewController* split_view_controller, WindowOverviewModeDelegate* delegate) { return scoped_ptr<WindowOverviewMode>( - new WindowOverviewModeImpl(container, window_list_provider, delegate)); + new WindowOverviewModeImpl(container, window_list_provider, + split_view_controller, delegate)); } } // namespace athena diff --git a/athena/wm/window_overview_mode.h b/athena/wm/window_overview_mode.h index 157b525..6597fea 100644 --- a/athena/wm/window_overview_mode.h +++ b/athena/wm/window_overview_mode.h @@ -9,6 +9,7 @@ #include "ui/aura/window.h" namespace athena { +class SplitViewController; class WindowListProvider; class WindowOverviewModeDelegate { @@ -31,6 +32,7 @@ class WindowOverviewMode { static scoped_ptr<WindowOverviewMode> Create( aura::Window* container, const WindowListProvider* window_list_provider, + SplitViewController* split_view_controller, WindowOverviewModeDelegate* delegate); }; |
