summaryrefslogtreecommitdiffstats
path: root/athena
diff options
context:
space:
mode:
authoroshima <oshima@chromium.org>2014-10-09 09:15:30 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-09 16:16:12 +0000
commitbb11c71d45fea38bab72ca28a6c44b19c7d9f564 (patch)
treeca47d3f94aa70299b3d36fd94165adc5d7462c86 /athena
parent17bfcf19eb55145a7886d4f9e52196b06f5d5100 (diff)
downloadchromium_src-bb11c71d45fea38bab72ca28a6c44b19c7d9f564.zip
chromium_src-bb11c71d45fea38bab72ca28a6c44b19c7d9f564.tar.gz
chromium_src-bb11c71d45fea38bab72ca28a6c44b19c7d9f564.tar.bz2
Handle transient children as a part of transient parent
Exclude transient children from window list. Introduced TransientGroupSetter to set the window property to all transient children. This CL depends on https://codereview.chromium.org/628413002/. BUG=410499 TEST=Updated WindowListProviderImplTest. Manual tests for animations: go to chrome://extensions, enable dev mode, and open file dialog. Go to overview mode, scroll, delete, select activity with file dialog. Review URL: https://codereview.chromium.org/633623002 Cr-Commit-Position: refs/heads/master@{#298890}
Diffstat (limited to 'athena')
-rw-r--r--athena/wm/public/window_list_provider.h4
-rw-r--r--athena/wm/test/window_manager_impl_test_api.cc1
-rw-r--r--athena/wm/window_list_provider_impl.cc62
-rw-r--r--athena/wm/window_list_provider_impl.h8
-rw-r--r--athena/wm/window_list_provider_impl_unittest.cc165
-rw-r--r--athena/wm/window_manager_impl.cc28
-rw-r--r--athena/wm/window_manager_impl.h4
-rw-r--r--athena/wm/window_overview_mode.cc209
8 files changed, 332 insertions, 149 deletions
diff --git a/athena/wm/public/window_list_provider.h b/athena/wm/public/window_list_provider.h
index 8790b1f..69560ea 100644
--- a/athena/wm/public/window_list_provider.h
+++ b/athena/wm/public/window_list_provider.h
@@ -29,10 +29,6 @@ class ATHENA_EXPORT WindowListProvider {
// Returns true if the |window| is part of the list.
virtual bool IsWindowInList(aura::Window* window) const = 0;
- // Returns true if the given window is a window which can be handled by the
- // WindowListProvider.
- virtual bool IsValidWindow(aura::Window* window) const = 0;
-
// Stacks a given |window| in direct front of a |reference_window|.
// Note: The |window| and |reference_window| has to be in the list already.
virtual void StackWindowFrontOf(aura::Window* window,
diff --git a/athena/wm/test/window_manager_impl_test_api.cc b/athena/wm/test/window_manager_impl_test_api.cc
index bf346f9..ef7a2cf 100644
--- a/athena/wm/test/window_manager_impl_test_api.cc
+++ b/athena/wm/test/window_manager_impl_test_api.cc
@@ -4,6 +4,7 @@
#include "athena/wm/test/window_manager_impl_test_api.h"
+#include "athena/wm/window_list_provider_impl.h"
#include "athena/wm/window_manager_impl.h"
namespace athena {
diff --git a/athena/wm/window_list_provider_impl.cc b/athena/wm/window_list_provider_impl.cc
index f684c41..a6aa781 100644
--- a/athena/wm/window_list_provider_impl.cc
+++ b/athena/wm/window_list_provider_impl.cc
@@ -6,41 +6,50 @@
#include <algorithm>
+#include "athena/athena_export.h"
#include "athena/wm/public/window_list_provider_observer.h"
#include "ui/aura/window.h"
+#include "ui/aura/window_property.h"
+#include "ui/wm/core/transient_window_manager.h"
+#include "ui/wm/core/window_util.h"
+
+DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(ATHENA_EXPORT, bool);
namespace athena {
+namespace {
+
+// Used to keep track of which window should be managed. This is necessary
+// as the necessary informatino used in IsValidWindow (transient parent
+// for example) may not available during destruction.
+DEFINE_WINDOW_PROPERTY_KEY(bool, kManagedKey, false);
+
+} // namespace
WindowListProviderImpl::WindowListProviderImpl(aura::Window* container)
: container_(container) {
CHECK(container_);
container_->AddObserver(this);
RecreateWindowList();
- std::for_each(window_list_.begin(), window_list_.end(),
- std::bind2nd(std::mem_fun(&aura::Window::AddObserver),
- this));
+ for (auto* window : window_list_)
+ window->AddObserver(this);
}
WindowListProviderImpl::~WindowListProviderImpl() {
// Remove all remaining window observers.
- for (aura::Window::Windows::const_iterator iter = window_list_.begin();
- iter != window_list_.end();
- ++iter) {
- CHECK(IsValidWindow(*iter));
- (*iter)->RemoveObserver(this);
+ for (auto* window : window_list_) {
+ CHECK(window->GetProperty(kManagedKey));
+ window->RemoveObserver(this);
}
container_->RemoveObserver(this);
}
-void WindowListProviderImpl::RecreateWindowList() {
- window_list_.clear();
- const aura::Window::Windows& container_children = container_->children();
- for (aura::Window::Windows::const_iterator iter = container_children.begin();
- iter != container_children.end();
- ++iter) {
- if (IsValidWindow(*iter))
- window_list_.push_back(*iter);
- }
+bool WindowListProviderImpl::IsValidWindow(aura::Window* window) const {
+ if (wm::GetTransientParent(window))
+ return false;
+
+ // TODO(oshima): crbug.com/413912.
+ return window->type() == ui::wm::WINDOW_TYPE_NORMAL ||
+ window->type() == ui::wm::WINDOW_TYPE_PANEL;
}
void WindowListProviderImpl::AddObserver(WindowListProviderObserver* observer) {
@@ -57,15 +66,10 @@ const aura::Window::Windows& WindowListProviderImpl::GetWindowList() const {
}
bool WindowListProviderImpl::IsWindowInList(aura::Window* window) const {
+ // TODO(oshima): Use kManagedKey specify which windows are managed.
return window->parent() == container_ && IsValidWindow(window);
}
-bool WindowListProviderImpl::IsValidWindow(aura::Window* window) const {
- // TODO(oshima): crbug.com/413912
- return window->type() == ui::wm::WINDOW_TYPE_NORMAL ||
- window->type() == ui::wm::WINDOW_TYPE_PANEL;
-}
-
void WindowListProviderImpl::StackWindowFrontOf(
aura::Window* window,
aura::Window* reference_window) {
@@ -84,16 +88,26 @@ void WindowListProviderImpl::StackWindowBehindTo(
container_->StackChildBelow(window, reference_window);
}
+void WindowListProviderImpl::RecreateWindowList() {
+ window_list_.clear();
+ for (auto* window : container_->children()) {
+ if (window->GetProperty(kManagedKey))
+ window_list_.push_back(window);
+ }
+}
+
void WindowListProviderImpl::OnWindowAdded(aura::Window* window) {
if (!IsValidWindow(window) || window->parent() != container_)
return;
+
+ window->SetProperty(kManagedKey, true);
RecreateWindowList();
DCHECK(IsWindowInList(window));
window->AddObserver(this);
}
void WindowListProviderImpl::OnWillRemoveWindow(aura::Window* window) {
- if (!IsValidWindow(window) || window->parent() != container_)
+ if (!window->GetProperty(kManagedKey))
return;
DCHECK(IsWindowInList(window));
aura::Window::Windows::iterator find = std::find(window_list_.begin(),
diff --git a/athena/wm/window_list_provider_impl.h b/athena/wm/window_list_provider_impl.h
index a686da2..ae1d956 100644
--- a/athena/wm/window_list_provider_impl.h
+++ b/athena/wm/window_list_provider_impl.h
@@ -6,6 +6,7 @@
#define ATHENA_WM_WINDOW_LIST_PROVIDER_IMPL_H_
#include "athena/wm/public/window_list_provider.h"
+#include "base/gtest_prod_util.h"
#include "ui/aura/window_observer.h"
namespace athena {
@@ -20,20 +21,21 @@ class ATHENA_EXPORT WindowListProviderImpl : public WindowListProvider,
explicit WindowListProviderImpl(aura::Window* container);
virtual ~WindowListProviderImpl();
- private:
- void RecreateWindowList();
+ bool IsValidWindow(aura::Window* window) const;
// WindowListProvider:
virtual void AddObserver(WindowListProviderObserver* observer) override;
virtual void RemoveObserver(WindowListProviderObserver* observer) override;
virtual const aura::Window::Windows& GetWindowList() const override;
virtual bool IsWindowInList(aura::Window* window) const override;
- virtual bool IsValidWindow(aura::Window* window) const override;
virtual void StackWindowFrontOf(aura::Window* window,
aura::Window*reference_window) override;
virtual void StackWindowBehindTo(aura::Window* window,
aura::Window*reference_window) override;
+ private:
+ void RecreateWindowList();
+
// aura::WindowObserver:
virtual void OnWindowAdded(aura::Window* new_window) override;
virtual void OnWillRemoveWindow(aura::Window* old_window) override;
diff --git a/athena/wm/window_list_provider_impl_unittest.cc b/athena/wm/window_list_provider_impl_unittest.cc
index 3419b2e..5b03d2d 100644
--- a/athena/wm/window_list_provider_impl_unittest.cc
+++ b/athena/wm/window_list_provider_impl_unittest.cc
@@ -6,10 +6,14 @@
#include <algorithm>
+#include "athena/screen/public/screen_manager.h"
#include "athena/test/base/athena_test_base.h"
#include "athena/wm/public/window_list_provider_observer.h"
+#include "athena/wm/public/window_manager.h"
+#include "ui/aura/client/window_tree_client.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
+#include "ui/wm/core/window_util.h"
namespace athena {
@@ -21,11 +25,26 @@ bool AreWindowListsEqual(const aura::Window::Windows& one,
std::equal(one.begin(), one.end(), two.begin());
}
-scoped_ptr<aura::Window> CreateWindow(aura::WindowDelegate* delegate,
+scoped_ptr<aura::Window> CreateWindow(aura::Window* parent,
+ aura::WindowDelegate* delegate,
ui::wm::WindowType window_type) {
scoped_ptr<aura::Window> window(new aura::Window(delegate));
window->SetType(window_type);
window->Init(aura::WINDOW_LAYER_SOLID_COLOR);
+ if (parent)
+ parent->AddChild(window.get());
+ return window.Pass();
+}
+
+scoped_ptr<aura::Window> CreateTransientWindow(aura::Window* transient_parent,
+ aura::WindowDelegate* delegate,
+ ui::wm::WindowType window_type) {
+ scoped_ptr<aura::Window> window(new aura::Window(delegate));
+ window->SetType(window_type);
+ window->Init(aura::WINDOW_LAYER_SOLID_COLOR);
+ wm::AddTransientChild(transient_parent, window.get());
+ aura::client::ParentWindowWithContext(
+ window.get(), ScreenManager::Get()->GetContext(), gfx::Rect());
return window.Pass();
}
@@ -94,24 +113,27 @@ typedef test::AthenaTestBase WindowListProviderImplTest;
TEST_F(WindowListProviderImplTest, StackingOrder) {
aura::test::TestWindowDelegate delegate;
scoped_ptr<aura::Window> container(new aura::Window(&delegate));
+ scoped_ptr<WindowListProvider> list_provider(
+ new WindowListProviderImpl(container.get()));
+
scoped_ptr<aura::Window> first =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
+ CreateWindow(container.get(), &delegate, ui::wm::WINDOW_TYPE_NORMAL);
scoped_ptr<aura::Window> second =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
+ CreateWindow(container.get(), &delegate, ui::wm::WINDOW_TYPE_NORMAL);
scoped_ptr<aura::Window> third =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
- container->AddChild(first.get());
- container->AddChild(second.get());
- container->AddChild(third.get());
+ CreateWindow(container.get(), &delegate, ui::wm::WINDOW_TYPE_NORMAL);
+
+ EXPECT_EQ(3u, container->children().size());
+ EXPECT_EQ(container->children().size(),
+ list_provider->GetWindowList().size());
- scoped_ptr<WindowListProvider> list_provider(
- new WindowListProviderImpl(container.get()));
EXPECT_TRUE(AreWindowListsEqual(container->children(),
list_provider->GetWindowList()));
container->StackChildAtTop(first.get());
EXPECT_TRUE(AreWindowListsEqual(container->children(),
list_provider->GetWindowList()));
+ EXPECT_EQ(3u, container->children().size());
EXPECT_EQ(first.get(), container->children().back());
}
@@ -119,21 +141,17 @@ TEST_F(WindowListProviderImplTest, StackingOrder) {
TEST_F(WindowListProviderImplTest, ListContainsOnlyNormalWindows) {
aura::test::TestWindowDelegate delegate;
scoped_ptr<aura::Window> container(new aura::Window(&delegate));
+ scoped_ptr<WindowListProvider> list_provider(
+ new WindowListProviderImpl(container.get()));
+
scoped_ptr<aura::Window> first =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
+ CreateWindow(container.get(), &delegate, ui::wm::WINDOW_TYPE_NORMAL);
scoped_ptr<aura::Window> second =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_POPUP);
+ CreateWindow(container.get(), &delegate, ui::wm::WINDOW_TYPE_POPUP);
scoped_ptr<aura::Window> third =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
+ CreateWindow(container.get(), &delegate, ui::wm::WINDOW_TYPE_NORMAL);
scoped_ptr<aura::Window> fourth =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_MENU);
- container->AddChild(first.get());
- container->AddChild(second.get());
- container->AddChild(third.get());
- container->AddChild(fourth.get());
-
- scoped_ptr<WindowListProvider> list_provider(
- new WindowListProviderImpl(container.get()));
+ CreateWindow(container.get(), &delegate, ui::wm::WINDOW_TYPE_MENU);
const aura::Window::Windows& list = list_provider->GetWindowList();
EXPECT_EQ(list.end(), std::find(list.begin(), list.end(), second.get()));
@@ -146,16 +164,15 @@ TEST_F(WindowListProviderImplTest, ListContainsOnlyNormalWindows) {
TEST_F(WindowListProviderImplTest, SimpleChecks) {
aura::test::TestWindowDelegate delegate;
scoped_ptr<aura::Window> container(new aura::Window(&delegate));
+ scoped_ptr<WindowListProviderImpl> list_provider(
+ new WindowListProviderImpl(container.get()));
scoped_ptr<aura::Window> normal_window =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
+ CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
scoped_ptr<aura::Window> popup_window =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_POPUP);
+ CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_POPUP);
scoped_ptr<aura::Window> menu_window =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_MENU);
-
- scoped_ptr<WindowListProvider> list_provider(
- new WindowListProviderImpl(container.get()));
+ CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_MENU);
// Check which windows are valid and which are not.
EXPECT_TRUE(list_provider->IsValidWindow(normal_window.get()));
@@ -176,19 +193,18 @@ TEST_F(WindowListProviderImplTest, SimpleChecks) {
TEST_F(WindowListProviderImplTest, TestWindowOrderingFunctions) {
aura::test::TestWindowDelegate delegate;
scoped_ptr<aura::Window> container(new aura::Window(&delegate));
-
- scoped_ptr<aura::Window> window1 =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
- scoped_ptr<aura::Window> window2 =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
- scoped_ptr<aura::Window> window3 =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
-
scoped_ptr<WindowListProvider> list_provider(
new WindowListProviderImpl(container.get()));
scoped_ptr<WindowListObserver> observer(
new WindowListObserver(list_provider.get()));
+ scoped_ptr<aura::Window> window1 =
+ CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
+ scoped_ptr<aura::Window> window2 =
+ CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
+ scoped_ptr<aura::Window> window3 =
+ CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
+
EXPECT_FALSE(list_provider->IsWindowInList(window1.get()));
EXPECT_FALSE(list_provider->IsWindowInList(window2.get()));
EXPECT_FALSE(list_provider->IsWindowInList(window3.get()));
@@ -244,26 +260,20 @@ TEST_F(WindowListProviderImplTest, TestWindowOrderingFunctions) {
TEST_F(WindowListProviderImplTest, TestWindowRemovalNotification) {
aura::test::TestWindowDelegate delegate;
scoped_ptr<aura::Window> container(new aura::Window(&delegate));
+ scoped_ptr<WindowListProvider> list_provider(
+ new WindowListProviderImpl(container.get()));
+ scoped_ptr<WindowListObserver> observer(
+ new WindowListObserver(list_provider.get()));
scoped_ptr<aura::Window> window1 =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
+ CreateWindow(container.get(), &delegate, ui::wm::WINDOW_TYPE_NORMAL);
scoped_ptr<aura::Window> window2 =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
+ CreateWindow(container.get(), &delegate, ui::wm::WINDOW_TYPE_NORMAL);
scoped_ptr<aura::Window> window3 =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL);
+ CreateWindow(container.get(), &delegate, ui::wm::WINDOW_TYPE_NORMAL);
scoped_ptr<aura::Window> window4 =
- CreateWindow(&delegate, ui::wm::WINDOW_TYPE_POPUP);
+ CreateWindow(container.get(), &delegate, ui::wm::WINDOW_TYPE_POPUP);
- scoped_ptr<WindowListProvider> list_provider(
- new WindowListProviderImpl(container.get()));
- scoped_ptr<WindowListObserver> observer(
- new WindowListObserver(list_provider.get()));
-
- // Add the windows.
- container->AddChild(window1.get());
- container->AddChild(window2.get());
- container->AddChild(window3.get());
- container->AddChild(window4.get());
// The popup-window (window4) should not be included in the window-list.
ASSERT_EQ(3U, list_provider->GetWindowList().size());
EXPECT_EQ(0, observer->window_removal_calls());
@@ -287,4 +297,63 @@ TEST_F(WindowListProviderImplTest, TestWindowRemovalNotification) {
EXPECT_EQ(3, observer->window_removal_calls());
}
+// Test that transient windows are handled property.
+TEST_F(WindowListProviderImplTest, TransientWindows) {
+ aura::test::TestWindowDelegate delegate;
+ delegate.set_can_focus(true);
+
+ WindowListProvider* list_provider =
+ WindowManager::Get()->GetWindowListProvider();
+
+ scoped_ptr<WindowListObserver> observer(
+ new WindowListObserver(list_provider));
+ scoped_ptr<aura::Window> w1 = CreateTestWindow(&delegate, gfx::Rect());
+ w1->Show();
+ scoped_ptr<aura::Window> w2 = CreateTestWindow(&delegate, gfx::Rect());
+ w2->Show();
+ scoped_ptr<aura::Window> t1 =
+ CreateTransientWindow(w1.get(), &delegate, ui::wm::WINDOW_TYPE_NORMAL);
+ t1->Show();
+
+ EXPECT_EQ(2u, list_provider->GetWindowList().size());
+
+ // Activation should honor transient relations.
+ wm::ActivateWindow(w2.get());
+ EXPECT_EQ(w1.get(), list_provider->GetWindowList()[0]);
+ EXPECT_EQ(w2.get(), list_provider->GetWindowList()[1]);
+
+ EXPECT_EQ(w1.get(), w1->parent()->children()[0]);
+ EXPECT_EQ(t1.get(), w1->parent()->children()[1]);
+ EXPECT_EQ(w2.get(), w1->parent()->children()[2]);
+
+ wm::ActivateWindow(w1.get());
+ EXPECT_EQ(w2.get(), w1->parent()->children()[0]);
+ EXPECT_EQ(w1.get(), w1->parent()->children()[1]);
+ EXPECT_EQ(t1.get(), w1->parent()->children()[2]);
+
+ // Manual operations should honor transient relations too.
+ // TODO(oshima): moving the active window back should activate the top window.
+ list_provider->StackWindowBehindTo(w1.get(), w2.get());
+ EXPECT_EQ(w1.get(), w1->parent()->children()[0]);
+ EXPECT_EQ(t1.get(), w1->parent()->children()[1]);
+ EXPECT_EQ(w2.get(), w1->parent()->children()[2]);
+
+ list_provider->StackWindowFrontOf(w1.get(), w2.get());
+ EXPECT_EQ(w2.get(), w1->parent()->children()[0]);
+ EXPECT_EQ(w1.get(), w1->parent()->children()[1]);
+ EXPECT_EQ(t1.get(), w1->parent()->children()[2]);
+
+ // Transient windows should follow the transient parent's
+ // visibility.
+ EXPECT_TRUE(t1->IsVisible());
+ w1->Hide();
+ EXPECT_FALSE(t1->IsVisible());
+ w1->Show();
+ EXPECT_TRUE(t1->IsVisible());
+
+ // Resetting transient window won't notify the observer.
+ t1.reset();
+ EXPECT_EQ(0, observer->window_removal_calls());
+}
+
} // namespace athena
diff --git a/athena/wm/window_manager_impl.cc b/athena/wm/window_manager_impl.cc
index 35722c1..92b6dda 100644
--- a/athena/wm/window_manager_impl.cc
+++ b/athena/wm/window_manager_impl.cc
@@ -23,6 +23,7 @@
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"
#include "ui/wm/core/shadow_controller.h"
+#include "ui/wm/core/transient_window_manager.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/core/wm_state.h"
#include "ui/wm/public/activation_client.h"
@@ -99,7 +100,14 @@ void AthenaContainerLayoutManager::OnWindowResized() {
}
void AthenaContainerLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
- if (!instance->window_list_provider_->IsWindowInList(child))
+ // TODO(oshima): Split view modes needs to take the transient window into
+ // account.
+ if (wm::GetTransientParent(child)) {
+ wm::TransientWindowManager::Get(child)
+ ->set_parent_controls_visibility(true);
+ }
+
+ if (!instance->window_list_provider_->IsValidWindow(child))
return;
if (instance->split_view_controller_->IsSplitViewModeActive() &&
@@ -240,10 +248,22 @@ void WindowManagerImpl::SetInOverview(bool active) {
void WindowManagerImpl::InstallAccelerators() {
const AcceleratorData accelerator_data[] = {
- {TRIGGER_ON_PRESS, ui::VKEY_F6, ui::EF_NONE, CMD_TOGGLE_OVERVIEW,
+ {TRIGGER_ON_PRESS,
+ ui::VKEY_F6,
+ ui::EF_NONE,
+ CMD_TOGGLE_OVERVIEW,
+ AF_NONE},
+ {TRIGGER_ON_PRESS,
+ ui::VKEY_F6,
+ ui::EF_CONTROL_DOWN,
+ CMD_TOGGLE_SPLIT_VIEW,
AF_NONE},
- {TRIGGER_ON_PRESS, ui::VKEY_F6, ui::EF_CONTROL_DOWN,
- CMD_TOGGLE_SPLIT_VIEW, AF_NONE},
+ // Debug
+ {TRIGGER_ON_PRESS,
+ ui::VKEY_6,
+ ui::EF_NONE,
+ CMD_TOGGLE_OVERVIEW,
+ AF_NONE | AF_DEBUG},
};
AcceleratorManager::Get()->RegisterAccelerators(
accelerator_data, arraysize(accelerator_data), this);
diff --git a/athena/wm/window_manager_impl.h b/athena/wm/window_manager_impl.h
index 2edd856..b5261f4 100644
--- a/athena/wm/window_manager_impl.h
+++ b/athena/wm/window_manager_impl.h
@@ -27,7 +27,7 @@ class WindowManagerImplTestApi;
class BezelController;
class SplitViewController;
-class WindowListProvider;
+class WindowListProviderImpl;
class WindowManagerObserver;
class ATHENA_EXPORT WindowManagerImpl : public WindowManager,
@@ -86,7 +86,7 @@ class ATHENA_EXPORT WindowManagerImpl : public WindowManager,
virtual void OnTitleDragCanceled(aura::Window* window) override;
scoped_ptr<aura::Window> container_;
- scoped_ptr<WindowListProvider> window_list_provider_;
+ scoped_ptr<WindowListProviderImpl> window_list_provider_;
scoped_ptr<WindowOverviewMode> overview_;
scoped_ptr<BezelController> bezel_controller_;
scoped_ptr<SplitViewController> split_view_controller_;
diff --git a/athena/wm/window_overview_mode.cc b/athena/wm/window_overview_mode.cc
index ce67744..0b16b6c 100644
--- a/athena/wm/window_overview_mode.cc
+++ b/athena/wm/window_overview_mode.cc
@@ -4,8 +4,7 @@
#include "athena/wm/window_overview_mode.h"
-#include <algorithm>
-#include <functional>
+#include <complex>
#include <vector>
#include "athena/wm/overview_toolbar.h"
@@ -13,7 +12,7 @@
#include "athena/wm/public/window_list_provider_observer.h"
#include "athena/wm/split_view_controller.h"
#include "base/bind.h"
-#include "base/macros.h"
+#include "base/memory/scoped_vector.h"
#include "ui/aura/scoped_window_targeter.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
@@ -31,11 +30,10 @@
#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/window_animations.h"
#include "ui/wm/core/window_util.h"
+#include "ui/wm/public/activation_client.h"
namespace {
-const float kOverviewDefaultScale = 0.75f;
-
struct WindowOverviewState {
// The current overview state of the window. 0.f means the window is at the
// topmost position. 1.f means the window is at the bottom-most position.
@@ -53,14 +51,17 @@ struct WindowOverviewState {
} // namespace
-DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*)
+DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*);
DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState,
kWindowOverviewState,
- NULL)
+ NULL);
+
namespace athena {
namespace {
+const float kOverviewDefaultScale = 0.75f;
+
gfx::Transform GetTransformForSplitWindow(aura::Window* window, float scale) {
const float kScrollWindowPositionInOverview = 0.65f;
int x_translate = window->bounds().width() * (1 - scale) / 2;
@@ -99,14 +100,102 @@ gfx::Transform GetTransformForState(aura::Window* window,
return transform;
}
-// Sets the progress-state for the window in the overview mode.
-void SetWindowProgress(aura::Window* window, float progress) {
- WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
- state->progress = progress;
+// A utility class used to set the transform/opacity to the window and
+// its transient children.
+class TransientGroupSetter {
+ public:
+ explicit TransientGroupSetter(aura::Window* window) : window_(window) {
+ }
+ ~TransientGroupSetter() {}
- gfx::Transform transform = GetTransformForState(window, state);
- window->SetTransform(transform);
-}
+ // Aborts all animations including its transient children.
+ void AbortAllAnimations() {
+ window_->layer()->GetAnimator()->AbortAllAnimations();
+ for (auto* transient_child : wm::GetTransientChildren(window_))
+ transient_child->layer()->GetAnimator()->AbortAllAnimations();
+ }
+
+ // Applys transform to the window and its transient children.
+ // Transient children gets a tranfrorm with the offset relateive
+ // it its transient parent.
+ void SetTransform(const gfx::Transform& transform) {
+ window_->SetTransform(transform);
+ for (auto* transient_child : wm::GetTransientChildren(window_)) {
+ gfx::Rect window_bounds = window_->bounds();
+ gfx::Rect child_bounds = transient_child->bounds();
+ gfx::Transform transient_window_transform(TranslateTransformOrigin(
+ child_bounds.origin() - window_bounds.origin(), transform));
+ transient_child->SetTransform(transient_window_transform);
+ }
+ }
+
+ // Sets the opacity to the window and its transient children.
+ void SetOpacity(float opacity) {
+ window_->layer()->SetOpacity(opacity);
+ for (auto* transient_child : wm::GetTransientChildren(window_)) {
+ transient_child->layer()->SetOpacity(opacity);
+ }
+ }
+
+ // Apply the transform with the overview scroll |progress|.
+ void SetWindowProgress(float progress) {
+ WindowOverviewState* state = window_->GetProperty(kWindowOverviewState);
+ state->progress = progress;
+
+ SetTransform(GetTransformForState(window_, state));
+ }
+
+ private:
+ static gfx::Transform TranslateTransformOrigin(
+ const gfx::Vector2d& new_origin,
+ const gfx::Transform& transform) {
+ gfx::Transform result;
+ result.Translate(-new_origin.x(), -new_origin.y());
+ result.PreconcatTransform(transform);
+ result.Translate(new_origin.x(), new_origin.y());
+ return result;
+ }
+
+ aura::Window* window_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransientGroupSetter);
+};
+
+// TransientGroupSetter with animation.
+class AnimateTransientGroupSetter : public TransientGroupSetter {
+ public:
+ explicit AnimateTransientGroupSetter(aura::Window* window)
+ : TransientGroupSetter(window) {
+ animation_settings_.push_back(CreateScopedLayerAnimationSettings(window));
+ for (auto* transient_child : wm::GetTransientChildren(window)) {
+ animation_settings_.push_back(
+ CreateScopedLayerAnimationSettings(transient_child));
+ }
+ }
+ ~AnimateTransientGroupSetter() {}
+
+ ui::ScopedLayerAnimationSettings* GetMainWindowAnimationSettings() {
+ CHECK(animation_settings_.size());
+ return animation_settings_[0];
+ }
+
+ private:
+ static ui::ScopedLayerAnimationSettings* CreateScopedLayerAnimationSettings(
+ aura::Window* window) {
+ const int kTransitionMs = 250;
+
+ ui::ScopedLayerAnimationSettings* settings =
+ new ui::ScopedLayerAnimationSettings(window->layer()->GetAnimator());
+ settings->SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ settings->SetTransitionDuration(
+ base::TimeDelta::FromMilliseconds(kTransitionMs));
+ return settings;
+ }
+
+ ScopedVector<ui::ScopedLayerAnimationSettings> animation_settings_;
+ DISALLOW_COPY_AND_ASSIGN(AnimateTransientGroupSetter);
+};
void HideWindowIfNotVisible(aura::Window* window,
SplitViewController* split_view_controller) {
@@ -115,7 +204,9 @@ void HideWindowIfNotVisible(aura::Window* window,
should_hide = window != split_view_controller->left_window() &&
window != split_view_controller->right_window();
} else {
- should_hide = !wm::IsActiveWindow(window);
+ aura::Window* active = aura::client::GetActivationClient(
+ window->GetRootWindow())->GetActiveWindow();
+ should_hide = active != window && wm::GetTransientParent(active) != window;
}
if (should_hide)
window->Hide();
@@ -126,18 +217,15 @@ void RestoreWindowState(aura::Window* window,
SplitViewController* split_view_controller) {
window->ClearProperty(kWindowOverviewState);
- 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)));
+ AnimateTransientGroupSetter setter(window);
- window->SetTransform(gfx::Transform());
+ setter.GetMainWindowAnimationSettings()->AddObserver(
+ new ui::ClosureAnimationObserver(
+ base::Bind(&HideWindowIfNotVisible, window, split_view_controller)));
+ setter.SetTransform(gfx::Transform());
// Reset the window opacity in case the user is dragging a window.
- window->layer()->SetOpacity(1.0f);
+ setter.SetOpacity(1.0f);
wm::SetShadowType(window, wm::SHADOW_TYPE_NONE);
}
@@ -156,19 +244,17 @@ void TransformSplitWindowScale(aura::Window* window, float scale) {
gfx::Transform transform = window->layer()->GetTargetTransform();
if (transform.Scale2d() == gfx::Vector2dF(scale, scale))
return;
- ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
- window->SetTransform(GetTransformForSplitWindow(window, scale));
+ AnimateTransientGroupSetter setter(window);
+ setter.SetTransform(GetTransformForSplitWindow(window, scale));
}
void AnimateWindowTo(aura::Window* animate_window,
aura::Window* target_window) {
- ui::ScopedLayerAnimationSettings settings(
- animate_window->layer()->GetAnimator());
- settings.SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ AnimateTransientGroupSetter setter(animate_window);
+
WindowOverviewState* target_state =
target_window->GetProperty(kWindowOverviewState);
- SetWindowProgress(animate_window, target_state->progress);
+ setter.SetWindowProgress(target_state->progress);
}
// Always returns the same target.
@@ -231,10 +317,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
window_list_provider_->GetWindowList();
if (windows.empty())
return;
- std::for_each(windows.begin(),
- windows.end(),
- std::bind2nd(std::ptr_fun(&RestoreWindowState),
- split_view_controller_));
+ for (auto* window : windows)
+ RestoreWindowState(window, split_view_controller_);
}
private:
@@ -314,20 +398,19 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
++index;
}
- scoped_refptr<ui::LayerAnimator> animator =
- window->layer()->GetAnimator();
+ TransientGroupSetter setter(window);
// Unset any in-progress animation.
- animator->AbortAllAnimations();
+ setter.AbortAllAnimations();
+
+ // Showing transient parent will show the transient children if any.
window->Show();
- window->SetTransform(gfx::Transform());
+
+ setter.SetTransform(gfx::Transform());
// Setup the animation.
{
- ui::ScopedLayerAnimationSettings settings(animator);
- settings.SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250));
- SetWindowProgress(window, progress);
+ AnimateTransientGroupSetter setter(window);
+ setter.SetWindowProgress(progress);
}
}
}
@@ -347,7 +430,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
targeter->FindTargetForLocatedEvent(container_, event));
while (target && target->parent() != container_)
target = target->parent();
- return target;
+ aura::Window* transient_parent = wm::GetTransientParent(target);
+ return transient_parent ? transient_parent : target;
}
// Scroll the window list by |delta_y| amount. |delta_y| is negative when
@@ -369,7 +453,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
// It is possible to scroll |window| up. Scroll it up, and update
// |delta_y_p| for the next window.
float apply = delta_y_p * state->progress;
- SetWindowProgress(window, std::max(0.f, state->progress - apply * 3));
+ TransientGroupSetter setter(window);
+ setter.SetWindowProgress(std::max(0.f, state->progress - apply * 3));
delta_y_p -= apply;
}
}
@@ -385,7 +470,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
if (1.f - state->progress > kEpsilon) {
// It is possible to scroll |window| down. Scroll it down, and update
// |delta_y_p| for the next window.
- SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p));
+ TransientGroupSetter setter(window);
+ setter.SetWindowProgress(std::min(1.f, state->progress + delta_y_p));
delta_y_p /= 2.f;
}
}
@@ -446,7 +532,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
gfx::Transform transform =
GetTransformForState(dragged_window_, dragged_state);
transform.Translate(-dragged_distance.x(), 0);
- dragged_window_->SetTransform(transform);
+ TransientGroupSetter setter(dragged_window_);
+ setter.SetTransform(transform);
// Update the toolbar.
const int kMinDistanceForActionButtons = 20;
@@ -488,11 +575,11 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
? 1
: gfx::Tween::FloatValueBetween(ratio, kMaxOpacity, kMinOpacity);
if (animate_opacity) {
- ui::ScopedLayerAnimationSettings settings(
- dragged_window_->layer()->GetAnimator());
- dragged_window_->layer()->SetOpacity(opacity);
+ AnimateTransientGroupSetter setter(dragged_window_);
+ setter.SetOpacity(opacity);
} else {
- dragged_window_->layer()->SetOpacity(opacity);
+ TransientGroupSetter setter(dragged_window_);
+ setter.SetOpacity(opacity);
}
if (split_view_controller_->IsSplitViewModeActive()) {
@@ -525,9 +612,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
void CloseDragWindow(const ui::GestureEvent& gesture) {
// Animate |dragged_window_| offscreen first, then destroy it.
{
- wm::ScopedHidingAnimationSettings settings(dragged_window_);
- settings.layer_animation_settings()->SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ AnimateTransientGroupSetter setter(dragged_window_);
WindowOverviewState* dragged_state =
dragged_window_->GetProperty(kWindowOverviewState);
@@ -541,8 +626,8 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
else
transform_x = -(transformed_bounds.x() + transformed_bounds.width());
transform.Translate(transform_x / kOverviewDefaultScale, 0);
- dragged_window_->SetTransform(transform);
- dragged_window_->layer()->SetOpacity(kMinOpacity);
+
+ setter.SetOpacity(kMinOpacity);
}
delete dragged_window_;
dragged_window_ = NULL;
@@ -554,13 +639,9 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
dragged_window_->GetProperty(kWindowOverviewState);
CHECK(dragged_state);
- ui::ScopedLayerAnimationSettings settings(
- dragged_window_->layer()->GetAnimator());
- settings.SetPreemptionStrategy(
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- dragged_window_->SetTransform(
- GetTransformForState(dragged_window_, dragged_state));
- dragged_window_->layer()->SetOpacity(1.f);
+ AnimateTransientGroupSetter setter(dragged_window_);
+ setter.SetTransform(GetTransformForState(dragged_window_, dragged_state));
+ setter.SetOpacity(1.0f);
dragged_window_ = NULL;
}