summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-18 23:57:05 +0000
committerjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-18 23:57:05 +0000
commitfc7b744c639fb4a9c25b1dbf5f7553166fdc1801 (patch)
treee3f486d62831674fddc60d6f05689dad8fba3a55 /ash
parentae6c59c831e325ea8cd45340e27acd75d5ddc4e5 (diff)
downloadchromium_src-fc7b744c639fb4a9c25b1dbf5f7553166fdc1801.zip
chromium_src-fc7b744c639fb4a9c25b1dbf5f7553166fdc1801.tar.gz
chromium_src-fc7b744c639fb4a9c25b1dbf5f7553166fdc1801.tar.bz2
Aura: Split out CompactLayoutManager from ToplevelLayoutManager
Move the shared code to BaseLayoutManager. Adjust the unit tests. Alice needs this for some compact mode work she's doing right now. BUG=110648 TEST=Run Aura in both --aura-window-mode=normal and --aura-window-mode=compact, both still start correctly. Also unit test coverage from CompactLayoutManagerTest and ToplevelLayoutManagerTest Review URL: https://chromiumcodereview.appspot.com/9255024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118186 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/ash.gyp6
-rw-r--r--ash/shell.cc9
-rw-r--r--ash/wm/base_layout_manager.cc128
-rw-r--r--ash/wm/base_layout_manager.h71
-rw-r--r--ash/wm/base_layout_manager_unittest.cc135
-rw-r--r--ash/wm/compact_layout_manager.cc68
-rw-r--r--ash/wm/compact_layout_manager.h60
-rw-r--r--ash/wm/compact_layout_manager_unittest.cc87
-rw-r--r--ash/wm/toplevel_layout_manager.cc110
-rw-r--r--ash/wm/toplevel_layout_manager.h51
-rw-r--r--ash/wm/toplevel_layout_manager_unittest.cc26
11 files changed, 585 insertions, 166 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp
index c03b884..67460cf 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -104,6 +104,10 @@
'wm/activation_controller.h',
'wm/always_on_top_controller.cc',
'wm/always_on_top_controller.h',
+ 'wm/base_layout_manager.cc',
+ 'wm/base_layout_manager.h',
+ 'wm/compact_layout_manager.cc',
+ 'wm/compact_layout_manager.h',
'wm/compact_status_area_layout_manager.cc',
'wm/compact_status_area_layout_manager.h',
'wm/default_container_event_filter.cc',
@@ -214,6 +218,8 @@
'test/test_suite.h',
'tooltips/tooltip_controller_unittest.cc',
'wm/activation_controller_unittest.cc',
+ 'wm/base_layout_manager_unittest.cc',
+ 'wm/compact_layout_manager_unittest.cc',
'wm/default_container_layout_manager_unittest.cc',
'wm/image_grid_unittest.cc',
'wm/system_modal_container_layout_manager_unittest.cc',
diff --git a/ash/shell.cc b/ash/shell.cc
index 3f5e218..40df7c9 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -18,6 +18,7 @@
#include "ash/shell_window_ids.h"
#include "ash/tooltips/tooltip_controller.h"
#include "ash/wm/activation_controller.h"
+#include "ash/wm/compact_layout_manager.h"
#include "ash/wm/compact_status_area_layout_manager.h"
#include "ash/wm/default_container_event_filter.h"
#include "ash/wm/default_container_layout_manager.h"
@@ -315,10 +316,10 @@ void Shell::InitLayoutManagers(aura::RootWindow* root_window) {
// desktop background, etc. The launcher still exists so we can use its
// data model and list of open windows, but we hide the UI to save space.
if (IsWindowModeCompact()) {
- internal::ToplevelLayoutManager* toplevel_layout_manager =
- new internal::ToplevelLayoutManager();
- default_container->SetLayoutManager(toplevel_layout_manager);
- toplevel_layout_manager->set_status_area_widget(status_widget);
+ internal::CompactLayoutManager* compact_layout_manager =
+ new internal::CompactLayoutManager();
+ default_container->SetLayoutManager(compact_layout_manager);
+ compact_layout_manager->set_status_area_widget(status_widget);
internal::CompactStatusAreaLayoutManager* status_area_layout_manager =
new internal::CompactStatusAreaLayoutManager(status_widget);
GetContainer(internal::kShellWindowId_StatusContainer)->
diff --git a/ash/wm/base_layout_manager.cc b/ash/wm/base_layout_manager.cc
new file mode 100644
index 0000000..7c78ec0
--- /dev/null
+++ b/ash/wm/base_layout_manager.cc
@@ -0,0 +1,128 @@
+// Copyright (c) 2012 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.
+
+#include "ash/wm/base_layout_manager.h"
+
+#include "ash/wm/property_util.h"
+#include "ash/wm/window_util.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/window.h"
+#include "ui/base/ui_base_types.h"
+#include "ui/gfx/screen.h"
+
+namespace ash {
+namespace internal {
+
+/////////////////////////////////////////////////////////////////////////////
+// BaseLayoutManager, public:
+
+BaseLayoutManager::BaseLayoutManager() {
+ aura::RootWindow::GetInstance()->AddRootWindowObserver(this);
+}
+
+BaseLayoutManager::~BaseLayoutManager() {
+ for (WindowSet::const_iterator i = windows_.begin(); i != windows_.end(); ++i)
+ (*i)->RemoveObserver(this);
+ aura::RootWindow::GetInstance()->RemoveRootWindowObserver(this);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// BaseLayoutManager, LayoutManager overrides:
+
+void BaseLayoutManager::OnWindowResized() {
+}
+
+void BaseLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
+ windows_.insert(child);
+ child->AddObserver(this);
+ if (child->GetProperty(aura::client::kShowStateKey)) {
+ UpdateBoundsFromShowState(child);
+ }
+}
+
+void BaseLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
+ windows_.erase(child);
+ child->RemoveObserver(this);
+}
+
+void BaseLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
+ bool visibile) {
+}
+
+void BaseLayoutManager::SetChildBounds(aura::Window* child,
+ const gfx::Rect& requested_bounds) {
+ gfx::Rect child_bounds(requested_bounds);
+ // Avoid a janky resize on startup by ensuring the initial bounds fill the
+ // screen.
+ if (window_util::IsWindowMaximized(child))
+ child_bounds = gfx::Screen::GetMonitorWorkAreaNearestWindow(child);
+ else if (window_util::IsWindowFullscreen(child))
+ child_bounds = gfx::Screen::GetMonitorAreaNearestWindow(child);
+ SetChildBoundsDirect(child, child_bounds);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// BaseLayoutManager, RootWindowObserver overrides:
+
+void BaseLayoutManager::OnRootWindowResized(const gfx::Size& new_size) {
+ // If a user plugs an external monitor into a laptop running Aura the
+ // monitor size will change. Maximized windows need to resize to match.
+ // We also do this when developers running Aura on a desktop manually resize
+ // the host window.
+ for (WindowSet::const_iterator it = windows_.begin();
+ it != windows_.end();
+ ++it) {
+ aura::Window* window = *it;
+ // The work area may be smaller than the full screen.
+ gfx::Rect monitor_rect = window_util::IsWindowFullscreen(window) ?
+ gfx::Screen::GetMonitorAreaNearestWindow(window) :
+ gfx::Screen::GetMonitorWorkAreaNearestWindow(window);
+ // Put as much of the window as possible within the monitor area.
+ window->SetBounds(window->bounds().AdjustToFit(monitor_rect));
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// BaseLayoutManager, WindowObserver overrides:
+
+void BaseLayoutManager::OnWindowPropertyChanged(aura::Window* window,
+ const char* name,
+ void* old) {
+ if (name == aura::client::kShowStateKey) {
+ UpdateBoundsFromShowState(window);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseLayoutManager, private:
+
+void BaseLayoutManager::UpdateBoundsFromShowState(aura::Window* window) {
+ switch (window->GetIntProperty(aura::client::kShowStateKey)) {
+ case ui::SHOW_STATE_NORMAL: {
+ const gfx::Rect* restore = GetRestoreBounds(window);
+ window->SetProperty(aura::client::kRestoreBoundsKey, NULL);
+ if (restore)
+ window->SetBounds(*restore);
+ delete restore;
+ break;
+ }
+
+ case ui::SHOW_STATE_MAXIMIZED:
+ SetRestoreBoundsIfNotSet(window);
+ window->SetBounds(gfx::Screen::GetMonitorWorkAreaNearestWindow(window));
+ break;
+
+ case ui::SHOW_STATE_FULLSCREEN:
+ SetRestoreBoundsIfNotSet(window);
+ window->SetBounds(gfx::Screen::GetMonitorAreaNearestWindow(window));
+ break;
+
+ default:
+ break;
+ }
+}
+
+} // namespace internal
+} // namespace ash
diff --git a/ash/wm/base_layout_manager.h b/ash/wm/base_layout_manager.h
new file mode 100644
index 0000000..4ceb82e
--- /dev/null
+++ b/ash/wm/base_layout_manager.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2012 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 ASH_WM_BASE_LAYOUT_MANAGER_H_
+#define ASH_WM_BASE_LAYOUT_MANAGER_H_
+#pragma once
+
+#include <set>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ui/aura/layout_manager.h"
+#include "ui/aura/root_window_observer.h"
+#include "ui/aura/window_observer.h"
+#include "ash/ash_export.h"
+
+namespace aura {
+class Window;
+}
+
+namespace ash {
+namespace internal {
+
+// BaseLayoutManager is the simplest possible implementation for a window
+// layout manager. It listens for changes to kShowStateKey and resizes the
+// window appropriately. Subclasses should be sure to invoke the base class
+// for adding and removing windows, otherwise show state will not be tracked
+// properly.
+class ASH_EXPORT BaseLayoutManager : public aura::LayoutManager,
+ public aura::RootWindowObserver,
+ public aura::WindowObserver {
+ public:
+ typedef std::set<aura::Window*> WindowSet;
+
+ BaseLayoutManager();
+ virtual ~BaseLayoutManager();
+
+ const WindowSet& windows() const { return windows_; }
+
+ // LayoutManager overrides:
+ virtual void OnWindowResized() OVERRIDE;
+ virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE;
+ virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE;
+ virtual void OnChildWindowVisibilityChanged(aura::Window* child,
+ bool visibile) OVERRIDE;
+ virtual void SetChildBounds(aura::Window* child,
+ const gfx::Rect& requested_bounds) OVERRIDE;
+
+ // RootWindowObserver overrides:
+ virtual void OnRootWindowResized(const gfx::Size& new_size) OVERRIDE;
+
+ // WindowObserver overrides:
+ virtual void OnWindowPropertyChanged(aura::Window* window,
+ const char* name,
+ void* old) OVERRIDE;
+
+ private:
+ // Update window bounds based on a change in show state.
+ void UpdateBoundsFromShowState(aura::Window* window);
+
+ // Set of windows we're listening to.
+ WindowSet windows_;
+
+ DISALLOW_COPY_AND_ASSIGN(BaseLayoutManager);
+};
+
+} // namespace ash
+} // namespace internal
+
+#endif // ASH_WM_BASE_LAYOUT_MANAGER_H_
diff --git a/ash/wm/base_layout_manager_unittest.cc b/ash/wm/base_layout_manager_unittest.cc
new file mode 100644
index 0000000..6e16543
--- /dev/null
+++ b/ash/wm/base_layout_manager_unittest.cc
@@ -0,0 +1,135 @@
+// Copyright (c) 2012 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.
+
+#include "ash/wm/base_layout_manager.h"
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/screen_aura.h"
+#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/test_windows.h"
+#include "ui/base/ui_base_types.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+
+namespace {
+
+class BaseLayoutManagerTest : public aura::test::AuraTestBase {
+ public:
+ BaseLayoutManagerTest() : layout_manager_(NULL) {}
+ virtual ~BaseLayoutManagerTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ aura::test::AuraTestBase::SetUp();
+ aura::RootWindow::GetInstance()->screen()->set_work_area_insets(
+ gfx::Insets(1, 2, 3, 4));
+ aura::RootWindow::GetInstance()->SetHostSize(gfx::Size(800, 600));
+ container_.reset(new aura::Window(NULL));
+ container_->Init(ui::Layer::LAYER_HAS_NO_TEXTURE);
+ container_->SetBounds(gfx::Rect(0, 0, 500, 500));
+ layout_manager_ = new internal::BaseLayoutManager();
+ container_->SetLayoutManager(layout_manager_);
+ }
+
+ aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
+ return aura::test::CreateTestWindowWithBounds(bounds, container_.get());
+ }
+
+ private:
+ // Owned by |container_|.
+ internal::BaseLayoutManager* layout_manager_;
+
+ scoped_ptr<aura::Window> container_;
+
+ DISALLOW_COPY_AND_ASSIGN(BaseLayoutManagerTest);
+};
+
+} // namespace
+
+// Tests normal->maximize->normal.
+TEST_F(BaseLayoutManagerTest, Maximize) {
+ gfx::Rect bounds(100, 100, 200, 200);
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
+ // Maximized window fills the work area, not the whole monitor.
+ EXPECT_EQ(gfx::Screen::GetMonitorWorkAreaNearestWindow(window.get()),
+ window->bounds());
+ window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+ EXPECT_EQ(bounds, window->bounds());
+}
+
+// Tests maximized window size during root window resize.
+TEST_F(BaseLayoutManagerTest, MaximizeRootWindowResize) {
+ gfx::Rect bounds(100, 100, 200, 200);
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
+ EXPECT_EQ(gfx::Screen::GetMonitorWorkAreaNearestWindow(window.get()),
+ window->bounds());
+ // Enlarge the root window. We should still match the work area size.
+ aura::RootWindow::GetInstance()->SetHostSize(gfx::Size(800, 600));
+ EXPECT_EQ(gfx::Screen::GetMonitorWorkAreaNearestWindow(window.get()),
+ window->bounds());
+}
+
+// Tests normal->fullscreen->normal.
+TEST_F(BaseLayoutManagerTest, Fullscreen) {
+ gfx::Rect bounds(100, 100, 200, 200);
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ window->SetIntProperty(aura::client::kShowStateKey,
+ ui::SHOW_STATE_FULLSCREEN);
+ // Fullscreen window fills the whole monitor.
+ EXPECT_EQ(gfx::Screen::GetMonitorAreaNearestWindow(window.get()),
+ window->bounds());
+ window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+ EXPECT_EQ(bounds, window->bounds());
+}
+
+// Tests fullscreen window size during root window resize.
+TEST_F(BaseLayoutManagerTest, FullscreenRootWindowResize) {
+ gfx::Rect bounds(100, 100, 200, 200);
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ // Fullscreen window fills the whole monitor.
+ window->SetIntProperty(aura::client::kShowStateKey,
+ ui::SHOW_STATE_FULLSCREEN);
+ EXPECT_EQ(gfx::Screen::GetMonitorAreaNearestWindow(window.get()),
+ window->bounds());
+ // Enlarge the root window. We should still match the monitor size.
+ aura::RootWindow::GetInstance()->SetHostSize(gfx::Size(800, 600));
+ EXPECT_EQ(gfx::Screen::GetMonitorAreaNearestWindow(window.get()),
+ window->bounds());
+}
+
+// Tests that when the screen gets smaller the windows aren't bigger than
+// the screen.
+TEST_F(BaseLayoutManagerTest, RootWindowResizeShrinksWindows) {
+ scoped_ptr<aura::Window> window(
+ CreateTestWindow(gfx::Rect(10, 20, 500, 400)));
+ gfx::Rect work_area = gfx::Screen::GetMonitorAreaNearestWindow(window.get());
+ // Invariant: Window is smaller than work area.
+ EXPECT_LE(window->bounds().width(), work_area.width());
+ EXPECT_LE(window->bounds().height(), work_area.height());
+
+ // Make the root window narrower than our window.
+ aura::RootWindow::GetInstance()->SetHostSize(gfx::Size(300, 400));
+ work_area = gfx::Screen::GetMonitorAreaNearestWindow(window.get());
+ EXPECT_LE(window->bounds().width(), work_area.width());
+ EXPECT_LE(window->bounds().height(), work_area.height());
+
+ // Make the root window shorter than our window.
+ aura::RootWindow::GetInstance()->SetHostSize(gfx::Size(300, 200));
+ work_area = gfx::Screen::GetMonitorAreaNearestWindow(window.get());
+ EXPECT_LE(window->bounds().width(), work_area.width());
+ EXPECT_LE(window->bounds().height(), work_area.height());
+
+ // Enlarging the root window does not change the window bounds.
+ gfx::Rect old_bounds = window->bounds();
+ aura::RootWindow::GetInstance()->SetHostSize(gfx::Size(800, 600));
+ EXPECT_EQ(old_bounds.width(), window->bounds().width());
+ EXPECT_EQ(old_bounds.height(), window->bounds().height());
+}
+
+} // namespace ash
diff --git a/ash/wm/compact_layout_manager.cc b/ash/wm/compact_layout_manager.cc
new file mode 100644
index 0000000..867cd30
--- /dev/null
+++ b/ash/wm/compact_layout_manager.cc
@@ -0,0 +1,68 @@
+// Copyright (c) 2012 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.
+
+#include "ash/wm/compact_layout_manager.h"
+
+#include "ash/wm/window_util.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/views/widget/widget.h"
+
+namespace ash {
+namespace internal {
+
+/////////////////////////////////////////////////////////////////////////////
+// CompactLayoutManager, public:
+
+CompactLayoutManager::CompactLayoutManager()
+ : status_area_widget_(NULL) {
+}
+
+CompactLayoutManager::~CompactLayoutManager() {
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CompactLayoutManager, LayoutManager overrides:
+
+void CompactLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
+ BaseLayoutManager::OnWindowAddedToLayout(child);
+ UpdateStatusAreaVisibility();
+}
+
+void CompactLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
+ BaseLayoutManager::OnWillRemoveWindowFromLayout(child);
+ UpdateStatusAreaVisibility();
+}
+
+void CompactLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
+ bool visible) {
+ BaseLayoutManager::OnChildWindowVisibilityChanged(child, visible);
+ UpdateStatusAreaVisibility();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CompactLayoutManager, WindowObserver overrides:
+
+void CompactLayoutManager::OnWindowPropertyChanged(aura::Window* window,
+ const char* name,
+ void* old) {
+ BaseLayoutManager::OnWindowPropertyChanged(window, name, old);
+ if (name == aura::client::kShowStateKey)
+ UpdateStatusAreaVisibility();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// CompactLayoutManager, private:
+
+void CompactLayoutManager::UpdateStatusAreaVisibility() {
+ if (!status_area_widget_)
+ return;
+ // Full screen windows should hide the status area widget.
+ if (window_util::HasFullscreenWindow(windows()))
+ status_area_widget_->Hide();
+ else
+ status_area_widget_->Show();
+}
+
+} // namespace internal
+} // namespace ash
diff --git a/ash/wm/compact_layout_manager.h b/ash/wm/compact_layout_manager.h
new file mode 100644
index 0000000..7ce87dd
--- /dev/null
+++ b/ash/wm/compact_layout_manager.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2012 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 ASH_WM_COMPACT_LAYOUT_MANAGER_H_
+#define ASH_WM_COMPACT_LAYOUT_MANAGER_H_
+#pragma once
+
+#include "ash/ash_export.h"
+#include "ash/wm/base_layout_manager.h"
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+
+namespace views {
+class Widget;
+}
+
+namespace ash {
+namespace internal {
+
+// CompactLayoutManager is the LayoutManager used in compact window mode,
+// which emulates the traditional Chrome OS window manager. Windows are always
+// maximized, fill the screen, and only one tabbed browser window is visible at
+// a time. The status area appears in the top-right corner of the screen.
+class ASH_EXPORT CompactLayoutManager : public BaseLayoutManager {
+ public:
+ CompactLayoutManager();
+ virtual ~CompactLayoutManager();
+
+ void set_status_area_widget(views::Widget* widget) {
+ status_area_widget_ = widget;
+ }
+
+ // LayoutManager overrides:
+ virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE;
+ virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE;
+ virtual void OnChildWindowVisibilityChanged(aura::Window* child,
+ bool visibile) OVERRIDE;
+
+ // WindowObserver overrides:
+ virtual void OnWindowPropertyChanged(aura::Window* window,
+ const char* name,
+ void* old) OVERRIDE;
+
+ private:
+ // Hides the status area if we are managing it and full screen windows are
+ // visible.
+ void UpdateStatusAreaVisibility();
+
+ // Status area with clock, network, battery, etc. icons. May be NULL if the
+ // shelf is managing the status area.
+ views::Widget* status_area_widget_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompactLayoutManager);
+};
+
+} // namespace ash
+} // namespace internal
+
+#endif // ASH_WM_COMPACT_LAYOUT_MANAGER_H_
diff --git a/ash/wm/compact_layout_manager_unittest.cc b/ash/wm/compact_layout_manager_unittest.cc
new file mode 100644
index 0000000..46d596e
--- /dev/null
+++ b/ash/wm/compact_layout_manager_unittest.cc
@@ -0,0 +1,87 @@
+// Copyright (c) 2012 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.
+
+#include "ash/wm/compact_layout_manager.h"
+
+#include "ash/wm/shelf_layout_manager.h"
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/screen_aura.h"
+#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/test_windows.h"
+#include "ui/aura/window.h"
+#include "ui/base/ui_base_types.h"
+#include "ui/views/widget/widget.h"
+
+namespace ash {
+
+namespace {
+
+class CompactLayoutManagerTest : public aura::test::AuraTestBase {
+ public:
+ CompactLayoutManagerTest() : layout_manager_(NULL) {}
+ virtual ~CompactLayoutManagerTest() {}
+
+ internal::CompactLayoutManager* layout_manager() {
+ return layout_manager_;
+ }
+
+ virtual void SetUp() OVERRIDE {
+ aura::test::AuraTestBase::SetUp();
+ aura::RootWindow::GetInstance()->screen()->set_work_area_insets(
+ gfx::Insets(1, 2, 3, 4));
+ aura::RootWindow::GetInstance()->SetHostSize(gfx::Size(800, 600));
+ container_.reset(new aura::Window(NULL));
+ container_->Init(ui::Layer::LAYER_HAS_NO_TEXTURE);
+ container_->SetBounds(gfx::Rect(0, 0, 500, 500));
+ layout_manager_ = new internal::CompactLayoutManager();
+ container_->SetLayoutManager(layout_manager_);
+ }
+
+ aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
+ return aura::test::CreateTestWindowWithBounds(bounds, container_.get());
+ }
+
+ // Returns widget owned by its parent, so doesn't need scoped_ptr<>.
+ views::Widget* CreateTestWidget() {
+ views::Widget* widget = new views::Widget;
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
+ params.bounds = gfx::Rect(11, 22, 33, 44);
+ widget->Init(params);
+ widget->Show();
+ return widget;
+ }
+
+ private:
+ // Owned by |container_|.
+ internal::CompactLayoutManager* layout_manager_;
+
+ scoped_ptr<aura::Window> container_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompactLayoutManagerTest);
+};
+
+} // namespace
+
+// Tests status area visibility during window maximize and fullscreen.
+TEST_F(CompactLayoutManagerTest, StatusAreaVisibility) {
+ gfx::Rect bounds(100, 100, 200, 200);
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ views::Widget* widget = CreateTestWidget();
+ layout_manager()->set_status_area_widget(widget);
+ EXPECT_TRUE(widget->IsVisible());
+ window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
+ EXPECT_TRUE(widget->IsVisible());
+ window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+ EXPECT_TRUE(widget->IsVisible());
+ window->SetIntProperty(aura::client::kShowStateKey,
+ ui::SHOW_STATE_FULLSCREEN);
+ EXPECT_FALSE(widget->IsVisible());
+ window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+ EXPECT_TRUE(widget->IsVisible());
+}
+
+} // namespace ash
diff --git a/ash/wm/toplevel_layout_manager.cc b/ash/wm/toplevel_layout_manager.cc
index 83a8552..c1de9b9 100644
--- a/ash/wm/toplevel_layout_manager.cc
+++ b/ash/wm/toplevel_layout_manager.cc
@@ -4,15 +4,11 @@
#include "ash/wm/toplevel_layout_manager.h"
-#include "ash/wm/property_util.h"
#include "ash/wm/shelf_layout_manager.h"
#include "ash/wm/window_util.h"
#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
-#include "ui/base/ui_base_types.h"
#include "ui/gfx/screen.h"
-#include "ui/views/widget/widget.h"
namespace {
@@ -41,81 +37,41 @@ namespace internal {
// ToplevelLayoutManager, public:
ToplevelLayoutManager::ToplevelLayoutManager()
- : shelf_(NULL),
- status_area_widget_(NULL) {
- aura::RootWindow::GetInstance()->AddRootWindowObserver(this);
+ : shelf_(NULL) {
}
ToplevelLayoutManager::~ToplevelLayoutManager() {
- for (WindowSet::const_iterator i = windows_.begin(); i != windows_.end(); ++i)
- (*i)->RemoveObserver(this);
- aura::RootWindow::GetInstance()->RemoveRootWindowObserver(this);
}
/////////////////////////////////////////////////////////////////////////////
// ToplevelLayoutManager, LayoutManager overrides:
-void ToplevelLayoutManager::OnWindowResized() {
-}
-
void ToplevelLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
- windows_.insert(child);
- child->AddObserver(this);
- if (child->GetProperty(aura::client::kShowStateKey)) {
- UpdateBoundsFromShowState(child);
- UpdateShelfVisibility();
- UpdateStatusAreaVisibility();
- }
+ BaseLayoutManager::OnWindowAddedToLayout(child);
+ UpdateShelfVisibility();
}
-void ToplevelLayoutManager::OnWillRemoveWindowFromLayout(
- aura::Window* child) {
- windows_.erase(child);
- child->RemoveObserver(this);
+void ToplevelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
+ BaseLayoutManager::OnWillRemoveWindowFromLayout(child);
UpdateShelfVisibility();
- UpdateStatusAreaVisibility();
}
void ToplevelLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
- bool visibile) {
+ bool visible) {
+ BaseLayoutManager::OnChildWindowVisibilityChanged(child, visible);
UpdateShelfVisibility();
- UpdateStatusAreaVisibility();
}
void ToplevelLayoutManager::SetChildBounds(aura::Window* child,
const gfx::Rect& requested_bounds) {
gfx::Rect child_bounds(requested_bounds);
- // Avoid a janky resize on startup by ensuring the initial bounds fill the
- // screen.
- if (window_util::IsWindowMaximized(child))
- child_bounds = gfx::Screen::GetMonitorWorkAreaNearestWindow(child);
- else if (window_util::IsWindowFullscreen(child))
- child_bounds = gfx::Screen::GetMonitorAreaNearestWindow(child);
- else
+ // Ensure normal windows have the title bar at least partly visible.
+ if (!window_util::IsWindowMaximized(child) &&
+ !window_util::IsWindowFullscreen(child)) {
child_bounds = BoundsWithTitleBarVisible(
child_bounds, gfx::Screen::GetMonitorWorkAreaNearestWindow(child));
- SetChildBoundsDirect(child, child_bounds);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// ToplevelLayoutManager, RootWindowObserver overrides:
-
-void ToplevelLayoutManager::OnRootWindowResized(const gfx::Size& new_size) {
- // If a user plugs an external monitor into a laptop running Aura the
- // monitor size will change. Maximized windows need to resize to match.
- // We also do this when developers running Aura on a desktop manually resize
- // the host window.
- for (WindowSet::const_iterator it = windows_.begin();
- it != windows_.end();
- ++it) {
- aura::Window* window = *it;
- // The work area may be smaller than the full screen.
- gfx::Rect monitor_rect = window_util::IsWindowFullscreen(window) ?
- gfx::Screen::GetMonitorAreaNearestWindow(window) :
- gfx::Screen::GetMonitorWorkAreaNearestWindow(window);
- // Put as much of the window as possible within the monitor area.
- window->SetBounds(window->bounds().AdjustToFit(monitor_rect));
}
+ BaseLayoutManager::SetChildBounds(child, child_bounds);
}
/////////////////////////////////////////////////////////////////////////////
@@ -124,56 +80,18 @@ void ToplevelLayoutManager::OnRootWindowResized(const gfx::Size& new_size) {
void ToplevelLayoutManager::OnWindowPropertyChanged(aura::Window* window,
const char* name,
void* old) {
- if (name == aura::client::kShowStateKey) {
- UpdateBoundsFromShowState(window);
+ BaseLayoutManager::OnWindowPropertyChanged(window, name, old);
+ if (name == aura::client::kShowStateKey)
UpdateShelfVisibility();
- UpdateStatusAreaVisibility();
- }
}
//////////////////////////////////////////////////////////////////////////////
// ToplevelLayoutManager, private:
-void ToplevelLayoutManager::UpdateBoundsFromShowState(aura::Window* window) {
- switch (window->GetIntProperty(aura::client::kShowStateKey)) {
- case ui::SHOW_STATE_NORMAL: {
- const gfx::Rect* restore = GetRestoreBounds(window);
- window->SetProperty(aura::client::kRestoreBoundsKey, NULL);
- if (restore)
- window->SetBounds(*restore);
- delete restore;
- break;
- }
-
- case ui::SHOW_STATE_MAXIMIZED:
- SetRestoreBoundsIfNotSet(window);
- window->SetBounds(gfx::Screen::GetMonitorWorkAreaNearestWindow(window));
- break;
-
- case ui::SHOW_STATE_FULLSCREEN:
- SetRestoreBoundsIfNotSet(window);
- window->SetBounds(gfx::Screen::GetMonitorAreaNearestWindow(window));
- break;
-
- default:
- break;
- }
-}
-
void ToplevelLayoutManager::UpdateShelfVisibility() {
if (!shelf_)
return;
- shelf_->SetVisible(!window_util::HasFullscreenWindow(windows_));
-}
-
-void ToplevelLayoutManager::UpdateStatusAreaVisibility() {
- if (!status_area_widget_)
- return;
- // Full screen windows should hide the status area widget.
- if (window_util::HasFullscreenWindow(windows_))
- status_area_widget_->Hide();
- else
- status_area_widget_->Show();
+ shelf_->SetVisible(!window_util::HasFullscreenWindow(windows()));
}
} // namespace internal
diff --git a/ash/wm/toplevel_layout_manager.h b/ash/wm/toplevel_layout_manager.h
index 4d9412b..fd12958 100644
--- a/ash/wm/toplevel_layout_manager.h
+++ b/ash/wm/toplevel_layout_manager.h
@@ -6,21 +6,10 @@
#define ASH_WM_TOPLEVEL_LAYOUT_MANAGER_H_
#pragma once
-#include <set>
-
+#include "ash/ash_export.h"
+#include "ash/wm/base_layout_manager.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
-#include "ui/aura/layout_manager.h"
-#include "ui/aura/root_window_observer.h"
-#include "ui/aura/window_observer.h"
-#include "ash/ash_export.h"
-
-namespace aura {
-class Window;
-}
-namespace views {
-class Widget;
-}
namespace ash {
namespace internal {
@@ -28,23 +17,20 @@ namespace internal {
class ShelfLayoutManager;
// ToplevelLayoutManager is the LayoutManager installed on a container that
-// hosts what the shell considers to be top-level windows. It is used if the
-// WorkspaceManager is not enabled. ToplevelLayoutManager listens for changes to
-// kShowStateKey and resizes the window appropriately.
-class ASH_EXPORT ToplevelLayoutManager : public aura::LayoutManager,
- public aura::RootWindowObserver,
- public aura::WindowObserver {
+// hosts what the shell considers to be top-level windows.
+//
+// ToplevelLayoutManager is used if the WorkspaceManager is not enabled and
+// compact window mode is not enabled. It is intended to implement the simplest
+// possible window management code. If you have a more complex window mode
+// please implement a new LayoutManager for it.
+class ASH_EXPORT ToplevelLayoutManager : public BaseLayoutManager {
public:
ToplevelLayoutManager();
virtual ~ToplevelLayoutManager();
void set_shelf(ShelfLayoutManager* shelf) { shelf_ = shelf; }
- void set_status_area_widget(views::Widget* widget) {
- status_area_widget_ = widget;
- }
// LayoutManager overrides:
- virtual void OnWindowResized() OVERRIDE;
virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE;
virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE;
virtual void OnChildWindowVisibilityChanged(aura::Window* child,
@@ -52,39 +38,20 @@ class ASH_EXPORT ToplevelLayoutManager : public aura::LayoutManager,
virtual void SetChildBounds(aura::Window* child,
const gfx::Rect& requested_bounds) OVERRIDE;
- // RootWindowObserver overrides:
- virtual void OnRootWindowResized(const gfx::Size& new_size) OVERRIDE;
-
// WindowObserver overrides:
virtual void OnWindowPropertyChanged(aura::Window* window,
const char* name,
void* old) OVERRIDE;
private:
- typedef std::set<aura::Window*> WindowSet;
-
- // Update window bounds based on a change in show state.
- void UpdateBoundsFromShowState(aura::Window* window);
-
// Updates the visibility of the shelf based on if there are any full screen
// windows.
void UpdateShelfVisibility();
- // Hides the status area if we are managing it and full screen windows are
- // visible.
- void UpdateStatusAreaVisibility();
-
- // Set of windows we're listening to.
- WindowSet windows_;
-
// Owned by the Shell container window LauncherContainer. May be NULL if
// we're not using a shelf.
ShelfLayoutManager* shelf_;
- // Status area with clock, network, battery, etc. icons. May be NULL if the
- // shelf is managing the status area.
- views::Widget* status_area_widget_;
-
DISALLOW_COPY_AND_ASSIGN(ToplevelLayoutManager);
};
diff --git a/ash/wm/toplevel_layout_manager_unittest.cc b/ash/wm/toplevel_layout_manager_unittest.cc
index 05bc69c..abbbb2b 100644
--- a/ash/wm/toplevel_layout_manager_unittest.cc
+++ b/ash/wm/toplevel_layout_manager_unittest.cc
@@ -11,6 +11,7 @@
#include "ui/aura/root_window.h"
#include "ui/aura/screen_aura.h"
#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/test_windows.h"
#include "ui/base/ui_base_types.h"
#include "ui/aura/window.h"
#include "ui/views/widget/widget.h"
@@ -41,12 +42,7 @@ class ToplevelLayoutManagerTest : public aura::test::AuraTestBase {
}
aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
- aura::Window* window = new aura::Window(NULL);
- window->Init(ui::Layer::LAYER_HAS_NO_TEXTURE);
- window->SetBounds(bounds);
- window->Show();
- window->SetParent(container_.get());
- return window;
+ return aura::test::CreateTestWindowWithBounds(bounds, container_.get());
}
// Returns widget owned by its parent, so doesn't need scoped_ptr<>.
@@ -182,24 +178,6 @@ TEST_F(ToplevelLayoutManagerTest, WindowStaysOnScreen) {
EXPECT_LT(window->bounds().x(), work_area.right());
}
-// Tests status area visibility during window maximize and fullscreen.
-TEST_F(ToplevelLayoutManagerTest, StatusAreaVisibility) {
- gfx::Rect bounds(100, 100, 200, 200);
- scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
- views::Widget* widget = CreateTestWidget();
- layout_manager()->set_status_area_widget(widget);
- EXPECT_TRUE(widget->IsVisible());
- window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
- EXPECT_TRUE(widget->IsVisible());
- window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
- EXPECT_TRUE(widget->IsVisible());
- window->SetIntProperty(aura::client::kShowStateKey,
- ui::SHOW_STATE_FULLSCREEN);
- EXPECT_FALSE(widget->IsVisible());
- window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
- EXPECT_TRUE(widget->IsVisible());
-}
-
// Tests shelf visibility during window maximize and fullscreen.
TEST_F(ToplevelLayoutManagerTest, ShelfVisibility) {
gfx::Rect bounds(100, 100, 200, 200);