summaryrefslogtreecommitdiffstats
path: root/ash/wm
diff options
context:
space:
mode:
Diffstat (limited to 'ash/wm')
-rw-r--r--ash/wm/compact_layout_manager.cc85
-rw-r--r--ash/wm/compact_layout_manager.h66
-rw-r--r--ash/wm/toplevel_layout_manager.cc123
-rw-r--r--ash/wm/toplevel_layout_manager.h37
-rw-r--r--ash/wm/toplevel_layout_manager_unittest.cc154
-rw-r--r--ash/wm/toplevel_window_event_filter.cc2
-rw-r--r--ash/wm/toplevel_window_event_filter_unittest.cc6
-rw-r--r--ash/wm/window_util.cc39
-rw-r--r--ash/wm/window_util.h15
-rw-r--r--ash/wm/workspace_controller.h6
10 files changed, 323 insertions, 210 deletions
diff --git a/ash/wm/compact_layout_manager.cc b/ash/wm/compact_layout_manager.cc
deleted file mode 100644
index a4a2847..0000000
--- a/ash/wm/compact_layout_manager.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2011 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/aura/window.h"
-#include "ui/base/ui_base_types.h"
-#include "ui/gfx/screen.h"
-#include "ui/views/widget/widget.h"
-
-namespace ash {
-namespace internal {
-
-CompactLayoutManager::CompactLayoutManager(views::Widget* status_area_widget)
- : status_area_widget_(status_area_widget) {
-}
-
-CompactLayoutManager::~CompactLayoutManager() {
- for (Windows::const_iterator i = windows_.begin(); i != windows_.end(); ++i)
- (*i)->RemoveObserver(this);
-}
-
-void CompactLayoutManager::OnWindowResized() {
-}
-
-void CompactLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
- windows_.insert(child);
- child->AddObserver(this);
- if (child->GetProperty(aura::client::kShowStateKey)) {
- UpdateBoundsFromShowState(child);
- UpdateStatusAreaVisibility();
- }
-}
-
-void CompactLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
- windows_.erase(child);
- child->RemoveObserver(this);
-}
-
-void CompactLayoutManager::OnChildWindowVisibilityChanged(
- aura::Window* child,
- bool visibile) {
- UpdateStatusAreaVisibility();
-}
-
-void CompactLayoutManager::SetChildBounds(
- aura::Window* child,
- const gfx::Rect& requested_bounds) {
- gfx::Rect bounds = requested_bounds;
- // Avoid a janky resize on startup by ensuring the initial bounds fill the
- // screen.
- if (IsWindowMaximized(child))
- bounds = gfx::Screen::GetPrimaryMonitorBounds();
- SetChildBoundsDirect(child, bounds);
-}
-
-void CompactLayoutManager::OnWindowPropertyChanged(aura::Window* window,
- const char* name,
- void* old) {
- if (name == aura::client::kShowStateKey) {
- UpdateBoundsFromShowState(window);
- UpdateStatusAreaVisibility();
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// CompactLayoutManager, private:
-
-void CompactLayoutManager::UpdateStatusAreaVisibility() {
- if (!status_area_widget_)
- return;
- // Full screen windows should hide the status area widget.
- bool fullscreen_window = HasFullscreenWindow(windows_);
- bool widget_visible = status_area_widget_->IsVisible();
- if (fullscreen_window && widget_visible)
- status_area_widget_->Hide();
- else if (!fullscreen_window && !widget_visible)
- status_area_widget_->Show();
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/ash/wm/compact_layout_manager.h b/ash/wm/compact_layout_manager.h
deleted file mode 100644
index 8785903..0000000
--- a/ash/wm/compact_layout_manager.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2011 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 <set>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "ui/aura/layout_manager.h"
-#include "ui/aura/window_observer.h"
-#include "ash/ash_export.h"
-
-namespace views {
-class Widget;
-}
-
-namespace ash {
-namespace internal {
-
-// CompactLayoutManager is an alternate LayoutManager for the container that
-// hosts what the shell considers to be top-level windows. It is used for low
-// resolution screens and keeps the main browser window maximized.
-// It listens for changes to kShowStateKey and resizes the window appropriately.
-class ASH_EXPORT CompactLayoutManager : public aura::LayoutManager,
- public aura::WindowObserver {
- public:
- explicit CompactLayoutManager(views::Widget* status_area_widget);
- virtual ~CompactLayoutManager();
-
- // 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;
-
- // WindowObserver overrides:
- virtual void OnWindowPropertyChanged(aura::Window* window,
- const char* name,
- void* old) OVERRIDE;
-
- private:
- typedef std::set<aura::Window*> Windows;
-
- // Hides the status area when full screen windows cover it.
- void UpdateStatusAreaVisibility();
-
- // Set of windows we're listening to.
- Windows windows_;
-
- // Weak pointer to status area with clock, network, battery, etc. icons.
- 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/toplevel_layout_manager.cc b/ash/wm/toplevel_layout_manager.cc
index 09a5ae1..83a8552 100644
--- a/ash/wm/toplevel_layout_manager.cc
+++ b/ash/wm/toplevel_layout_manager.cc
@@ -1,27 +1,60 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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/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 {
+
+// Minimum number of pixels at the window top to keep visible on screen.
+const int kMinimumWindowTopVisible = 12;
+
+// Returns a bounds rectangle with at least a few pixels of the window's
+// title bar visible.
+gfx::Rect BoundsWithTitleBarVisible(const gfx::Rect& window_bounds,
+ const gfx::Rect& work_area) {
+ gfx::Rect bounds(window_bounds);
+ // Ensure title bar is vertically on screen.
+ if (bounds.y() < work_area.y())
+ bounds.set_y(work_area.y());
+ else if (bounds.y() + kMinimumWindowTopVisible > work_area.bottom())
+ bounds.set_y(work_area.bottom() - kMinimumWindowTopVisible);
+ return bounds;
+}
+
+} // namespace
namespace ash {
namespace internal {
-ToplevelLayoutManager::ToplevelLayoutManager() : shelf_(NULL) {
+/////////////////////////////////////////////////////////////////////////////
+// ToplevelLayoutManager, public:
+
+ToplevelLayoutManager::ToplevelLayoutManager()
+ : shelf_(NULL),
+ status_area_widget_(NULL) {
+ aura::RootWindow::GetInstance()->AddRootWindowObserver(this);
}
ToplevelLayoutManager::~ToplevelLayoutManager() {
- for (Windows::const_iterator i = windows_.begin(); i != windows_.end(); ++i)
+ 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() {
}
@@ -31,6 +64,7 @@ void ToplevelLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
if (child->GetProperty(aura::client::kShowStateKey)) {
UpdateBoundsFromShowState(child);
UpdateShelfVisibility();
+ UpdateStatusAreaVisibility();
}
}
@@ -39,38 +73,107 @@ void ToplevelLayoutManager::OnWillRemoveWindowFromLayout(
windows_.erase(child);
child->RemoveObserver(this);
UpdateShelfVisibility();
+ UpdateStatusAreaVisibility();
}
void ToplevelLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
bool visibile) {
UpdateShelfVisibility();
+ UpdateStatusAreaVisibility();
}
void ToplevelLayoutManager::SetChildBounds(aura::Window* child,
const gfx::Rect& requested_bounds) {
- const static int kTitleHeight = 12;
gfx::Rect child_bounds(requested_bounds);
- gfx::Rect work_area = gfx::Screen::GetMonitorWorkAreaNearestWindow(child);
- if (child_bounds.y() < 0)
- child_bounds.set_y(0);
- else if (child_bounds.y() + kTitleHeight > work_area.bottom())
- child_bounds.set_y(work_area.bottom() - kTitleHeight);
+ // 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
+ 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));
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// ToplevelLayoutManager, WindowObserver overrides:
+
void ToplevelLayoutManager::OnWindowPropertyChanged(aura::Window* window,
const char* name,
void* old) {
if (name == aura::client::kShowStateKey) {
UpdateBoundsFromShowState(window);
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(!HasFullscreenWindow(windows_));
+ 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();
}
} // namespace internal
diff --git a/ash/wm/toplevel_layout_manager.h b/ash/wm/toplevel_layout_manager.h
index 27aa7ac..4d9412b 100644
--- a/ash/wm/toplevel_layout_manager.h
+++ b/ash/wm/toplevel_layout_manager.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -11,9 +11,17 @@
#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 {
@@ -24,12 +32,16 @@ class ShelfLayoutManager;
// WorkspaceManager is not enabled. ToplevelLayoutManager listens for changes to
// kShowStateKey and resizes the window appropriately.
class ASH_EXPORT ToplevelLayoutManager : public aura::LayoutManager,
- public aura::WindowObserver {
+ public aura::RootWindowObserver,
+ public aura::WindowObserver {
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;
@@ -40,24 +52,39 @@ 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*> Windows;
+ 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.
- Windows windows_;
+ WindowSet windows_;
- // May be NULL if we're not using a shelf.
+ // 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 8f150ff..05bc69c 100644
--- a/ash/wm/toplevel_layout_manager_unittest.cc
+++ b/ash/wm/toplevel_layout_manager_unittest.cc
@@ -1,9 +1,10 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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/toplevel_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"
@@ -12,6 +13,7 @@
#include "ui/aura/test/aura_test_base.h"
#include "ui/base/ui_base_types.h"
#include "ui/aura/window.h"
+#include "ui/views/widget/widget.h"
namespace ash {
@@ -22,11 +24,15 @@ class ToplevelLayoutManagerTest : public aura::test::AuraTestBase {
ToplevelLayoutManagerTest() : layout_manager_(NULL) {}
virtual ~ToplevelLayoutManagerTest() {}
+ internal::ToplevelLayoutManager* 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(500, 400));
+ 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));
@@ -43,6 +49,16 @@ class ToplevelLayoutManagerTest : public aura::test::AuraTestBase {
return window;
}
+ // 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::ToplevelLayoutManager* layout_manager_;
@@ -59,22 +75,156 @@ TEST_F(ToplevelLayoutManagerTest, 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(ToplevelLayoutManagerTest, 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(ToplevelLayoutManagerTest, 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(ToplevelLayoutManagerTest, 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(ToplevelLayoutManagerTest, 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());
+}
+
+// Test that window stays on screen despite attempts to move it off.
+TEST_F(ToplevelLayoutManagerTest, WindowStaysOnScreen) {
+ scoped_ptr<aura::Window> window(
+ CreateTestWindow(gfx::Rect(10, 20, 300, 200)));
+ gfx::Rect work_area = gfx::Screen::GetMonitorAreaNearestWindow(window.get());
+ // Invariant: The top edge of the window is inside the work area and at least
+ // one pixel is visible horizontally.
+ // and horizontal dimensions.
+ EXPECT_GE(window->bounds().y(), 0);
+ EXPECT_LT(window->bounds().y(), work_area.bottom());
+ EXPECT_GE(window->bounds().right(), 0);
+ EXPECT_LT(window->bounds().x(), work_area.right());
+
+ // Try to move window above the top of screen.
+ window->SetBounds(gfx::Rect(10, -1, 300, 200));
+ EXPECT_GE(window->bounds().y(), 0);
+
+ // Try to move window below the bottom.
+ window->SetBounds(gfx::Rect(10, work_area.bottom(), 300, 200));
+ EXPECT_LT(window->bounds().y(), work_area.bottom());
+
+ // Put the screen near the right edge, then shrink the host window.
+ window->SetBounds(gfx::Rect(work_area.right() - 15, 20, 300, 200));
+ aura::RootWindow::GetInstance()->SetHostSize(gfx::Size(350, 250));
+ EXPECT_GE(window->bounds().y(), 0);
+ EXPECT_LT(window->bounds().y(), work_area.bottom());
+ EXPECT_GE(window->bounds().right(), 0);
+ 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);
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ views::Widget* launcher = CreateTestWidget();
+ views::Widget* status = CreateTestWidget();
+ scoped_ptr<internal::ShelfLayoutManager> shelf_layout_manager(
+ new internal::ShelfLayoutManager(launcher, status));
+ layout_manager()->set_shelf(shelf_layout_manager.get());
+ EXPECT_TRUE(shelf_layout_manager.get()->visible());
+ window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
+ EXPECT_TRUE(shelf_layout_manager.get()->visible());
+ window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+ EXPECT_TRUE(shelf_layout_manager.get()->visible());
+ window->SetIntProperty(aura::client::kShowStateKey,
+ ui::SHOW_STATE_FULLSCREEN);
+ EXPECT_FALSE(shelf_layout_manager.get()->visible());
+ window->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+ EXPECT_TRUE(shelf_layout_manager.get()->visible());
+ // Window depends on layout manager for cleanup.
+ window.reset();
+ // shelf_layout_manager is observing these animations so clean them up first.
+ launcher->GetNativeView()->layer()->GetAnimator()->StopAnimating();
+ status->GetNativeView()->layer()->GetAnimator()->StopAnimating();
+ shelf_layout_manager.reset();
+}
+
} // namespace ash
diff --git a/ash/wm/toplevel_window_event_filter.cc b/ash/wm/toplevel_window_event_filter.cc
index ccc7a4e..3396eed 100644
--- a/ash/wm/toplevel_window_event_filter.cc
+++ b/ash/wm/toplevel_window_event_filter.cc
@@ -129,7 +129,7 @@ bool IsBottomEdge(int window_component) {
void ToggleMaximizedState(aura::Window* window) {
window->SetIntProperty(aura::client::kShowStateKey,
- IsWindowMaximized(window) ?
+ window_util::IsWindowMaximized(window) ?
ui::SHOW_STATE_NORMAL : ui::SHOW_STATE_MAXIMIZED);
}
diff --git a/ash/wm/toplevel_window_event_filter_unittest.cc b/ash/wm/toplevel_window_event_filter_unittest.cc
index 0fef59d..db13f51 100644
--- a/ash/wm/toplevel_window_event_filter_unittest.cc
+++ b/ash/wm/toplevel_window_event_filter_unittest.cc
@@ -309,15 +309,15 @@ TEST_F(ToplevelWindowEventFilterTest, BottomRightPastMinimum) {
TEST_F(ToplevelWindowEventFilterTest, DoubleClickCaptionTogglesMaximize) {
scoped_ptr<aura::Window> w1(CreateWindow(HTCAPTION));
- EXPECT_FALSE(IsWindowMaximized(w1.get()));
+ EXPECT_FALSE(window_util::IsWindowMaximized(w1.get()));
aura::test::EventGenerator generator(w1.get());
generator.DoubleClickLeftButton();
- EXPECT_TRUE(IsWindowMaximized(w1.get()));
+ EXPECT_TRUE(window_util::IsWindowMaximized(w1.get()));
generator.DoubleClickLeftButton();
- EXPECT_FALSE(IsWindowMaximized(w1.get()));
+ EXPECT_FALSE(window_util::IsWindowMaximized(w1.get()));
}
TEST_F(ToplevelWindowEventFilterTest, BottomRightWorkArea) {
diff --git a/ash/wm/window_util.cc b/ash/wm/window_util.cc
index 37104d7..c402ef2 100644
--- a/ash/wm/window_util.cc
+++ b/ash/wm/window_util.cc
@@ -1,11 +1,10 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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/window_util.h"
#include "ash/wm/activation_controller.h"
-#include "ash/wm/property_util.h"
#include "ui/aura/client/activation_client.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/root_window.h"
@@ -15,11 +14,6 @@
namespace ash {
-bool IsWindowMaximized(aura::Window* window) {
- return window->GetIntProperty(aura::client::kShowStateKey) ==
- ui::SHOW_STATE_MAXIMIZED;
-}
-
void ActivateWindow(aura::Window* window) {
aura::client::GetActivationClient()->ActivateWindow(window);
}
@@ -40,30 +34,16 @@ aura::Window* GetActivatableWindow(aura::Window* window) {
return internal::ActivationController::GetActivatableWindow(window);
}
-void 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;
+namespace window_util {
- case ui::SHOW_STATE_FULLSCREEN:
- SetRestoreBoundsIfNotSet(window);
- window->SetBounds(gfx::Screen::GetMonitorAreaNearestWindow(window));
- break;
+bool IsWindowMaximized(aura::Window* window) {
+ return window->GetIntProperty(aura::client::kShowStateKey) ==
+ ui::SHOW_STATE_MAXIMIZED;
+}
- default:
- break;
- }
+bool IsWindowFullscreen(aura::Window* window) {
+ return window->GetIntProperty(aura::client::kShowStateKey) ==
+ ui::SHOW_STATE_FULLSCREEN;
}
bool HasFullscreenWindow(const WindowSet& windows) {
@@ -76,4 +56,5 @@ bool HasFullscreenWindow(const WindowSet& windows) {
return false;
}
+} // namespace window_util
} // namespace ash
diff --git a/ash/wm/window_util.h b/ash/wm/window_util.h
index e96591f..dbafb5b 100644
--- a/ash/wm/window_util.h
+++ b/ash/wm/window_util.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -18,9 +18,6 @@ namespace ash {
// TODO(jamescook): Put all these functions in namespace window_util.
-// Returns true if |window| is in the maximized state.
-ASH_EXPORT bool IsWindowMaximized(aura::Window* window);
-
// Convenience setters/getters for |aura::client::kRootWindowActiveWindow|.
ASH_EXPORT void ActivateWindow(aura::Window* window);
ASH_EXPORT void DeactivateWindow(aura::Window* window);
@@ -34,13 +31,19 @@ ASH_EXPORT aura::Window* GetActiveWindow();
// this is probably what you're looking for.
ASH_EXPORT aura::Window* GetActivatableWindow(aura::Window* window);
-// Update window bounds based on a change in show state.
-ASH_EXPORT void UpdateBoundsFromShowState(aura::Window* window);
+namespace window_util {
+
+// Returns true if |window| is in the maximized state.
+ASH_EXPORT bool IsWindowMaximized(aura::Window* window);
+
+// Returns true if |window| is in the fullscreen state.
+ASH_EXPORT bool IsWindowFullscreen(aura::Window* window);
// Returns true if the set of |windows| contains a full-screen window.
typedef std::set<aura::Window*> WindowSet;
ASH_EXPORT bool HasFullscreenWindow(const WindowSet& windows);
+} // namespace window_util
} // namespace ash
#endif // ASH_WM_WINDOW_UTIL_H_
diff --git a/ash/wm/workspace_controller.h b/ash/wm/workspace_controller.h
index f17a395..4e20a43 100644
--- a/ash/wm/workspace_controller.h
+++ b/ash/wm/workspace_controller.h
@@ -29,9 +29,9 @@ namespace internal {
class WorkspaceManager;
-// WorkspaceControlls owns a WorkspaceManager. WorkspaceControlls bridges
-// events From RootWindowObserver translating them to WorkspaceManager, and
-// a move event between Laucher and Workspace.
+// WorkspaceController owns a WorkspaceManager. WorkspaceController bridges
+// events from RootWindowObserver translating them to WorkspaceManager, and
+// a move event between Launcher and Workspace.
class ASH_EXPORT WorkspaceController :
public aura::RootWindowObserver,
public aura::WindowObserver,