diff options
author | skuhne <skuhne@chromium.org> | 2014-09-09 21:47:05 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-10 04:50:28 +0000 |
commit | 227733e374f946b4335ffd55938da4296057bedf (patch) | |
tree | b06e6e9d6cd5cdb33c79d883e1478d38f999b4ff /athena | |
parent | a1a1d99b8260260c13afcd4ba9d209f25f506bb9 (diff) | |
download | chromium_src-227733e374f946b4335ffd55938da4296057bedf.zip chromium_src-227733e374f946b4335ffd55938da4296057bedf.tar.gz chromium_src-227733e374f946b4335ffd55938da4296057bedf.tar.bz2 |
Adding functions to the window_list_provider for accessing the activities
window list
As discussed - added the window/activity order management functions
to the WindowListProvider and changed the use cases (at least partially).
There are still more things to do, but we might want to do that either
a. incrementally or
b. as a separate issue since the associated BUG(388085) has nothing to
do with this.
Note: This is more work - especially because the code in question is being
worked on actively by others.
BUG=407103
TEST=athena_unittest.SimpleChecks, athena_unittest.TestWindowOrderingFunctions
Review URL: https://codereview.chromium.org/480293003
Cr-Commit-Position: refs/heads/master@{#294103}
Diffstat (limited to 'athena')
-rw-r--r-- | athena/athena.gyp | 1 | ||||
-rw-r--r-- | athena/content/DEPS | 1 | ||||
-rw-r--r-- | athena/content/app_activity.cc | 9 | ||||
-rw-r--r-- | athena/content/app_activity_proxy.cc | 10 | ||||
-rw-r--r-- | athena/content/app_activity_registry.cc | 7 | ||||
-rw-r--r-- | athena/resource_manager/resource_manager_impl.cc | 20 | ||||
-rw-r--r-- | athena/wm/public/window_list_provider.h | 31 | ||||
-rw-r--r-- | athena/wm/public/window_list_provider_observer.h | 23 | ||||
-rw-r--r-- | athena/wm/public/window_manager.h | 5 | ||||
-rw-r--r-- | athena/wm/split_view_controller.cc | 8 | ||||
-rw-r--r-- | athena/wm/window_list_provider_impl.cc | 77 | ||||
-rw-r--r-- | athena/wm/window_list_provider_impl.h | 21 | ||||
-rw-r--r-- | athena/wm/window_list_provider_impl_unittest.cc | 163 | ||||
-rw-r--r-- | athena/wm/window_manager_impl.cc | 11 | ||||
-rw-r--r-- | athena/wm/window_manager_impl.h | 1 | ||||
-rw-r--r-- | athena/wm/window_manager_unittest.cc | 3 |
16 files changed, 362 insertions, 29 deletions
diff --git a/athena/athena.gyp b/athena/athena.gyp index 9a69a66..88b2c8d 100644 --- a/athena/athena.gyp +++ b/athena/athena.gyp @@ -107,6 +107,7 @@ 'wm/overview_toolbar.cc', 'wm/overview_toolbar.h', 'wm/public/window_list_provider.h', + 'wm/public/window_list_provider_observer.h', 'wm/public/window_manager.h', 'wm/public/window_manager_observer.h', 'wm/split_view_controller.cc', diff --git a/athena/content/DEPS b/athena/content/DEPS index 6bda5ed..4412db7 100644 --- a/athena/content/DEPS +++ b/athena/content/DEPS @@ -4,6 +4,7 @@ include_rules = [ "+athena/home/public", "+athena/input/public", "+athena/resource_manager/public", + "+athena/wm/public", "+components/renderer_context_menu", "+components/web_modal", "+content/public", diff --git a/athena/content/app_activity.cc b/athena/content/app_activity.cc index e557b61..2c7dc8b 100644 --- a/athena/content/app_activity.cc +++ b/athena/content/app_activity.cc @@ -7,6 +7,8 @@ #include "athena/activity/public/activity_manager.h" #include "athena/content/app_activity_registry.h" #include "athena/content/public/app_registry.h" +#include "athena/wm/public/window_list_provider.h" +#include "athena/wm/public/window_manager.h" #include "content/public/browser/web_contents.h" #include "ui/aura/window.h" #include "ui/views/controls/webview/webview.h" @@ -87,11 +89,12 @@ void AppActivity::Init() { DCHECK(app_activity_registry_); Activity* app_proxy = app_activity_registry_->unloaded_activity_proxy(); if (app_proxy) { - // TODO(skuhne): This should call the WindowListProvider to re-arrange. // Note: At this time the |AppActivity| did not get registered to the // |ResourceManager| - so we can move it around if needed. - aura::Window* proxy_window = app_proxy->GetWindow(); - proxy_window->parent()->StackChildBelow(GetWindow(), proxy_window); + WindowListProvider* window_list_provider = + WindowManager::GetInstance()->GetWindowListProvider(); + window_list_provider->StackWindowFrontOf(app_proxy->GetWindow(), + GetWindow()); Activity::Delete(app_proxy); // With the removal the object, the proxy should be deleted. DCHECK(!app_activity_registry_->unloaded_activity_proxy()); diff --git a/athena/content/app_activity_proxy.cc b/athena/content/app_activity_proxy.cc index a5ca0f4..bf08a59 100644 --- a/athena/content/app_activity_proxy.cc +++ b/athena/content/app_activity_proxy.cc @@ -5,6 +5,8 @@ #include "athena/content/app_activity_proxy.h" #include "athena/content/app_activity_registry.h" +#include "athena/wm/public/window_list_provider.h" +#include "athena/wm/public/window_manager.h" #include "ui/aura/window.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" @@ -58,10 +60,10 @@ aura::Window* AppActivityProxy::GetWindow() { void AppActivityProxy::Init() { DCHECK(replaced_activity_); - // TODO(skuhne): This should call the WindowListProvider to re-arrange. - // At this point we can move the Activity to its proper Activity location. - aura::Window* relative_window = replaced_activity_->GetWindow(); - relative_window->parent()->StackChildBelow(GetWindow(), relative_window); + WindowListProvider* window_list_provider = + WindowManager::GetInstance()->GetWindowListProvider(); + window_list_provider->StackWindowBehindTo(GetWindow(), + replaced_activity_->GetWindow()); // We moved. replaced_activity_ = NULL; } diff --git a/athena/content/app_activity_registry.cc b/athena/content/app_activity_registry.cc index 2af51ce..24505df 100644 --- a/athena/content/app_activity_registry.cc +++ b/athena/content/app_activity_registry.cc @@ -10,6 +10,8 @@ #include "athena/content/public/app_registry.h" #include "athena/extensions/public/extensions_delegate.h" #include "athena/resource_manager/public/resource_manager.h" +#include "athena/wm/public/window_list_provider.h" +#include "athena/wm/public/window_manager.h" #include "ui/aura/window.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" @@ -103,9 +105,10 @@ void AppActivityRegistry::RestartApplication(AppActivityProxy* proxy) { AppActivity* AppActivityRegistry::GetMruActivity() { DCHECK(activity_list_.size()); - // TODO(skuhne): This should be a query into the window manager. + WindowListProvider* window_list_provider = + WindowManager::GetInstance()->GetWindowListProvider(); const aura::Window::Windows children = - activity_list_[0]->GetWindow()->parent()->children(); + window_list_provider->GetWindowList(); // Find the first window in the container which is part of the application. for (aura::Window::Windows::const_iterator child_iterator = children.begin(); child_iterator != children.end(); ++child_iterator) { diff --git a/athena/resource_manager/resource_manager_impl.cc b/athena/resource_manager/resource_manager_impl.cc index 42351a0..4036ebc 100644 --- a/athena/resource_manager/resource_manager_impl.cc +++ b/athena/resource_manager/resource_manager_impl.cc @@ -12,12 +12,13 @@ #include "athena/activity/public/activity_manager_observer.h" #include "athena/resource_manager/memory_pressure_notifier.h" #include "athena/resource_manager/public/resource_manager_delegate.h" +#include "athena/wm/public/window_list_provider.h" +#include "athena/wm/public/window_list_provider_observer.h" #include "athena/wm/public/window_manager.h" #include "athena/wm/public/window_manager_observer.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "ui/aura/window.h" -#include "ui/aura/window_observer.h" namespace athena { @@ -25,7 +26,7 @@ class ResourceManagerImpl : public ResourceManager, public WindowManagerObserver, public ActivityManagerObserver, public MemoryPressureObserver, - public aura::WindowObserver { + public WindowListProviderObserver { public: ResourceManagerImpl(ResourceManagerDelegate* delegate); virtual ~ResourceManagerImpl(); @@ -63,8 +64,8 @@ class ResourceManagerImpl : public ResourceManager, MemoryPressureObserver::MemoryPressure pressure) OVERRIDE; virtual ResourceManagerDelegate* GetDelegate() OVERRIDE; - // aura::WindowObserver: - virtual void OnWindowStackingChanged(aura::Window* window) OVERRIDE; + // WindowListProviderObserver: + virtual void OnWindowStackingChanged() OVERRIDE; private: // Manage the resources for our activities. @@ -128,11 +129,13 @@ ResourceManagerImpl::ResourceManagerImpl(ResourceManagerDelegate* delegate) in_overview_mode_(false), in_splitview_mode_(false) { WindowManager::GetInstance()->AddObserver(this); + WindowManager::GetInstance()->GetWindowListProvider()->AddObserver(this); ActivityManager::Get()->AddObserver(this); } ResourceManagerImpl::~ResourceManagerImpl() { ActivityManager::Get()->RemoveObserver(this); + WindowManager::GetInstance()->GetWindowListProvider()->RemoveObserver(this); WindowManager::GetInstance()->RemoveObserver(this); while (!activity_list_.empty()) @@ -154,12 +157,10 @@ void ResourceManagerImpl::OnActivityStarted(Activity* activity) { ManageResource(); // Remember that the activity order has changed. activity_order_changed_ = true; - activity->GetWindow()->AddObserver(this); } void ResourceManagerImpl::OnActivityEnding(Activity* activity) { DCHECK(activity->GetWindow()); - activity->GetWindow()->RemoveObserver(this); // Remove the activity from the list again. std::vector<Activity*>::iterator it = std::find(activity_list_.begin(), activity_list_.end(), activity); @@ -192,9 +193,14 @@ void ResourceManagerImpl::OnSplitViewModeExit() { in_splitview_mode_ = false; } -void ResourceManagerImpl::OnWindowStackingChanged(aura::Window* window) { +void ResourceManagerImpl::OnWindowStackingChanged() { // TODO(skuhne): This needs to be changed to some WindowListProvider observer // if we decouple window order from activity order. + activity_order_changed_ = true; + if (pause_) { + queued_command_ = true; + return; + } // No need to do anything while being in overview mode. if (in_overview_mode_) diff --git a/athena/wm/public/window_list_provider.h b/athena/wm/public/window_list_provider.h index d22aa3d..b3083a9 100644 --- a/athena/wm/public/window_list_provider.h +++ b/athena/wm/public/window_list_provider.h @@ -10,13 +10,42 @@ namespace athena { +class WindowListProviderObserver; + // Interface for an ordered list of aura::Window objects. +// Note that lists returned by GetCurrentWindowList() will not change if any of +// the other member functions will be called later. class ATHENA_EXPORT WindowListProvider { public: virtual ~WindowListProvider() {} - // Returns an ordered list of windows. + // Adding/removing an observer to status changes. + virtual void AddObserver(WindowListProviderObserver* observer) = 0; + virtual void RemoveObserver(WindowListProviderObserver* observer) = 0; + + // Returns an ordered list of the current window configuration. virtual aura::Window::Windows GetWindowList() const = 0; + + // 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; + + // Moves a given |window| to the front of all windows of the window list. + // Note: The window has to be in the list already. + virtual void MoveToFront(aura::Window* window) = 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, + aura::Window* reference_window) = 0; + + // Stacks a given |window| directly behind a |reference_window|. + // Note: The |window| and |reference_window| has to be in the list already. + virtual void StackWindowBehindTo(aura::Window* window, + aura::Window* reference_window) = 0; }; } // namespace athena diff --git a/athena/wm/public/window_list_provider_observer.h b/athena/wm/public/window_list_provider_observer.h new file mode 100644 index 0000000..007f5aa --- /dev/null +++ b/athena/wm/public/window_list_provider_observer.h @@ -0,0 +1,23 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATHENA_WM_PUBLIC_WINDOW_LIST_PROVIDER_OBSERVER_H_ +#define ATHENA_WM_PUBLIC_WINDOW_LIST_PROVIDER_OBSERVER_H_ + +#include "athena/athena_export.h" + +namespace athena { + +// An observer to window list changes like e.g. stacking order has changed. +class ATHENA_EXPORT WindowListProviderObserver { + public: + virtual ~WindowListProviderObserver() {} + + // The Window stacking has changed. + virtual void OnWindowStackingChanged() = 0; +}; + +} // namespace athena + +#endif // ATHENA_WM_PUBLIC_WINDOW_LIST_PROVIDER_OBSERVER_H_ diff --git a/athena/wm/public/window_manager.h b/athena/wm/public/window_manager.h index afbd06d..ee8a2e5 100644 --- a/athena/wm/public/window_manager.h +++ b/athena/wm/public/window_manager.h @@ -9,6 +9,7 @@ namespace athena { +class WindowListProvider; class WindowManagerObserver; // Manages the application, web windows. @@ -30,6 +31,10 @@ class ATHENA_EXPORT WindowManager { virtual void RemoveObserver(WindowManagerObserver* observer) = 0; virtual void ToggleSplitViewForTest() = 0; + + // This returns the window list provider of the current MRU order of windows. + // The ownership remains with the WindowManager. + virtual WindowListProvider* GetWindowListProvider() = 0; }; } // namespace athena diff --git a/athena/wm/split_view_controller.cc b/athena/wm/split_view_controller.cc index 85db209..957b8c7 100644 --- a/athena/wm/split_view_controller.cc +++ b/athena/wm/split_view_controller.cc @@ -97,11 +97,15 @@ void SplitViewController::ActivateSplitMode(aura::Window* left, SetState(ACTIVE); if (right_window_ != right) { right_window_ = right; - container_->StackChildAtTop(right_window_); + // Since the |window_list_provider_| controls directly the order of windows, + // it needs to change the window order accordingly. + window_list_provider_->MoveToFront(right_window_); } if (left_window_ != left) { left_window_ = left; - container_->StackChildAtTop(left_window_); + // Since the |window_list_provider_| controls directly the order of windows, + // it needs to change the window order accordingly. + window_list_provider_->MoveToFront(left_window_); } UpdateLayout(true); } diff --git a/athena/wm/window_list_provider_impl.cc b/athena/wm/window_list_provider_impl.cc index 8b4cba5..6c6580f 100644 --- a/athena/wm/window_list_provider_impl.cc +++ b/athena/wm/window_list_provider_impl.cc @@ -4,6 +4,7 @@ #include "athena/wm/window_list_provider_impl.h" +#include "athena/wm/public/window_list_provider_observer.h" #include "ui/aura/window.h" namespace athena { @@ -11,9 +12,28 @@ namespace athena { WindowListProviderImpl::WindowListProviderImpl(aura::Window* container) : container_(container) { CHECK(container_); + container_->AddObserver(this); } WindowListProviderImpl::~WindowListProviderImpl() { + // Remove all remaining window observers. + 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)) + (*iter)->RemoveObserver(this); + } + container_->RemoveObserver(this); +} + +void WindowListProviderImpl::AddObserver(WindowListProviderObserver* observer) { + observers_.AddObserver(observer); +} + +void WindowListProviderImpl::RemoveObserver( + WindowListProviderObserver* observer) { + observers_.RemoveObserver(observer); } aura::Window::Windows WindowListProviderImpl::GetWindowList() const { @@ -22,10 +42,65 @@ aura::Window::Windows WindowListProviderImpl::GetWindowList() const { for (aura::Window::Windows::const_iterator iter = container_children.begin(); iter != container_children.end(); ++iter) { - if ((*iter)->type() == ui::wm::WINDOW_TYPE_NORMAL) + if (IsValidWindow(*iter)) list.push_back(*iter); } return list; } +bool WindowListProviderImpl::IsWindowInList(aura::Window* window) const { + return window->parent() == container_ && IsValidWindow(window); +} + +bool WindowListProviderImpl::IsValidWindow(aura::Window* window) const { + return window->type() == ui::wm::WINDOW_TYPE_NORMAL; +} + +void WindowListProviderImpl::MoveToFront(aura::Window* window) { + DCHECK(IsWindowInList(window)); + container_->StackChildAtTop(window); +} + +void WindowListProviderImpl::StackWindowFrontOf( + aura::Window* window, + aura::Window* reference_window) { + DCHECK_NE(window, reference_window); + DCHECK(IsWindowInList(window)); + DCHECK(IsWindowInList(reference_window)); + container_->StackChildAbove(window, reference_window); +} + +void WindowListProviderImpl::StackWindowBehindTo( + aura::Window* window, + aura::Window* reference_window) { + DCHECK_NE(window, reference_window); + DCHECK(IsWindowInList(window)); + DCHECK(IsWindowInList(reference_window)); + container_->StackChildBelow(window, reference_window); +} + +void WindowListProviderImpl::OnWindowAdded(aura::Window* window) { + if (!IsValidWindow(window) || window->parent() != container_) + return; + DCHECK(IsWindowInList(window)); + window->AddObserver(this); +} + +void WindowListProviderImpl::OnWillRemoveWindow(aura::Window* window) { + if (!IsValidWindow(window) || window->parent() != container_) + return; + DCHECK(IsWindowInList(window)); + window->RemoveObserver(this); +} + +void WindowListProviderImpl::OnWindowStackingChanged(aura::Window* window) { + if (window == container_) + return; + DCHECK(IsWindowInList(window)); + // Inform our listeners that the stacking has been changed. + FOR_EACH_OBSERVER(WindowListProviderObserver, + observers_, + OnWindowStackingChanged()); +} + } // namespace athena diff --git a/athena/wm/window_list_provider_impl.h b/athena/wm/window_list_provider_impl.h index a62507e..4049928 100644 --- a/athena/wm/window_list_provider_impl.h +++ b/athena/wm/window_list_provider_impl.h @@ -6,21 +6,40 @@ #define ATHENA_WM_WINDOW_LIST_PROVIDER_IMPL_H_ #include "athena/wm/public/window_list_provider.h" +#include "ui/aura/window_observer.h" namespace athena { +class WindowListProviderObserver; + // This implementation of the WindowListProviderImpl uses the same order as in // the container window's stacking order. -class ATHENA_EXPORT WindowListProviderImpl : public WindowListProvider { +class ATHENA_EXPORT WindowListProviderImpl : public WindowListProvider, + public aura::WindowObserver { public: explicit WindowListProviderImpl(aura::Window* container); virtual ~WindowListProviderImpl(); private: // WindowListProvider: + virtual void AddObserver(WindowListProviderObserver* observer) OVERRIDE; + virtual void RemoveObserver(WindowListProviderObserver* observer) OVERRIDE; virtual aura::Window::Windows GetWindowList() const OVERRIDE; + virtual bool IsWindowInList(aura::Window* window) const OVERRIDE; + virtual bool IsValidWindow(aura::Window* window) const OVERRIDE; + virtual void MoveToFront(aura::Window* window) OVERRIDE; + virtual void StackWindowFrontOf(aura::Window* window, + aura::Window*reference_window) OVERRIDE; + virtual void StackWindowBehindTo(aura::Window* window, + aura::Window*reference_window) OVERRIDE; + + // aura::WindowObserver: + virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE; + virtual void OnWillRemoveWindow(aura::Window* old_window) OVERRIDE; + virtual void OnWindowStackingChanged(aura::Window* window) OVERRIDE; aura::Window* container_; + ObserverList<WindowListProviderObserver> observers_; DISALLOW_COPY_AND_ASSIGN(WindowListProviderImpl); }; diff --git a/athena/wm/window_list_provider_impl_unittest.cc b/athena/wm/window_list_provider_impl_unittest.cc index eba6b7a..246b57c 100644 --- a/athena/wm/window_list_provider_impl_unittest.cc +++ b/athena/wm/window_list_provider_impl_unittest.cc @@ -7,6 +7,7 @@ #include <algorithm> #include "athena/test/athena_test_base.h" +#include "athena/wm/public/window_list_provider_observer.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/window.h" @@ -28,6 +29,56 @@ scoped_ptr<aura::Window> CreateWindow(aura::WindowDelegate* delegate, return window.Pass(); } +// Return a string which defines the order of windows in |now| using the indices +// of |original|. The string will then have the lowest/oldest window on the left +// and the highest / newest on the right. +std::string GetWindowOrder(const aura::Window::Windows& original, + const aura::Window::Windows& now) { + if (original.size() != now.size()) + return "size has changed."; + std::string output; + for (aura::Window::Windows::const_iterator it = now.begin(); + it != now.end(); ++it) { + for (size_t i = 0; i < original.size(); i++) { + if ((*it) == original[i]) { + output += (output.size() ? " " : std::string()) + + std::to_string(i + 1); + break; + } + } + } + return output; +} + +class WindowListObserver : public WindowListProviderObserver { + public: + explicit WindowListObserver(WindowListProvider* provider) + : calls_(0), + provider_(provider) { + provider_->AddObserver(this); + } + virtual ~WindowListObserver() { + provider_->RemoveObserver(this); + } + + int calls() const { return calls_; } + + // WindowListProviderObserver: + virtual void OnWindowStackingChanged() OVERRIDE { + calls_++; + } + + private: + // The number of calls to the observer. + int calls_; + + // The associated WindowListProvider which is observed. + WindowListProvider* provider_; + + DISALLOW_COPY_AND_ASSIGN(WindowListObserver); +}; + + } // namespace typedef test::AthenaTestBase WindowListProviderImplTest; @@ -58,6 +109,7 @@ TEST_F(WindowListProviderImplTest, StackingOrder) { EXPECT_EQ(first.get(), container->children().back()); } +// Tests that only normal windows of the associated container will be listed. TEST_F(WindowListProviderImplTest, ListContainsOnlyNormalWindows) { aura::test::TestWindowDelegate delegate; scoped_ptr<aura::Window> container(new aura::Window(&delegate)); @@ -76,6 +128,7 @@ TEST_F(WindowListProviderImplTest, ListContainsOnlyNormalWindows) { scoped_ptr<WindowListProvider> list_provider( new WindowListProviderImpl(container.get())); + const aura::Window::Windows list = list_provider->GetWindowList(); EXPECT_EQ(list.end(), std::find(list.begin(), list.end(), second.get())); EXPECT_EQ(list.end(), std::find(list.begin(), list.end(), fourth.get())); @@ -83,4 +136,114 @@ TEST_F(WindowListProviderImplTest, ListContainsOnlyNormalWindows) { EXPECT_NE(list.end(), std::find(list.begin(), list.end(), third.get())); } +// Testing that IsValidWidow, IsWindowInList and AddWindow work as expected. +TEST_F(WindowListProviderImplTest, SimpleChecks) { + aura::test::TestWindowDelegate delegate; + scoped_ptr<aura::Window> container(new aura::Window(&delegate)); + + scoped_ptr<aura::Window> normal_window = + CreateWindow(&delegate, ui::wm::WINDOW_TYPE_NORMAL); + scoped_ptr<aura::Window> popup_window = + CreateWindow(&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())); + + // Check which windows are valid and which are not. + EXPECT_TRUE(list_provider->IsValidWindow(normal_window.get())); + EXPECT_FALSE(list_provider->IsValidWindow(popup_window.get())); + EXPECT_FALSE(list_provider->IsValidWindow(menu_window.get())); + + // Check that no window is currently in the list. + EXPECT_FALSE(list_provider->IsWindowInList(normal_window.get())); + EXPECT_FALSE(list_provider->IsWindowInList(popup_window.get())); + EXPECT_FALSE(list_provider->IsWindowInList(menu_window.get())); + + // Check that adding the window will add it to the list. + container->AddChild(normal_window.get()); + EXPECT_TRUE(list_provider->IsWindowInList(normal_window.get())); +} + +// Testing that window ordering functions work as expected. +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())); + + EXPECT_FALSE(list_provider->IsWindowInList(window1.get())); + EXPECT_FALSE(list_provider->IsWindowInList(window2.get())); + EXPECT_FALSE(list_provider->IsWindowInList(window3.get())); + + // Add the windows. + container->AddChild(window1.get()); + container->AddChild(window2.get()); + container->AddChild(window3.get()); + aura::Window::Windows original_order = list_provider->GetWindowList(); + ASSERT_EQ(3U, original_order.size()); + EXPECT_EQ(original_order[0], window1.get()); + EXPECT_EQ(original_order[1], window2.get()); + EXPECT_EQ(original_order[2], window3.get()); + + EXPECT_EQ(0, observer.get()->calls()); + + // Move 2 to the front. + list_provider->MoveToFront(window2.get()); + EXPECT_EQ("1 3 2", GetWindowOrder(original_order, + list_provider->GetWindowList())); + EXPECT_EQ(1, observer->calls()); + + // Move 2 to the front again. Should not change anything. + list_provider->MoveToFront(window2.get()); + EXPECT_EQ("1 3 2", GetWindowOrder(original_order, + list_provider->GetWindowList())); + EXPECT_EQ(1, observer->calls()); + + // Move 1 (from the back) in front of 3. + list_provider->StackWindowFrontOf(window1.get(), window3.get()); + EXPECT_EQ("3 1 2", GetWindowOrder(original_order, + list_provider->GetWindowList())); + EXPECT_EQ(2, observer->calls()); + + // Move 2 (from the front) in front of 3. + list_provider->StackWindowFrontOf(window2.get(), window3.get()); + EXPECT_EQ("3 2 1", GetWindowOrder(original_order, + list_provider->GetWindowList())); + EXPECT_EQ(3, observer->calls()); + + // Move 1 (from the front) behind 3. + list_provider->StackWindowBehindTo(window1.get(), window3.get()); + EXPECT_EQ("1 3 2", GetWindowOrder(original_order, + list_provider->GetWindowList())); + EXPECT_EQ(4, observer->calls()); + + // Move 1 (from the back) in front of 2. + list_provider->StackWindowFrontOf(window1.get(), window2.get()); + EXPECT_EQ("3 2 1", GetWindowOrder(original_order, + list_provider->GetWindowList())); + EXPECT_EQ(5, observer->calls()); + + // Test that no change should also report no call. + list_provider->StackWindowFrontOf(window1.get(), window2.get()); + EXPECT_EQ("3 2 1", GetWindowOrder(original_order, + list_provider->GetWindowList())); + EXPECT_EQ(5, observer->calls()); + list_provider->StackWindowBehindTo(window2.get(), window1.get()); + EXPECT_EQ("3 2 1", GetWindowOrder(original_order, + list_provider->GetWindowList())); + EXPECT_EQ(5, observer->calls()); +} + } // namespace athena diff --git a/athena/wm/window_manager_impl.cc b/athena/wm/window_manager_impl.cc index c7b4b95..9797422 100644 --- a/athena/wm/window_manager_impl.cc +++ b/athena/wm/window_manager_impl.cc @@ -184,11 +184,8 @@ void WindowManagerImpl::SetInOverview(bool active) { if (active) { FOR_EACH_OBSERVER(WindowManagerObserver, observers_, OnOverviewModeEnter()); - // Re-stack all windows in the order defined by window_list_provider_. - aura::Window::Windows window_list = window_list_provider_->GetWindowList(); - aura::Window::Windows::iterator it; - for (it = window_list.begin(); it != window_list.end(); ++it) - container_->StackChildAtTop(*it); + // Note: The window_list_provider_ resembles the exact window list of the + // container, so no re-stacking is required before showing the OverviewMode. overview_ = WindowOverviewMode::Create( container_.get(), window_list_provider_.get(), split_view_controller_.get(), this); @@ -221,6 +218,10 @@ void WindowManagerImpl::ToggleSplitViewForTest() { ToggleSplitview(); } +WindowListProvider* WindowManagerImpl::GetWindowListProvider() { + return window_list_provider_.get(); +} + void WindowManagerImpl::OnSelectWindow(aura::Window* window) { if (split_view_controller_->IsSplitViewModeActive()) { split_view_controller_->DeactivateSplitMode(); diff --git a/athena/wm/window_manager_impl.h b/athena/wm/window_manager_impl.h index d741585..4895555 100644 --- a/athena/wm/window_manager_impl.h +++ b/athena/wm/window_manager_impl.h @@ -62,6 +62,7 @@ class WindowManagerImpl : public WindowManager, virtual void AddObserver(WindowManagerObserver* observer) OVERRIDE; virtual void RemoveObserver(WindowManagerObserver* observer) OVERRIDE; virtual void ToggleSplitViewForTest() OVERRIDE; + virtual WindowListProvider* GetWindowListProvider() OVERRIDE; // WindowOverviewModeDelegate: virtual void OnSelectWindow(aura::Window* window) OVERRIDE; diff --git a/athena/wm/window_manager_unittest.cc b/athena/wm/window_manager_unittest.cc index 4e3324f..8c22eb2 100644 --- a/athena/wm/window_manager_unittest.cc +++ b/athena/wm/window_manager_unittest.cc @@ -162,9 +162,6 @@ TEST_F(WindowManagerTest, BezelGestureToSwitchBetweenWindows) { EXPECT_TRUE(wm::IsActiveWindow(second.get())); EXPECT_EQ(second.get(), wm_api.GetWindowListProvider()->GetWindowList().back()); - EXPECT_FALSE(first->IsVisible()); - EXPECT_TRUE(second->IsVisible()); - EXPECT_FALSE(third->IsVisible()); } TEST_F(WindowManagerTest, TitleDragSwitchBetweenWindows) { |