summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/ash.gyp3
-rw-r--r--ash/root_window_controller.cc1
-rw-r--r--ash/shell.cc1
-rw-r--r--ash/wm/base_layout_manager.cc284
-rw-r--r--ash/wm/base_layout_manager.h128
-rw-r--r--ash/wm/base_layout_manager_unittest.cc313
-rw-r--r--ash/wm/workspace/workspace_layout_manager.cc158
-rw-r--r--ash/wm/workspace/workspace_layout_manager.h58
-rw-r--r--ash/wm/workspace/workspace_layout_manager_unittest.cc296
-rw-r--r--ash/wm/workspace_controller.cc1
10 files changed, 493 insertions, 750 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp
index ffeb74b..9d45eb6 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -444,8 +444,6 @@
'wm/ash_native_cursor_manager.h',
'wm/ash_focus_rules.cc',
'wm/ash_focus_rules.h',
- 'wm/base_layout_manager.cc',
- 'wm/base_layout_manager.h',
'wm/boot_splash_screen_chromeos.cc',
'wm/boot_splash_screen_chromeos.h',
'wm/caption_buttons/alternate_frame_size_button.cc',
@@ -897,7 +895,6 @@
'touch/touch_observer_hud_unittest.cc',
'wm/app_list_controller_unittest.cc',
'wm/ash_native_cursor_manager_unittest.cc',
- 'wm/base_layout_manager_unittest.cc',
'wm/caption_buttons/alternate_frame_size_button_unittest.cc',
'wm/caption_buttons/frame_caption_button_container_view_unittest.cc',
'wm/caption_buttons/frame_maximize_button_unittest.cc',
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index cd24636..a3ec739 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -30,7 +30,6 @@
#include "ash/touch/touch_hud_projection.h"
#include "ash/touch/touch_observer_hud.h"
#include "ash/wm/always_on_top_controller.h"
-#include "ash/wm/base_layout_manager.h"
#include "ash/wm/dock/docked_window_layout_manager.h"
#include "ash/wm/panels/panel_layout_manager.h"
#include "ash/wm/panels/panel_window_event_handler.h"
diff --git a/ash/shell.cc b/ash/shell.cc
index 986612e..a01990e 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -54,7 +54,6 @@
#include "ash/wm/app_list_controller.h"
#include "ash/wm/ash_focus_rules.h"
#include "ash/wm/ash_native_cursor_manager.h"
-#include "ash/wm/base_layout_manager.h"
#include "ash/wm/coordinate_conversion.h"
#include "ash/wm/custom_frame_view_ash.h"
#include "ash/wm/event_client_impl.h"
diff --git a/ash/wm/base_layout_manager.cc b/ash/wm/base_layout_manager.cc
deleted file mode 100644
index 18c8ee8..0000000
--- a/ash/wm/base_layout_manager.cc
+++ /dev/null
@@ -1,284 +0,0 @@
-// 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/screen_util.h"
-#include "ash/session_state_delegate.h"
-#include "ash/shelf/shelf_layout_manager.h"
-#include "ash/shell.h"
-#include "ash/wm/window_animations.h"
-#include "ash/wm/window_properties.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "ash/wm/workspace/workspace_window_resizer.h"
-#include "ui/aura/client/activation_client.h"
-#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/window.h"
-#include "ui/base/ui_base_types.h"
-#include "ui/compositor/layer.h"
-#include "ui/gfx/screen.h"
-#include "ui/views/corewm/corewm_switches.h"
-#include "ui/views/corewm/window_util.h"
-
-namespace ash {
-namespace internal {
-
-/////////////////////////////////////////////////////////////////////////////
-// BaseLayoutManager, public:
-
-BaseLayoutManager::BaseLayoutManager(aura::Window* root_window)
- : root_window_(root_window) {
- Shell::GetInstance()->activation_client()->AddObserver(this);
- Shell::GetInstance()->AddShellObserver(this);
- root_window_->AddObserver(this);
-}
-
-BaseLayoutManager::~BaseLayoutManager() {
- if (root_window_)
- root_window_->RemoveObserver(this);
- for (WindowSet::const_iterator i = windows_.begin(); i != windows_.end(); ++i)
- (*i)->RemoveObserver(this);
- Shell::GetInstance()->RemoveShellObserver(this);
- Shell::GetInstance()->activation_client()->RemoveObserver(this);
-}
-
-// static
-gfx::Rect BaseLayoutManager::BoundsWithScreenEdgeVisible(
- aura::Window* window,
- const gfx::Rect& restore_bounds) {
- gfx::Rect max_bounds =
- ash::ScreenUtil::GetMaximizedWindowBoundsInParent(window);
- // If the restore_bounds are more than 1 grid step away from the size the
- // window would be when maximized, inset it.
- max_bounds.Inset(ash::internal::WorkspaceWindowResizer::kScreenEdgeInset,
- ash::internal::WorkspaceWindowResizer::kScreenEdgeInset);
- if (restore_bounds.Contains(max_bounds))
- return max_bounds;
- return restore_bounds;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// BaseLayoutManager, aura::LayoutManager overrides:
-
-void BaseLayoutManager::OnWindowResized() {
-}
-
-void BaseLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
- windows_.insert(child);
- child->AddObserver(this);
- wm::WindowState* window_state = wm::GetWindowState(child);
- window_state->AddObserver(this);
-
- // Only update the bounds if the window has a show state that depends on the
- // workspace area.
- if (window_state->IsMaximizedOrFullscreen())
- UpdateBoundsFromShowType(window_state);
-}
-
-void BaseLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
- windows_.erase(child);
- child->RemoveObserver(this);
- wm::GetWindowState(child)->RemoveObserver(this);
-}
-
-void BaseLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) {
-}
-
-void BaseLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
- bool visible) {
- wm::WindowState* window_state = wm::GetWindowState(child);
- // Attempting to show a minimized window. Unminimize it.
- if (visible && window_state->IsMinimized())
- window_state->Unminimize();
-}
-
-void BaseLayoutManager::SetChildBounds(aura::Window* child,
- const gfx::Rect& requested_bounds) {
- gfx::Rect child_bounds(requested_bounds);
- wm::WindowState* window_state = wm::GetWindowState(child);
- // Some windows rely on this to set their initial bounds.
- if (window_state->IsMaximized())
- child_bounds = ScreenUtil::GetMaximizedWindowBoundsInParent(child);
- else if (window_state->IsFullscreen())
- child_bounds = ScreenUtil::GetDisplayBoundsInParent(child);
- SetChildBoundsDirect(child, child_bounds);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// BaseLayoutManager, aura::WindowObserver overrides:
-
-void BaseLayoutManager::OnWindowDestroying(aura::Window* window) {
- if (root_window_ == window) {
- root_window_->RemoveObserver(this);
- root_window_ = NULL;
- }
-}
-
-void BaseLayoutManager::OnWindowBoundsChanged(aura::Window* window,
- const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) {
- if (root_window_ == window)
- AdjustAllWindowsBoundsForWorkAreaChange(ADJUST_WINDOW_DISPLAY_SIZE_CHANGED);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// BaseLayoutManager, aura::client::ActivationChangeObserver implementation:
-
-void BaseLayoutManager::OnWindowActivated(aura::Window* gained_active,
- aura::Window* lost_active) {
- wm::WindowState* window_state = wm::GetWindowState(gained_active);
- if (window_state && window_state->IsMinimized() &&
- !gained_active->IsVisible()) {
- window_state->Unminimize();
- DCHECK(!window_state->IsMinimized());
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// BaseLayoutManager, ash::ShellObserver overrides:
-
-void BaseLayoutManager::OnDisplayWorkAreaInsetsChanged() {
- AdjustAllWindowsBoundsForWorkAreaChange(
- ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// BaseLayoutManager, ash::wm::WindowStateObserver overrides:
-
-void BaseLayoutManager::OnWindowShowTypeChanged(wm::WindowState* window_state,
- wm::WindowShowType old_type) {
- if (old_type != wm::SHOW_TYPE_MINIMIZED &&
- !window_state->HasRestoreBounds() &&
- window_state->IsMaximizedOrFullscreen() &&
- !wm::IsMaximizedOrFullscreenWindowShowType(old_type)) {
- window_state->SetRestoreBoundsInParent(window_state->window()->bounds());
- }
-
- UpdateBoundsFromShowType(window_state);
- ShowTypeChanged(window_state, old_type);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// BaseLayoutManager, protected:
-
-void BaseLayoutManager::ShowTypeChanged(
- wm::WindowState* window_state,
- wm::WindowShowType last_show_type) {
- if (window_state->IsMinimized()) {
- if (last_show_type == wm::SHOW_TYPE_MINIMIZED)
- return;
-
- // Save the previous show state so that we can correctly restore it.
- window_state->window()->SetProperty(aura::client::kRestoreShowStateKey,
- wm::ToWindowShowState(last_show_type));
- views::corewm::SetWindowVisibilityAnimationType(
- window_state->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
-
- // Hide the window.
- window_state->window()->Hide();
- // Activate another window.
- if (window_state->IsActive())
- window_state->Deactivate();
- } else if ((window_state->window()->TargetVisibility() ||
- last_show_type == wm::SHOW_TYPE_MINIMIZED) &&
- !window_state->window()->layer()->visible()) {
- // The layer may be hidden if the window was previously minimized. Make
- // sure it's visible.
- window_state->window()->Show();
- if (last_show_type == wm::SHOW_TYPE_MINIMIZED)
- window_state->set_unminimize_to_restore_bounds(false);
- }
-}
-
-void BaseLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(
- AdjustWindowReason reason) {
- // Don't do any adjustments of the insets while we are in screen locked mode.
- // This would happen if the launcher was auto hidden before the login screen
- // was shown and then gets shown when the login screen gets presented.
- if (reason == ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED &&
- Shell::GetInstance()->session_state_delegate()->IsScreenLocked())
- return;
-
- // If a user plugs an external display into a laptop running Aura the
- // display 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.
- // We also need to do this when the work area insets changes.
- for (WindowSet::const_iterator it = windows_.begin();
- it != windows_.end();
- ++it) {
- AdjustWindowBoundsForWorkAreaChange(wm::GetWindowState(*it), reason);
- }
-}
-
-void BaseLayoutManager::AdjustWindowBoundsForWorkAreaChange(
- wm::WindowState* window_state,
- AdjustWindowReason reason) {
- aura::Window* window = window_state->window();
- if (window_state->IsMaximized()) {
- SetChildBoundsDirect(
- window, ScreenUtil::GetMaximizedWindowBoundsInParent(window));
- } else if (window_state->IsFullscreen()) {
- SetChildBoundsDirect(
- window, ScreenUtil::GetDisplayBoundsInParent(window));
- } else {
- // The work area may be smaller than the full screen.
- gfx::Rect display_rect =
- ScreenUtil::GetDisplayWorkAreaBoundsInParent(window);
- // Put as much of the window as possible within the display area.
- gfx::Rect bounds = window->bounds();
- bounds.AdjustToFit(display_rect);
- window->SetBounds(bounds);
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// BaseLayoutManager, private:
-
-void BaseLayoutManager::UpdateBoundsFromShowType(
- wm::WindowState* window_state) {
- aura::Window* window = window_state->window();
- switch (window_state->window_show_type()) {
- case wm::SHOW_TYPE_DEFAULT:
- case wm::SHOW_TYPE_NORMAL:
- if (window_state->HasRestoreBounds()) {
- gfx::Rect bounds_in_parent = window_state->GetRestoreBoundsInParent();
- SetChildBoundsDirect(window,
- BoundsWithScreenEdgeVisible(window,
- bounds_in_parent));
- }
- window_state->ClearRestoreBounds();
- break;
-
- case wm::SHOW_TYPE_LEFT_SNAPPED:
- case wm::SHOW_TYPE_RIGHT_SNAPPED:
- if (window_state->HasRestoreBounds())
- SetChildBoundsDirect(window, window_state->GetRestoreBoundsInParent());
- window_state->ClearRestoreBounds();
- break;
-
- case wm::SHOW_TYPE_MAXIMIZED:
- SetChildBoundsDirect(
- window, ScreenUtil::GetMaximizedWindowBoundsInParent(window));
- break;
-
- case wm::SHOW_TYPE_FULLSCREEN:
- // Don't animate the full-screen window transition.
- // TODO(jamescook): Use animation here. Be sure the lock screen works.
- SetChildBoundsDirect(window,
- ScreenUtil::GetDisplayBoundsInParent(window));
- break;
-
- case wm::SHOW_TYPE_MINIMIZED:
- case wm::SHOW_TYPE_INACTIVE:
- case wm::SHOW_TYPE_DETACHED:
- case wm::SHOW_TYPE_END:
- case wm::SHOW_TYPE_AUTO_POSITIONED:
- break;
- }
-}
-
-} // namespace internal
-} // namespace ash
diff --git a/ash/wm/base_layout_manager.h b/ash/wm/base_layout_manager.h
deleted file mode 100644
index 341915e..0000000
--- a/ash/wm/base_layout_manager.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// 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_
-
-#include <set>
-
-#include "ash/ash_export.h"
-#include "ash/shell_observer.h"
-#include "ash/wm/window_state_observer.h"
-#include "ash/wm/wm_types.h"
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "ui/aura/client/activation_change_observer.h"
-#include "ui/aura/layout_manager.h"
-#include "ui/aura/window_observer.h"
-#include "ui/events/event_handler.h"
-
-namespace aura {
-class Window;
-}
-
-namespace ash {
-namespace wm {
-class WindowState;
-}
-
-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::WindowObserver,
- public aura::client::ActivationChangeObserver,
- public ShellObserver,
- public wm::WindowStateObserver {
- public:
- typedef std::set<aura::Window*> WindowSet;
-
- explicit BaseLayoutManager(aura::Window* root_window);
- virtual ~BaseLayoutManager();
-
- const WindowSet& windows() const { return windows_; }
-
- // Given a |window| and tentative |restore_bounds|, returns new bounds that
- // ensure that at least a few pixels of the screen background are visible
- // outside the edges of the window.
- static gfx::Rect BoundsWithScreenEdgeVisible(aura::Window* window,
- const gfx::Rect& restore_bounds);
-
- // aura::LayoutManager overrides:
- virtual void OnWindowResized() OVERRIDE;
- virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE;
- virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE;
- virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE;
- virtual void OnChildWindowVisibilityChanged(aura::Window* child,
- bool visible) OVERRIDE;
- virtual void SetChildBounds(aura::Window* child,
- const gfx::Rect& requested_bounds) OVERRIDE;
-
- // aura::WindowObserver overrides:
- virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
- virtual void OnWindowBoundsChanged(aura::Window* window,
- const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) OVERRIDE;
-
- // aura::client::ActivationChangeObserver overrides:
- virtual void OnWindowActivated(aura::Window* gained_active,
- aura::Window* lost_active) OVERRIDE;
-
- // ash::ShellObserver overrides:
- virtual void OnDisplayWorkAreaInsetsChanged() OVERRIDE;
-
- // wm::WindowStateObserver overrides:
- virtual void OnWindowShowTypeChanged(wm::WindowState* window_state,
- wm::WindowShowType type) OVERRIDE;
-
- protected:
- enum AdjustWindowReason {
- ADJUST_WINDOW_DISPLAY_SIZE_CHANGED,
- ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED,
- };
-
- // Invoked from OnWindowShowTypeChanged().
- virtual void ShowTypeChanged(wm::WindowState* window_state,
- wm::WindowShowType last_show_type);
-
- // Adjusts the window's bounds when the display area changes for given
- // window. This happens when the display size, work area insets or
- // the display on which the window exists has changed.
- // If this is called for a display size change (i.e. |reason|
- // is ADJUST_WINDOW_DISPLAY_SIZE_CHANGED), the non-maximized/non-fullscreen
- // windows are readjusted to make sure the window is completely within the
- // display region. Otherwise, it makes sure at least some parts of the window
- // is on display.
- virtual void AdjustAllWindowsBoundsForWorkAreaChange(
- AdjustWindowReason reason);
-
- // Adjusts the sizes of the specific window in respond to a screen change or
- // display-area size change.
- virtual void AdjustWindowBoundsForWorkAreaChange(
- wm::WindowState* window_state,
- AdjustWindowReason reason);
-
- aura::Window* root_window() { return root_window_; }
-
- private:
- // Update window bounds based on a change in show type.
- void UpdateBoundsFromShowType(wm::WindowState* controller);
-
- // Set of windows we're listening to.
- WindowSet windows_;
-
- aura::Window* root_window_;
-
- DISALLOW_COPY_AND_ASSIGN(BaseLayoutManager);
-};
-
-} // namespace internal
-} // namespace ash
-
-#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
deleted file mode 100644
index b869648..0000000
--- a/ash/wm/base_layout_manager_unittest.cc
+++ /dev/null
@@ -1,313 +0,0 @@
-// 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/screen_util.h"
-#include "ash/session_state_delegate.h"
-#include "ash/shelf/shelf_layout_manager.h"
-#include "ash/shell.h"
-#include "ash/shell_window_ids.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "ash/wm/workspace/workspace_window_resizer.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/test/test_windows.h"
-#include "ui/aura/window.h"
-#include "ui/base/ui_base_types.h"
-#include "ui/gfx/insets.h"
-#include "ui/gfx/screen.h"
-
-namespace ash {
-
-namespace {
-
-class BaseLayoutManagerTest : public test::AshTestBase {
- public:
- BaseLayoutManagerTest() {}
- virtual ~BaseLayoutManagerTest() {}
-
- virtual void SetUp() OVERRIDE {
- test::AshTestBase::SetUp();
- UpdateDisplay("800x600");
- aura::Window* default_container = Shell::GetContainer(
- Shell::GetPrimaryRootWindow(),
- internal::kShellWindowId_DefaultContainer);
- default_container->SetLayoutManager(new internal::BaseLayoutManager(
- Shell::GetPrimaryRootWindow()));
- }
-
- aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
- return CreateTestWindowInShellWithBounds(bounds);
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BaseLayoutManagerTest);
-};
-
-// Tests normal->maximize->normal.
-TEST_F(BaseLayoutManagerTest, Maximize) {
- gfx::Rect bounds(100, 100, 200, 200);
- scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
- // Maximized window fills the work area, not the whole display.
- EXPECT_EQ(
- ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
- window->bounds().ToString());
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
- EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
-}
-
-// Tests normal->minimize->normal.
-TEST_F(BaseLayoutManagerTest, Minimize) {
- gfx::Rect bounds(100, 100, 200, 200);
- scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
- // Note: Currently minimize doesn't do anything except set the state.
- // See crbug.com/104571.
- EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
- EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
-}
-
-// A WindowDelegate which sets the focus when the window
-// becomes visible.
-class FocusDelegate : public aura::test::TestWindowDelegate {
- public:
- FocusDelegate()
- : window_(NULL),
- show_state_(ui::SHOW_STATE_END) {
- }
- virtual ~FocusDelegate() {}
-
- void set_window(aura::Window* window) { window_ = window; }
-
- // aura::test::TestWindowDelegate overrides:
- virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
- if (window_) {
- if (visible)
- window_->Focus();
- show_state_ = window_->GetProperty(aura::client::kShowStateKey);
- }
- }
-
- ui::WindowShowState GetShowStateAndReset() {
- ui::WindowShowState ret = show_state_;
- show_state_ = ui::SHOW_STATE_END;
- return ret;
- }
-
- private:
- aura::Window* window_;
- ui::WindowShowState show_state_;
-
- DISALLOW_COPY_AND_ASSIGN(FocusDelegate);
-};
-
-// Make sure that the window's show state is correct in
-// |WindowDelegate::OnWindowTargetVisibilityChanged|, and setting
-// focus in this callback doesn't cause DCHECK error. See
-// crbug.com/168383.
-TEST_F(BaseLayoutManagerTest, FocusDuringUnminimize) {
- FocusDelegate delegate;
- scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
- &delegate, 0, gfx::Rect(100, 100, 100, 100)));
- delegate.set_window(window.get());
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
- EXPECT_FALSE(window->IsVisible());
- EXPECT_EQ(ui::SHOW_STATE_MINIMIZED, delegate.GetShowStateAndReset());
- window->Show();
- EXPECT_TRUE(window->IsVisible());
- EXPECT_EQ(ui::SHOW_STATE_DEFAULT, delegate.GetShowStateAndReset());
-}
-
-// 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->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
- gfx::Rect initial_work_area_bounds =
- ScreenUtil::GetMaximizedWindowBoundsInParent(window.get());
- EXPECT_EQ(initial_work_area_bounds.ToString(), window->bounds().ToString());
- // Enlarge the root window. We should still match the work area size.
- UpdateDisplay("900x700");
- EXPECT_EQ(
- ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
- window->bounds().ToString());
- EXPECT_NE(
- initial_work_area_bounds.ToString(),
- ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString());
-}
-
-// Tests normal->fullscreen->normal.
-TEST_F(BaseLayoutManagerTest, Fullscreen) {
- gfx::Rect bounds(100, 100, 200, 200);
- scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
- // Fullscreen window fills the whole display.
- EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
- window.get()).bounds().ToString(),
- window->bounds().ToString());
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
- EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
-}
-
-// 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 display.
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
- EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
- window.get()).bounds().ToString(),
- window->bounds().ToString());
- // Enlarge the root window. We should still match the display size.
- UpdateDisplay("800x600");
- EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
- window.get()).bounds().ToString(),
- window->bounds().ToString());
-}
-
-// 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 = Shell::GetScreen()->GetDisplayNearestWindow(
- window.get()).work_area();
- // 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.
- UpdateDisplay("300x400");
- work_area = Shell::GetScreen()->GetDisplayNearestWindow(
- window.get()).work_area();
- EXPECT_LE(window->bounds().width(), work_area.width());
- EXPECT_LE(window->bounds().height(), work_area.height());
-
- // Make the root window shorter than our window.
- UpdateDisplay("300x200");
- work_area = Shell::GetScreen()->GetDisplayNearestWindow(
- window.get()).work_area();
- 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();
- UpdateDisplay("800x600");
- EXPECT_EQ(old_bounds.width(), window->bounds().width());
- EXPECT_EQ(old_bounds.height(), window->bounds().height());
-}
-
-// Tests that a maximized window with too-large restore bounds will be restored
-// to smaller than the full work area.
-TEST_F(BaseLayoutManagerTest, BoundsWithScreenEdgeVisible) {
- // Create a window with bounds that fill the screen.
- gfx::Rect bounds = Shell::GetScreen()->GetPrimaryDisplay().bounds();
- scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
- // Maximize it, which writes the old bounds to restore bounds.
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
- // Restore it.
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
- // It should have the default maximized window bounds, inset by the grid size.
- int grid_size = internal::WorkspaceWindowResizer::kScreenEdgeInset;
- gfx::Rect max_bounds =
- ash::ScreenUtil::GetMaximizedWindowBoundsInParent(window.get());
- max_bounds.Inset(grid_size, grid_size);
- EXPECT_EQ(max_bounds.ToString(), window->bounds().ToString());
-}
-
-// Verifies maximizing sets the restore bounds, and restoring
-// restores the bounds.
-TEST_F(BaseLayoutManagerTest, MaximizeSetsRestoreBounds) {
- scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
- wm::WindowState* window_state = wm::GetWindowState(window.get());
-
- // Maximize it, which will keep the previous restore bounds.
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
- EXPECT_EQ("1,2 3x4", window_state->GetRestoreBoundsInParent().ToString());
-
- // Restore it, which should restore bounds and reset restore bounds.
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
- EXPECT_EQ("1,2 3x4", window->bounds().ToString());
- EXPECT_FALSE(window_state->HasRestoreBounds());
-}
-
-// Verifies maximizing keeps the restore bounds if set.
-TEST_F(BaseLayoutManagerTest, MaximizeResetsRestoreBounds) {
- scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
-
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- window_state->SetRestoreBoundsInParent(gfx::Rect(10, 11, 12, 13));
-
- // Maximize it, which will keep the previous restore bounds.
- window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
- EXPECT_EQ("10,11 12x13", window_state->GetRestoreBoundsInParent().ToString());
-}
-
-// Verifies that the restore bounds do not get reset when restoring to a
-// maximzied state from a minimized state.
-TEST_F(BaseLayoutManagerTest, BoundsAfterRestoringToMaximizeFromMinimize) {
- scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
- gfx::Rect bounds(10, 15, 25, 35);
- window->SetBounds(bounds);
-
- wm::WindowState* window_state = wm::GetWindowState(window.get());
- // Maximize it, which should reset restore bounds.
- window_state->Maximize();
- EXPECT_EQ(bounds.ToString(),
- window_state->GetRestoreBoundsInParent().ToString());
-
- // Minimize the window. The restore bounds should not change.
- window_state->Minimize();
- EXPECT_EQ(bounds.ToString(),
- window_state->GetRestoreBoundsInParent().ToString());
-
- // Show the window again. The window should be maximized, and the restore
- // bounds should not change.
- window->Show();
- EXPECT_EQ(bounds.ToString(),
- window_state->GetRestoreBoundsInParent().ToString());
- EXPECT_TRUE(window_state->IsMaximized());
-
- window_state->Restore();
- EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
-}
-
-// Verify if the window is not resized during screen lock. See: crbug.com/173127
-TEST_F(BaseLayoutManagerTest, NotResizeWhenScreenIsLocked) {
- SetCanLockScreen(true);
- scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
- // window with AlwaysOnTop will be managed by BaseLayoutManager.
- window->SetProperty(aura::client::kAlwaysOnTopKey, true);
- window->Show();
-
- internal::ShelfLayoutManager* shelf =
- internal::ShelfLayoutManager::ForShelf(window.get());
- shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
-
- window->SetBounds(ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()));
- gfx::Rect window_bounds = window->bounds();
- EXPECT_EQ(
- ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
- window_bounds.ToString());
-
- Shell::GetInstance()->session_state_delegate()->LockScreen();
- shelf->UpdateVisibilityState();
- EXPECT_NE(
- ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
- window_bounds.ToString());
-
- Shell::GetInstance()->session_state_delegate()->UnlockScreen();
- shelf->UpdateVisibilityState();
- EXPECT_EQ(window_bounds.ToString(), window->bounds().ToString());
-}
-
-} // namespace
-} // namespace ash
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc
index 031534a..4e79c6e 100644
--- a/ash/wm/workspace/workspace_layout_manager.cc
+++ b/ash/wm/workspace/workspace_layout_manager.cc
@@ -7,21 +7,25 @@
#include "ash/display/display_controller.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h"
+#include "ash/session_state_delegate.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shell.h"
#include "ash/wm/always_on_top_controller.h"
-#include "ash/wm/base_layout_manager.h"
#include "ash/wm/window_animations.h"
#include "ash/wm/window_positioner.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
+#include "ash/wm/workspace/workspace_window_resizer.h"
+#include "ui/aura/client/activation_client.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/base/ui_base_types.h"
+#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event.h"
+#include "ui/gfx/screen.h"
#include "ui/views/corewm/window_util.h"
using aura::Window;
@@ -65,49 +69,96 @@ void MoveToDisplayForRestore(wm::WindowState* window_state) {
}
}
+gfx::Rect BoundsWithScreenEdgeVisible(
+ aura::Window* window,
+ const gfx::Rect& restore_bounds) {
+ gfx::Rect max_bounds =
+ ash::ScreenUtil::GetMaximizedWindowBoundsInParent(window);
+ // If the restore_bounds are more than 1 grid step away from the size the
+ // window would be when maximized, inset it.
+ max_bounds.Inset(ash::internal::WorkspaceWindowResizer::kScreenEdgeInset,
+ ash::internal::WorkspaceWindowResizer::kScreenEdgeInset);
+ if (restore_bounds.Contains(max_bounds))
+ return max_bounds;
+ return restore_bounds;
+}
+
} // namespace
WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window)
- : BaseLayoutManager(window->GetRootWindow()),
- shelf_(NULL),
+ : shelf_(NULL),
window_(window),
+ root_window_(window->GetRootWindow()),
work_area_in_parent_(ScreenUtil::ConvertRectFromScreen(
window_,
Shell::GetScreen()->GetDisplayNearestWindow(window_).work_area())),
is_fullscreen_(GetRootWindowController(
window->GetRootWindow())->GetWindowForFullscreenMode() != NULL) {
+ Shell::GetInstance()->activation_client()->AddObserver(this);
+ Shell::GetInstance()->AddShellObserver(this);
+ root_window_->AddObserver(this);
}
WorkspaceLayoutManager::~WorkspaceLayoutManager() {
+ if (root_window_)
+ root_window_->RemoveObserver(this);
+ for (WindowSet::const_iterator i = windows_.begin(); i != windows_.end(); ++i)
+ (*i)->RemoveObserver(this);
+ Shell::GetInstance()->RemoveShellObserver(this);
+ Shell::GetInstance()->activation_client()->RemoveObserver(this);
}
void WorkspaceLayoutManager::SetShelf(internal::ShelfLayoutManager* shelf) {
shelf_ = shelf;
}
+//////////////////////////////////////////////////////////////////////////////
+// WorkspaceLayoutManager, aura::LayoutManager implementation:
+
void WorkspaceLayoutManager::OnWindowAddedToLayout(Window* child) {
AdjustWindowBoundsWhenAdded(wm::GetWindowState(child));
- BaseLayoutManager::OnWindowAddedToLayout(child);
+
+ windows_.insert(child);
+ child->AddObserver(this);
+ wm::WindowState* window_state = wm::GetWindowState(child);
+ window_state->AddObserver(this);
+
+ // Only update the bounds if the window has a show state that depends on the
+ // workspace area.
+ if (window_state->IsMaximized()) {
+ SetChildBoundsDirect(
+ child, ScreenUtil::GetMaximizedWindowBoundsInParent(child));
+ } else if (window_state->IsFullscreen()) {
+ SetChildBoundsDirect(
+ child, ScreenUtil::GetDisplayBoundsInParent(child));
+ }
+
UpdateShelfVisibility();
UpdateFullscreenState();
WindowPositioner::RearrangeVisibleWindowOnShow(child);
}
void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout(Window* child) {
- BaseLayoutManager::OnWillRemoveWindowFromLayout(child);
+ windows_.erase(child);
+ child->RemoveObserver(this);
+ wm::GetWindowState(child)->RemoveObserver(this);
+
if (child->TargetVisibility())
WindowPositioner::RearrangeVisibleWindowOnHideOrRemove(child);
}
void WorkspaceLayoutManager::OnWindowRemovedFromLayout(Window* child) {
- BaseLayoutManager::OnWindowRemovedFromLayout(child);
UpdateShelfVisibility();
UpdateFullscreenState();
}
void WorkspaceLayoutManager::OnChildWindowVisibilityChanged(Window* child,
bool visible) {
- BaseLayoutManager::OnChildWindowVisibilityChanged(child, visible);
+ wm::WindowState* window_state = wm::GetWindowState(child);
+ // Attempting to show a minimized window. Unminimize it.
+ if (visible && window_state->IsMinimized())
+ window_state->Unminimize();
+
if (child->TargetVisibility()) {
WindowPositioner::RearrangeVisibleWindowOnShow(child);
} else {
@@ -139,6 +190,9 @@ void WorkspaceLayoutManager::SetChildBounds(
UpdateShelfVisibility();
}
+//////////////////////////////////////////////////////////////////////////////
+// WorkspaceLayoutManager, ash::ShellObserver implementation:
+
void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() {
const gfx::Rect work_area(ScreenUtil::ConvertRectFromScreen(
window_,
@@ -149,6 +203,9 @@ void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() {
}
}
+//////////////////////////////////////////////////////////////////////////////
+// WorkspaceLayoutManager, aura::WindowObserver implementation:
+
void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window,
const void* key,
intptr_t old) {
@@ -160,11 +217,41 @@ void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window,
}
void WorkspaceLayoutManager::OnWindowStackingChanged(aura::Window* window) {
- BaseLayoutManager::OnWindowStackingChanged(window);
UpdateShelfVisibility();
UpdateFullscreenState();
}
+void WorkspaceLayoutManager::OnWindowDestroying(aura::Window* window) {
+ if (root_window_ == window) {
+ root_window_->RemoveObserver(this);
+ root_window_ = NULL;
+ }
+}
+
+void WorkspaceLayoutManager::OnWindowBoundsChanged(aura::Window* window,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) {
+ if (root_window_ == window)
+ AdjustAllWindowsBoundsForWorkAreaChange(ADJUST_WINDOW_DISPLAY_SIZE_CHANGED);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// WorkspaceLayoutManager,
+// aura::client::ActivationChangeObserver implementation:
+
+void WorkspaceLayoutManager::OnWindowActivated(aura::Window* gained_active,
+ aura::Window* lost_active) {
+ wm::WindowState* window_state = wm::GetWindowState(gained_active);
+ if (window_state && window_state->IsMinimized() &&
+ !gained_active->IsVisible()) {
+ window_state->Unminimize();
+ DCHECK(!window_state->IsMinimized());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// WorkspaceLayoutManager, wm::WindowStateObserver implementation:
+
void WorkspaceLayoutManager::OnWindowShowTypeChanged(
wm::WindowState* window_state,
wm::WindowShowType old_type) {
@@ -204,12 +291,63 @@ void WorkspaceLayoutManager::OnWindowShowTypeChanged(
UpdateShelfVisibility();
}
+void WorkspaceLayoutManager::ShowTypeChanged(
+ wm::WindowState* window_state,
+ wm::WindowShowType last_show_type) {
+ if (window_state->IsMinimized()) {
+ if (last_show_type == wm::SHOW_TYPE_MINIMIZED)
+ return;
+
+ // Save the previous show state so that we can correctly restore it.
+ window_state->window()->SetProperty(aura::client::kRestoreShowStateKey,
+ wm::ToWindowShowState(last_show_type));
+ views::corewm::SetWindowVisibilityAnimationType(
+ window_state->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
+
+ // Hide the window.
+ window_state->window()->Hide();
+ // Activate another window.
+ if (window_state->IsActive())
+ window_state->Deactivate();
+ } else if ((window_state->window()->TargetVisibility() ||
+ last_show_type == wm::SHOW_TYPE_MINIMIZED) &&
+ !window_state->window()->layer()->visible()) {
+ // The layer may be hidden if the window was previously minimized. Make
+ // sure it's visible.
+ window_state->window()->Show();
+ if (last_show_type == wm::SHOW_TYPE_MINIMIZED &&
+ !window_state->IsMaximizedOrFullscreen()) {
+ window_state->set_unminimize_to_restore_bounds(false);
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// WorkspaceLayoutManager, private:
+
void WorkspaceLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(
AdjustWindowReason reason) {
work_area_in_parent_ = ScreenUtil::ConvertRectFromScreen(
window_,
Shell::GetScreen()->GetDisplayNearestWindow(window_).work_area());
- BaseLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(reason);
+
+ // Don't do any adjustments of the insets while we are in screen locked mode.
+ // This would happen if the launcher was auto hidden before the login screen
+ // was shown and then gets shown when the login screen gets presented.
+ if (reason == ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED &&
+ Shell::GetInstance()->session_state_delegate()->IsScreenLocked())
+ return;
+
+ // If a user plugs an external display into a laptop running Aura the
+ // display 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.
+ // We also need to do this when the work area insets changes.
+ for (WindowSet::const_iterator it = windows_.begin();
+ it != windows_.end();
+ ++it) {
+ AdjustWindowBoundsForWorkAreaChange(wm::GetWindowState(*it), reason);
+ }
}
void WorkspaceLayoutManager::AdjustWindowBoundsForWorkAreaChange(
@@ -322,7 +460,7 @@ void WorkspaceLayoutManager::UpdateBoundsFromShowType(
show_type == wm::SHOW_TYPE_RIGHT_SNAPPED) {
AdjustSnappedBounds(window_state, &bounds_in_parent);
} else {
- bounds_in_parent = BaseLayoutManager::BoundsWithScreenEdgeVisible(
+ bounds_in_parent = BoundsWithScreenEdgeVisible(
window,
bounds_in_parent);
}
diff --git a/ash/wm/workspace/workspace_layout_manager.h b/ash/wm/workspace/workspace_layout_manager.h
index 906a04a..8cd44cc 100644
--- a/ash/wm/workspace/workspace_layout_manager.h
+++ b/ash/wm/workspace/workspace_layout_manager.h
@@ -7,11 +7,14 @@
#include <set>
+#include "ash/ash_export.h"
#include "ash/shell_observer.h"
-#include "ash/wm/base_layout_manager.h"
+#include "ash/wm/window_state_observer.h"
#include "ash/wm/wm_types.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "ui/aura/client/activation_change_observer.h"
+#include "ui/aura/layout_manager.h"
#include "ui/aura/window_observer.h"
#include "ui/gfx/rect.h"
@@ -25,13 +28,21 @@ class Layer;
}
namespace ash {
+namespace wm {
+class WindowState;
+}
namespace internal {
class ShelfLayoutManager;
// LayoutManager used on the window created for a workspace.
-class ASH_EXPORT WorkspaceLayoutManager : public BaseLayoutManager {
+class ASH_EXPORT WorkspaceLayoutManager
+ : public aura::LayoutManager,
+ public aura::WindowObserver,
+ public aura::client::ActivationChangeObserver,
+ public ShellObserver,
+ public wm::WindowStateObserver {
public:
explicit WorkspaceLayoutManager(aura::Window* window);
virtual ~WorkspaceLayoutManager();
@@ -56,18 +67,45 @@ class ASH_EXPORT WorkspaceLayoutManager : public BaseLayoutManager {
const void* key,
intptr_t old) OVERRIDE;
virtual void OnWindowStackingChanged(aura::Window* window) OVERRIDE;
+ virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
+ virtual void OnWindowBoundsChanged(aura::Window* window,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) OVERRIDE;
+
+ // aura::client::ActivationChangeObserver overrides:
+ virtual void OnWindowActivated(aura::Window* gained_active,
+ aura::Window* lost_active) OVERRIDE;
// WindowStateObserver overrides:
virtual void OnWindowShowTypeChanged(wm::WindowState* window_state,
wm::WindowShowType old_type) OVERRIDE;
private:
- // Overridden from BaseLayoutManager:
- virtual void AdjustAllWindowsBoundsForWorkAreaChange(
- AdjustWindowReason reason) OVERRIDE;
- virtual void AdjustWindowBoundsForWorkAreaChange(
- wm::WindowState* window_state,
- AdjustWindowReason reason) OVERRIDE;
+ typedef std::set<aura::Window*> WindowSet;
+
+ enum AdjustWindowReason {
+ ADJUST_WINDOW_DISPLAY_SIZE_CHANGED,
+ ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED,
+ };
+
+ // Invoked from OnWindowShowTypeChanged().
+ void ShowTypeChanged(wm::WindowState* window_state,
+ wm::WindowShowType last_show_type);
+
+ // Adjusts the window's bounds when the display area changes for given
+ // window. This happens when the display size, work area insets or
+ // the display on which the window exists has changed.
+ // If this is called for a display size change (i.e. |reason|
+ // is ADJUST_WINDOW_DISPLAY_SIZE_CHANGED), the non-maximized/non-fullscreen
+ // windows are readjusted to make sure the window is completely within the
+ // display region. Otherwise, it makes sure at least some parts of the window
+ // is on display.
+ void AdjustAllWindowsBoundsForWorkAreaChange(AdjustWindowReason reason);
+
+ // Adjusts the sizes of the specific window in respond to a screen change or
+ // display-area size change.
+ void AdjustWindowBoundsForWorkAreaChange(wm::WindowState* window_state,
+ AdjustWindowReason reason);
void AdjustWindowBoundsWhenAdded(wm::WindowState* window_state);
@@ -96,6 +134,10 @@ class ASH_EXPORT WorkspaceLayoutManager : public BaseLayoutManager {
internal::ShelfLayoutManager* shelf_;
aura::Window* window_;
+ aura::Window* root_window_;
+
+ // Set of windows we're listening to.
+ WindowSet windows_;
// The work area in the coordinates of |window_|.
gfx::Rect work_area_in_parent_;
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc
index 41e067f..8baf51c 100644
--- a/ash/wm/workspace/workspace_layout_manager_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -8,18 +8,24 @@
#include "ash/display/display_manager.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h"
+#include "ash/session_state_delegate.h"
#include "ash/shelf/shelf_layout_manager.h"
-#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/shell_observer.h"
+#include "ash/shell_window_ids.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
+#include "ash/wm/workspace/workspace_window_resizer.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/test/test_windows.h"
#include "ui/aura/window.h"
+#include "ui/base/ui_base_types.h"
#include "ui/gfx/insets.h"
+#include "ui/gfx/screen.h"
#include "ui/views/corewm/window_util.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
@@ -479,4 +485,292 @@ TEST_F(WorkspaceLayoutManagerTest, NotifyFullscreenChanges) {
EXPECT_FALSE(observer.is_fullscreen());
}
+// Following tests were originally written for BaseLayoutManager.
+
+namespace {
+
+class WorkspaceLayoutManagerSoloTest : public test::AshTestBase {
+ public:
+ WorkspaceLayoutManagerSoloTest() {}
+ virtual ~WorkspaceLayoutManagerSoloTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ test::AshTestBase::SetUp();
+ UpdateDisplay("800x600");
+ aura::Window* default_container = Shell::GetContainer(
+ Shell::GetPrimaryRootWindow(),
+ internal::kShellWindowId_DefaultContainer);
+ default_container->SetLayoutManager(new internal::WorkspaceLayoutManager(
+ Shell::GetPrimaryRootWindow()));
+ }
+
+ aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
+ return CreateTestWindowInShellWithBounds(bounds);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerSoloTest);
+};
+
+} // namespace
+
+// Tests normal->maximize->normal.
+TEST_F(WorkspaceLayoutManagerSoloTest, Maximize) {
+ gfx::Rect bounds(100, 100, 200, 200);
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
+ // Maximized window fills the work area, not the whole display.
+ EXPECT_EQ(
+ ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
+ window->bounds().ToString());
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+ EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
+}
+
+// Tests normal->minimize->normal.
+TEST_F(WorkspaceLayoutManagerSoloTest, Minimize) {
+ gfx::Rect bounds(100, 100, 200, 200);
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
+ // Note: Currently minimize doesn't do anything except set the state.
+ // See crbug.com/104571.
+ EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+ EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
+}
+
+// A WindowDelegate which sets the focus when the window
+// becomes visible.
+class FocusDelegate : public aura::test::TestWindowDelegate {
+ public:
+ FocusDelegate()
+ : window_(NULL),
+ show_state_(ui::SHOW_STATE_END) {
+ }
+ virtual ~FocusDelegate() {}
+
+ void set_window(aura::Window* window) { window_ = window; }
+
+ // aura::test::TestWindowDelegate overrides:
+ virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
+ if (window_) {
+ if (visible)
+ window_->Focus();
+ show_state_ = window_->GetProperty(aura::client::kShowStateKey);
+ }
+ }
+
+ ui::WindowShowState GetShowStateAndReset() {
+ ui::WindowShowState ret = show_state_;
+ show_state_ = ui::SHOW_STATE_END;
+ return ret;
+ }
+
+ private:
+ aura::Window* window_;
+ ui::WindowShowState show_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(FocusDelegate);
+};
+
+// Make sure that the window's show state is correct in
+// |WindowDelegate::OnWindowTargetVisibilityChanged|, and setting
+// focus in this callback doesn't cause DCHECK error. See
+// crbug.com/168383.
+TEST_F(WorkspaceLayoutManagerSoloTest, FocusDuringUnminimize) {
+ FocusDelegate delegate;
+ scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
+ &delegate, 0, gfx::Rect(100, 100, 100, 100)));
+ delegate.set_window(window.get());
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
+ EXPECT_FALSE(window->IsVisible());
+ EXPECT_EQ(ui::SHOW_STATE_MINIMIZED, delegate.GetShowStateAndReset());
+ window->Show();
+ EXPECT_TRUE(window->IsVisible());
+ EXPECT_EQ(ui::SHOW_STATE_DEFAULT, delegate.GetShowStateAndReset());
+}
+
+// Tests maximized window size during root window resize.
+TEST_F(WorkspaceLayoutManagerSoloTest, MaximizeRootWindowResize) {
+ gfx::Rect bounds(100, 100, 200, 200);
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
+ gfx::Rect initial_work_area_bounds =
+ ScreenUtil::GetMaximizedWindowBoundsInParent(window.get());
+ EXPECT_EQ(initial_work_area_bounds.ToString(), window->bounds().ToString());
+ // Enlarge the root window. We should still match the work area size.
+ UpdateDisplay("900x700");
+ EXPECT_EQ(
+ ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
+ window->bounds().ToString());
+ EXPECT_NE(
+ initial_work_area_bounds.ToString(),
+ ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString());
+}
+
+// Tests normal->fullscreen->normal.
+TEST_F(WorkspaceLayoutManagerSoloTest, Fullscreen) {
+ gfx::Rect bounds(100, 100, 200, 200);
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
+ // Fullscreen window fills the whole display.
+ EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
+ window.get()).bounds().ToString(),
+ window->bounds().ToString());
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+ EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
+}
+
+// Tests fullscreen window size during root window resize.
+TEST_F(WorkspaceLayoutManagerSoloTest, FullscreenRootWindowResize) {
+ gfx::Rect bounds(100, 100, 200, 200);
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ // Fullscreen window fills the whole display.
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
+ EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
+ window.get()).bounds().ToString(),
+ window->bounds().ToString());
+ // Enlarge the root window. We should still match the display size.
+ UpdateDisplay("800x600");
+ EXPECT_EQ(Shell::GetScreen()->GetDisplayNearestWindow(
+ window.get()).bounds().ToString(),
+ window->bounds().ToString());
+}
+
+// Tests that when the screen gets smaller the windows aren't bigger than
+// the screen.
+TEST_F(WorkspaceLayoutManagerSoloTest, RootWindowResizeShrinksWindows) {
+ scoped_ptr<aura::Window> window(
+ CreateTestWindow(gfx::Rect(10, 20, 500, 400)));
+ gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
+ window.get()).work_area();
+ // 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.
+ UpdateDisplay("300x400");
+ work_area = Shell::GetScreen()->GetDisplayNearestWindow(
+ window.get()).work_area();
+ EXPECT_LE(window->bounds().width(), work_area.width());
+ EXPECT_LE(window->bounds().height(), work_area.height());
+
+ // Make the root window shorter than our window.
+ UpdateDisplay("300x200");
+ work_area = Shell::GetScreen()->GetDisplayNearestWindow(
+ window.get()).work_area();
+ 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();
+ UpdateDisplay("800x600");
+ EXPECT_EQ(old_bounds.width(), window->bounds().width());
+ EXPECT_EQ(old_bounds.height(), window->bounds().height());
+}
+
+// Tests that a maximized window with too-large restore bounds will be restored
+// to smaller than the full work area.
+TEST_F(WorkspaceLayoutManagerSoloTest, BoundsWithScreenEdgeVisible) {
+ // Create a window with bounds that fill the screen.
+ gfx::Rect bounds = Shell::GetScreen()->GetPrimaryDisplay().bounds();
+ scoped_ptr<aura::Window> window(CreateTestWindow(bounds));
+ // Maximize it, which writes the old bounds to restore bounds.
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
+ // Restore it.
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+ // It should have the default maximized window bounds, inset by the grid size.
+ int grid_size = internal::WorkspaceWindowResizer::kScreenEdgeInset;
+ gfx::Rect max_bounds =
+ ash::ScreenUtil::GetMaximizedWindowBoundsInParent(window.get());
+ max_bounds.Inset(grid_size, grid_size);
+ EXPECT_EQ(max_bounds.ToString(), window->bounds().ToString());
+}
+
+// Verifies maximizing sets the restore bounds, and restoring
+// restores the bounds.
+TEST_F(WorkspaceLayoutManagerSoloTest, MaximizeSetsRestoreBounds) {
+ scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(10, 20, 30, 40)));
+ wm::WindowState* window_state = wm::GetWindowState(window.get());
+
+ // Maximize it, which will keep the previous restore bounds.
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
+ EXPECT_EQ("10,20 30x40", window_state->GetRestoreBoundsInParent().ToString());
+
+ // Restore it, which should restore bounds and reset restore bounds.
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+ EXPECT_EQ("10,20 30x40", window->bounds().ToString());
+ EXPECT_FALSE(window_state->HasRestoreBounds());
+}
+
+// Verifies maximizing keeps the restore bounds if set.
+TEST_F(WorkspaceLayoutManagerSoloTest, MaximizeResetsRestoreBounds) {
+ scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
+
+ wm::WindowState* window_state = wm::GetWindowState(window.get());
+ window_state->SetRestoreBoundsInParent(gfx::Rect(10, 11, 12, 13));
+
+ // Maximize it, which will keep the previous restore bounds.
+ window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
+ EXPECT_EQ("10,11 12x13", window_state->GetRestoreBoundsInParent().ToString());
+}
+
+// Verifies that the restore bounds do not get reset when restoring to a
+// maximzied state from a minimized state.
+TEST_F(WorkspaceLayoutManagerSoloTest,
+ BoundsAfterRestoringToMaximizeFromMinimize) {
+ scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
+ gfx::Rect bounds(10, 15, 25, 35);
+ window->SetBounds(bounds);
+
+ wm::WindowState* window_state = wm::GetWindowState(window.get());
+ // Maximize it, which should reset restore bounds.
+ window_state->Maximize();
+ EXPECT_EQ(bounds.ToString(),
+ window_state->GetRestoreBoundsInParent().ToString());
+ // Minimize the window. The restore bounds should not change.
+ window_state->Minimize();
+ EXPECT_EQ(bounds.ToString(),
+ window_state->GetRestoreBoundsInParent().ToString());
+
+ // Show the window again. The window should be maximized, and the restore
+ // bounds should not change.
+ window->Show();
+ EXPECT_EQ(bounds.ToString(),
+ window_state->GetRestoreBoundsInParent().ToString());
+ EXPECT_TRUE(window_state->IsMaximized());
+
+ window_state->Restore();
+ EXPECT_EQ(bounds.ToString(), window->bounds().ToString());
+}
+
+// Verify if the window is not resized during screen lock. See: crbug.com/173127
+TEST_F(WorkspaceLayoutManagerSoloTest, NotResizeWhenScreenIsLocked) {
+ SetCanLockScreen(true);
+ scoped_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(1, 2, 3, 4)));
+ // window with AlwaysOnTop will be managed by BaseLayoutManager.
+ window->SetProperty(aura::client::kAlwaysOnTopKey, true);
+ window->Show();
+
+ internal::ShelfLayoutManager* shelf =
+ internal::ShelfLayoutManager::ForShelf(window.get());
+ shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
+
+ window->SetBounds(ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()));
+ gfx::Rect window_bounds = window->bounds();
+ EXPECT_EQ(
+ ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
+ window_bounds.ToString());
+
+ Shell::GetInstance()->session_state_delegate()->LockScreen();
+ shelf->UpdateVisibilityState();
+ EXPECT_NE(
+ ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()).ToString(),
+ window_bounds.ToString());
+
+ Shell::GetInstance()->session_state_delegate()->UnlockScreen();
+ shelf->UpdateVisibilityState();
+ EXPECT_EQ(window_bounds.ToString(), window->bounds().ToString());
+}
+
} // namespace ash
diff --git a/ash/wm/workspace_controller.cc b/ash/wm/workspace_controller.cc
index fa162e4..d869d13 100644
--- a/ash/wm/workspace_controller.cc
+++ b/ash/wm/workspace_controller.cc
@@ -8,7 +8,6 @@
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
-#include "ash/wm/base_layout_manager.h"
#include "ash/wm/window_animations.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"