summaryrefslogtreecommitdiffstats
path: root/athena/wm
diff options
context:
space:
mode:
authorSadrul Habib Chowdhury <sadrul@chromium.org>2014-08-28 17:41:02 -0400
committerSadrul Habib Chowdhury <sadrul@chromium.org>2014-08-28 21:45:06 +0000
commit35e2f0861aa93d71fe5b59626f63088100635a40 (patch)
tree1792e23bf4f081c94735b4bf47506b497a38a3f7 /athena/wm
parent04e05b5d2a783d3e9a260db685b51e39a51039f2 (diff)
downloadchromium_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.h1
-rw-r--r--athena/wm/window_manager_impl.cc32
-rw-r--r--athena/wm/window_manager_unittest.cc20
-rw-r--r--athena/wm/window_overview_mode.cc73
-rw-r--r--athena/wm/window_overview_mode.h2
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);
};