summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/wm/maximize_mode/maximize_mode_window_manager.cc13
-rw-r--r--ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc171
-rw-r--r--ash/wm/maximize_mode/maximize_mode_window_state.cc15
-rw-r--r--chrome/browser/ui/views/apps/chrome_native_app_window_views.cc3
4 files changed, 175 insertions, 27 deletions
diff --git a/ash/wm/maximize_mode/maximize_mode_window_manager.cc b/ash/wm/maximize_mode/maximize_mode_window_manager.cc
index 9514b4f..964f77a 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_manager.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_manager.cc
@@ -11,6 +11,7 @@
#include "ash/wm/maximize_mode/workspace_backdrop_delegate.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/window_selector_controller.h"
+#include "ash/wm/wm_event.h"
#include "ash/wm/workspace_controller.h"
#include "ui/aura/window.h"
#include "ui/gfx/screen.h"
@@ -62,12 +63,18 @@ void MaximizeModeWindowManager::OnWindowDestroying(aura::Window* window) {
ForgetWindow(window);
}
-void MaximizeModeWindowManager::OnWindowAdded(
- aura::Window* window) {
+void MaximizeModeWindowManager::OnWindowAdded(aura::Window* window) {
// A window can get removed and then re-added by a drag and drop operation.
if (IsContainerWindow(window->parent()) &&
- window_state_map_.find(window) == window_state_map_.end())
+ window_state_map_.find(window) == window_state_map_.end()) {
MaximizeAndTrackWindow(window);
+ // When the state got added, the "WM_EVENT_ADDED_TO_WORKSPACE" event got
+ // already sent and we have to notify our state again.
+ if (window_state_map_.find(window) != window_state_map_.end()) {
+ wm::WMEvent event(wm::WM_EVENT_ADDED_TO_WORKSPACE);
+ wm::GetWindowState(window)->OnWMEvent(&event);
+ }
+ }
}
void MaximizeModeWindowManager::OnWindowBoundsChanged(
diff --git a/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc b/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
index 0cc96ff..9f2c5d6 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
@@ -4,6 +4,7 @@
#include "ash/wm/maximize_mode/maximize_mode_window_manager.h"
+#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/switchable_windows.h"
#include "ash/test/ash_test_base.h"
@@ -31,17 +32,27 @@ class MaximizeModeWindowManagerTest : public test::AshTestBase {
MaximizeModeWindowManagerTest() {}
virtual ~MaximizeModeWindowManagerTest() {}
- // Creates a window. Note: This function will only work with a single root
- // window.
+ // Creates a window which has a fixed size.
+ aura::Window* CreateFixedSizeNonMaximizableWindow(ui::wm::WindowType type,
+ const gfx::Rect& bounds) {
+ return CreateWindowInWatchedContainer(
+ type, bounds, gfx::Size(), false, false);
+ }
+
+ // Creates a window which can not be maximized, but resized. |max_size|
+ // denotes the maximal possible size, if the size is empty, the window has no
+ // upper limit. Note: This function will only work with a single root window.
aura::Window* CreateNonMaximizableWindow(ui::wm::WindowType type,
- const gfx::Rect& bounds) {
- return CreateWindowInWatchedContainer(type, bounds, false);
+ const gfx::Rect& bounds,
+ const gfx::Size& max_size) {
+ return CreateWindowInWatchedContainer(type, bounds, max_size, false, true);
}
- // Creates a window.
+ // Creates a maximizable and resizable window.
aura::Window* CreateWindow(ui::wm::WindowType type,
const gfx::Rect bounds) {
- return CreateWindowInWatchedContainer(type, bounds, true);
+ return CreateWindowInWatchedContainer(
+ type, bounds, gfx::Size(), true, true);
}
// Create the Maximized mode window manager.
@@ -74,17 +85,25 @@ class MaximizeModeWindowManagerTest : public test::AshTestBase {
private:
// Create a window in one of the containers which are watched by the
// MaximizeModeWindowManager. Note that this only works with one root window.
+ // If |can_maximize| is not set, |max_size| is the upper limiting size for
+ // the window, whereas an empty size means that there is no limit.
aura::Window* CreateWindowInWatchedContainer(ui::wm::WindowType type,
const gfx::Rect& bounds,
- bool can_maximize) {
+ const gfx::Size& max_size,
+ bool can_maximize,
+ bool can_resize) {
aura::test::TestWindowDelegate* delegate = NULL;
if (!can_maximize) {
delegate = aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate();
delegate->set_window_component(HTCAPTION);
+ if (!max_size.IsEmpty())
+ delegate->set_maximum_size(max_size);
}
aura::Window* window = aura::test::CreateTestWindowWithDelegateAndType(
delegate, type, 0, bounds, NULL);
window->SetProperty(aura::client::kCanMaximizeKey, can_maximize);
+ if (!can_resize)
+ window->SetProperty(aura::client::kCanResizeKey, false);
aura::Window* container = Shell::GetContainer(
Shell::GetPrimaryRootWindow(),
kSwitchableWindowContainerIds[0]);
@@ -116,7 +135,7 @@ TEST_F(MaximizeModeWindowManagerTest, PreCreateWindows) {
scoped_ptr<aura::Window> w1(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect1));
scoped_ptr<aura::Window> w2(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect2));
scoped_ptr<aura::Window> w3(
- CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect3));
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect3));
scoped_ptr<aura::Window> w4(CreateWindow(ui::wm::WINDOW_TYPE_PANEL, rect));
scoped_ptr<aura::Window> w5(CreateWindow(ui::wm::WINDOW_TYPE_POPUP, rect));
scoped_ptr<aura::Window> w6(CreateWindow(ui::wm::WINDOW_TYPE_CONTROL, rect));
@@ -168,6 +187,64 @@ TEST_F(MaximizeModeWindowManagerTest, PreCreateWindows) {
EXPECT_EQ(rect.ToString(), w8->bounds().ToString());
}
+// Test that non-maximizable windows get properly handled when going into
+// maximized mode.
+TEST_F(MaximizeModeWindowManagerTest,
+ PreCreateNonMaximizableButResizableWindows) {
+ // The window bounds.
+ gfx::Rect rect(10, 10, 200, 50);
+ gfx::Size max_size(300, 200);
+ gfx::Size empty_size;
+ scoped_ptr<aura::Window> unlimited_window(
+ CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect, empty_size));
+ scoped_ptr<aura::Window> limited_window(
+ CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect, max_size));
+ scoped_ptr<aura::Window> fixed_window(
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
+ EXPECT_FALSE(wm::GetWindowState(unlimited_window.get())->IsMaximized());
+ EXPECT_EQ(rect.ToString(), unlimited_window->bounds().ToString());
+ EXPECT_FALSE(wm::GetWindowState(limited_window.get())->IsMaximized());
+ EXPECT_EQ(rect.ToString(), limited_window->bounds().ToString());
+ EXPECT_FALSE(wm::GetWindowState(fixed_window.get())->IsMaximized());
+ EXPECT_EQ(rect.ToString(), fixed_window->bounds().ToString());
+
+ gfx::Size workspace_size = ScreenUtil::GetMaximizedWindowBoundsInParent(
+ unlimited_window.get()).size();
+
+ // Create the manager and make sure that all qualifying windows were detected
+ // and changed.
+ ash::MaximizeModeWindowManager* manager = CreateMaximizeModeWindowManager();
+ ASSERT_TRUE(manager);
+ EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
+ // The unlimited window should have the size of the workspace / parent window.
+ EXPECT_FALSE(wm::GetWindowState(unlimited_window.get())->IsMaximized());
+ EXPECT_EQ("0,0", unlimited_window->bounds().origin().ToString());
+ EXPECT_EQ(workspace_size.ToString(),
+ unlimited_window->bounds().size().ToString());
+ // The limited window should have the size of the upper possible bounds.
+ EXPECT_FALSE(wm::GetWindowState(limited_window.get())->IsMaximized());
+ EXPECT_NE(rect.origin().ToString(),
+ limited_window->bounds().origin().ToString());
+ EXPECT_EQ(max_size.ToString(),
+ limited_window->bounds().size().ToString());
+ // The fixed size window should have the size of the original window.
+ EXPECT_FALSE(wm::GetWindowState(fixed_window.get())->IsMaximized());
+ EXPECT_NE(rect.origin().ToString(),
+ fixed_window->bounds().origin().ToString());
+ EXPECT_EQ(rect.size().ToString(),
+ fixed_window->bounds().size().ToString());
+
+ // Destroy the manager again and check that the windows return to their
+ // previous state.
+ DestroyMaximizeModeWindowManager();
+ EXPECT_FALSE(wm::GetWindowState(unlimited_window.get())->IsMaximized());
+ EXPECT_EQ(rect.ToString(), unlimited_window->bounds().ToString());
+ EXPECT_FALSE(wm::GetWindowState(limited_window.get())->IsMaximized());
+ EXPECT_EQ(rect.ToString(), limited_window->bounds().ToString());
+ EXPECT_FALSE(wm::GetWindowState(fixed_window.get())->IsMaximized());
+ EXPECT_EQ(rect.ToString(), fixed_window->bounds().ToString());
+}
+
// Test that creating windows while a maximizer exists picks them properly up.
TEST_F(MaximizeModeWindowManagerTest, CreateWindows) {
ash::MaximizeModeWindowManager* manager = CreateMaximizeModeWindowManager();
@@ -184,7 +261,7 @@ TEST_F(MaximizeModeWindowManagerTest, CreateWindows) {
scoped_ptr<aura::Window> w1(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect1));
scoped_ptr<aura::Window> w2(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect2));
scoped_ptr<aura::Window> w3(
- CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect3));
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect3));
scoped_ptr<aura::Window> w4(CreateWindow(ui::wm::WINDOW_TYPE_PANEL, rect));
scoped_ptr<aura::Window> w5(CreateWindow(ui::wm::WINDOW_TYPE_POPUP, rect));
scoped_ptr<aura::Window> w6(CreateWindow(ui::wm::WINDOW_TYPE_CONTROL, rect));
@@ -224,6 +301,60 @@ TEST_F(MaximizeModeWindowManagerTest, CreateWindows) {
EXPECT_EQ(rect.ToString(), w8->bounds().ToString());
}
+// Test that non-maximizable windows get properly handled when created in
+// maximized mode.
+TEST_F(MaximizeModeWindowManagerTest,
+ CreateNonMaximizableButResizableWindows) {
+ // Create the manager and make sure that all qualifying windows were detected
+ // and changed.
+ ash::MaximizeModeWindowManager* manager = CreateMaximizeModeWindowManager();
+ ASSERT_TRUE(manager);
+
+ gfx::Rect rect(10, 10, 200, 50);
+ gfx::Size max_size(300, 200);
+ gfx::Size empty_size;
+ scoped_ptr<aura::Window> unlimited_window(
+ CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect, empty_size));
+ scoped_ptr<aura::Window> limited_window(
+ CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect, max_size));
+ scoped_ptr<aura::Window> fixed_window(
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
+
+ gfx::Size workspace_size = ScreenUtil::GetMaximizedWindowBoundsInParent(
+ unlimited_window.get()).size();
+
+ // All windows should be sized now as big as possible and be centered.
+ EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
+ // The unlimited window should have the size of the workspace / parent window.
+ EXPECT_FALSE(wm::GetWindowState(unlimited_window.get())->IsMaximized());
+ EXPECT_EQ("0,0", unlimited_window->bounds().origin().ToString());
+ EXPECT_EQ(workspace_size.ToString(),
+ unlimited_window->bounds().size().ToString());
+ // The limited window should have the size of the upper possible bounds.
+ EXPECT_FALSE(wm::GetWindowState(limited_window.get())->IsMaximized());
+ EXPECT_NE(rect.origin().ToString(),
+ limited_window->bounds().origin().ToString());
+ EXPECT_EQ(max_size.ToString(),
+ limited_window->bounds().size().ToString());
+ // The fixed size window should have the size of the original window.
+ EXPECT_FALSE(wm::GetWindowState(fixed_window.get())->IsMaximized());
+ EXPECT_NE(rect.origin().ToString(),
+ fixed_window->bounds().origin().ToString());
+ EXPECT_EQ(rect.size().ToString(),
+ fixed_window->bounds().size().ToString());
+
+ // Destroy the manager again and check that the windows return to their
+ // creation state.
+ DestroyMaximizeModeWindowManager();
+
+ EXPECT_FALSE(wm::GetWindowState(unlimited_window.get())->IsMaximized());
+ EXPECT_EQ(rect.ToString(), unlimited_window->bounds().ToString());
+ EXPECT_FALSE(wm::GetWindowState(limited_window.get())->IsMaximized());
+ EXPECT_EQ(rect.ToString(), limited_window->bounds().ToString());
+ EXPECT_FALSE(wm::GetWindowState(fixed_window.get())->IsMaximized());
+ EXPECT_EQ(rect.ToString(), fixed_window->bounds().ToString());
+}
+
// Test that windows which got created before the maximizer was created can be
// destroyed while the maximizer is still running.
TEST_F(MaximizeModeWindowManagerTest, PreCreateWindowsDeleteWhileActive) {
@@ -240,7 +371,7 @@ TEST_F(MaximizeModeWindowManagerTest, PreCreateWindowsDeleteWhileActive) {
scoped_ptr<aura::Window> w2(
CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect2));
scoped_ptr<aura::Window> w3(
- CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect3));
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect3));
// Create the manager and make sure that all qualifying windows were
// detected and changed.
@@ -268,8 +399,8 @@ TEST_F(MaximizeModeWindowManagerTest, CreateWindowsAndDeleteWhileActive) {
scoped_ptr<aura::Window> w2(
CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, gfx::Rect(10, 60, 200, 50)));
scoped_ptr<aura::Window> w3(
- CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL,
- gfx::Rect(20, 140, 100, 100)));
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL,
+ gfx::Rect(20, 140, 100, 100)));
// Check that the windows got automatically maximized as well.
EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
EXPECT_TRUE(wm::GetWindowState(w1.get())->IsMaximized());
@@ -346,20 +477,20 @@ TEST_F(MaximizeModeWindowManagerTest, MinimizedWindowBehavior) {
initially_maximized_window.get())->IsMaximized());
}
-// Check that resizing the desktop does reposition unmaximizable & managed
-// windows.
+// Check that resizing the desktop does reposition unmaximizable, unresizable &
+// managed windows.
TEST_F(MaximizeModeWindowManagerTest, DesktopSizeChangeMovesUnmaximizable) {
UpdateDisplay("400x400");
// This window will move because it does not fit the new bounds.
gfx::Rect rect(20, 300, 100, 100);
scoped_ptr<aura::Window> window1(
- CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
EXPECT_EQ(rect.ToString(), window1->bounds().ToString());
// This window will not move because it does fit the new bounds.
gfx::Rect rect2(20, 140, 100, 100);
scoped_ptr<aura::Window> window2(
- CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect2));
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect2));
// Turning on the manager will reposition (but not resize) the window.
ash::MaximizeModeWindowManager* manager = CreateMaximizeModeWindowManager();
@@ -388,7 +519,7 @@ TEST_F(MaximizeModeWindowManagerTest, DesktopSizeChangeMovesUnmaximizable) {
TEST_F(MaximizeModeWindowManagerTest, SizeChangeReturnWindowToOriginalPos) {
gfx::Rect rect(20, 140, 100, 100);
scoped_ptr<aura::Window> window(
- CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
// Turning on the manager will reposition (but not resize) the window.
ash::MaximizeModeWindowManager* manager = CreateMaximizeModeWindowManager();
@@ -417,11 +548,11 @@ TEST_F(MaximizeModeWindowManagerTest, SizeChangeReturnWindowToOriginalPos) {
TEST_F(MaximizeModeWindowManagerTest, ModeChangeKeepsMRUOrder) {
gfx::Rect rect(20, 140, 100, 100);
scoped_ptr<aura::Window> w1(
- CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
scoped_ptr<aura::Window> w2(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
scoped_ptr<aura::Window> w3(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
scoped_ptr<aura::Window> w4(
- CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
scoped_ptr<aura::Window> w5(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
// The windows should be in the reverse order of creation in the MRU list.
@@ -564,7 +695,7 @@ TEST_F(MaximizeModeWindowManagerTest, SnapModeTests) {
TEST_F(MaximizeModeWindowManagerTest, TryToDesktopSizeDragUnmaximizable) {
gfx::Rect rect(10, 10, 100, 100);
scoped_ptr<aura::Window> window(
- CreateNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
+ CreateFixedSizeNonMaximizableWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
EXPECT_EQ(rect.ToString(), window->bounds().ToString());
// 1. Move the mouse over the caption and check that dragging the window does
diff --git a/ash/wm/maximize_mode/maximize_mode_window_state.cc b/ash/wm/maximize_mode/maximize_mode_window_state.cc
index 97b1503..e823455 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_state.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_state.cc
@@ -28,7 +28,7 @@ namespace {
// Returns the biggest possible size for a window which is about to be
// maximized.
gfx::Size GetMaximumSizeOfWindow(wm::WindowState* window_state) {
- DCHECK(window_state->CanMaximize());
+ DCHECK(window_state->CanMaximize() || window_state->CanResize());
gfx::Size workspace_size = ScreenUtil::GetMaximizedWindowBoundsInParent(
window_state->window()).size();
@@ -48,7 +48,8 @@ gfx::Size GetMaximumSizeOfWindow(wm::WindowState* window_state) {
// Returns the maximized and centered bounds of a window.
gfx::Rect GetMaximizedAndCenteredBounds(wm::WindowState* state_object) {
gfx::Rect bounds_in_parent;
- if (state_object->CanMaximize()) {
+ // Make the window as big as possible.
+ if (state_object->CanMaximize() || state_object->CanResize()) {
bounds_in_parent.set_size(GetMaximumSizeOfWindow(state_object));
} else {
// We prefer the user given window dimensions over the current windows
@@ -137,8 +138,14 @@ void MaximizeModeWindowState::OnWMEvent(wm::WindowState* window_state,
case wm::WM_EVENT_SHOW_INACTIVE:
return;
case wm::WM_EVENT_SET_BOUNDS:
- if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED &&
- current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED) {
+ if (current_state_type_ == wm::WINDOW_STATE_TYPE_MAXIMIZED ||
+ window_state->CanResize()) {
+ // In case the window is resizable and / or maximized we ignore the
+ // requested bounds change and resize to the biggest possible size.
+ MaximizeOrCenterWindow(window_state, true);
+ } else if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED) {
+ // In all other cases (except for minimized windows) we respect the
+ // requested bounds and center it to a fully visible area on the screen.
gfx::Rect bounds_in_parent =
(static_cast<const wm::SetBoundsEvent*>(event))->requested_bounds();
bounds_in_parent.ClampToCenteredSize(
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
index 749447e..b51f0fb 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
@@ -164,7 +164,10 @@ class NativeAppWindowStateDelegate : public ash::wm::WindowStateDelegate,
virtual void OnPostWindowStateTypeChange(
ash::wm::WindowState* window_state,
ash::wm::WindowStateType old_type) OVERRIDE {
+ // Since the window state might get set by a window manager, it is possible
+ // to come here before the application set its |BaseWindow|.
if (!window_state->IsFullscreen() && !window_state->IsMinimized() &&
+ app_window_->GetBaseWindow() &&
app_window_->GetBaseWindow()->IsFullscreenOrPending()) {
app_window_->Restore();
// Usually OnNativeWindowChanged() is called when the window bounds are