diff options
author | skuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-12 05:08:03 +0000 |
---|---|---|
committer | skuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-12 05:08:03 +0000 |
commit | 4dd774723032d372a9d70d8888728b508f46b95f (patch) | |
tree | 2d1b75cf3e2db9d161004626966cd173f6c52fd2 | |
parent | d25b41879f7670a2b81499151738ed8fb8572151 (diff) | |
download | chromium_src-4dd774723032d372a9d70d8888728b508f46b95f.zip chromium_src-4dd774723032d372a9d70d8888728b508f46b95f.tar.gz chromium_src-4dd774723032d372a9d70d8888728b508f46b95f.tar.bz2 |
Addressing problems with non maximizable windows in always maximized mode as well as windows which get maximized in maximized mode
BUG=353189,359714
TEST=unittest & visual verification
Review URL: https://codereview.chromium.org/232023007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@263474 0039d316-1c4b-4281-b951-d872f2087c98
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 |