diff options
Diffstat (limited to 'chromium/ash/wm/workspace/snap_sizer_unittest.cc')
-rw-r--r-- | chromium/ash/wm/workspace/snap_sizer_unittest.cc | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/chromium/ash/wm/workspace/snap_sizer_unittest.cc b/chromium/ash/wm/workspace/snap_sizer_unittest.cc new file mode 100644 index 00000000000..81a09f93940 --- /dev/null +++ b/chromium/ash/wm/workspace/snap_sizer_unittest.cc @@ -0,0 +1,393 @@ +// Copyright 2013 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/workspace/snap_sizer.h" + +#include "ash/ash_switches.h" +#include "ash/screen_ash.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "ash/wm/window_state.h" +#include "ash/wm/window_util.h" +#include "base/command_line.h" +#include "ui/aura/root_window.h" +#include "ui/aura/test/test_window_delegate.h" +#include "ui/aura/window.h" +#include "ui/gfx/screen.h" + +namespace ash { + +typedef test::AshTestBase SnapSizerTest; + +using internal::SnapSizer; + +// Test that a window gets properly snapped to the display's edges in a +// multi monitor environment. +TEST_F(SnapSizerTest, MultipleDisplays) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("0+0-500x400, 0+500-600x400"); + const gfx::Rect kPrimaryDisplayWorkAreaBounds = + ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); + const gfx::Rect kSecondaryDisplayWorkAreaBounds = + ScreenAsh::GetSecondaryDisplay().work_area(); + + scoped_ptr<aura::Window> window( + CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); + wm::WindowState* window_state = wm::GetWindowState(window.get()); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + gfx::Rect expected = gfx::Rect( + kPrimaryDisplayWorkAreaBounds.x(), + kPrimaryDisplayWorkAreaBounds.y(), + window->bounds().width(), // No expectation for the width. + kPrimaryDisplayWorkAreaBounds.height()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); + // The width should not change when a window switches from being snapped to + // the left edge to being snapped to the right edge. + expected.set_x(kPrimaryDisplayWorkAreaBounds.right() - expected.width()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + // Move the window to the secondary display. + window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100), + ScreenAsh::GetSecondaryDisplay()); + + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); + expected = gfx::Rect( + kSecondaryDisplayWorkAreaBounds.right() - window->bounds().width(), + kSecondaryDisplayWorkAreaBounds.y(), + window->bounds().width(), // No expectation for the width. + kSecondaryDisplayWorkAreaBounds.height()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + // The width should not change when a window switches from being snapped to + // the right edge to being snapped to the left edge. + expected.set_x(kSecondaryDisplayWorkAreaBounds.x()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); +} + +// Test how the minimum and maximum size specified by the aura::WindowDelegate +// affect snapping. +TEST_F(SnapSizerTest, MinimumSize) { + if (!SupportsHostWindowResize()) + return; + + UpdateDisplay("0+0-600x800"); + const gfx::Rect kWorkAreaBounds = + ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); + + aura::test::TestWindowDelegate delegate; + scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate( + &delegate, -1, gfx::Rect(0, 100, kWorkAreaBounds.width() - 1, 100))); + + // It should be possible to snap a window with a minimum size. + delegate.set_minimum_size(gfx::Size(kWorkAreaBounds.width() - 1, 0)); + wm::WindowState* window_state = wm::GetWindowState(window.get()); + EXPECT_TRUE(window_state->CanSnap()); + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); + gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x() + 1, + kWorkAreaBounds.y(), + kWorkAreaBounds.width() - 1, + kWorkAreaBounds.height()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + // It should not be possible to snap a window with a maximum size. + delegate.set_minimum_size(gfx::Size()); + delegate.set_maximum_size(gfx::Size(kWorkAreaBounds.width() - 1, INT_MAX)); + EXPECT_FALSE(window_state->CanSnap()); +} + +// Test that repeatedly calling SnapSizer::SnapWindow() when the +// --ash-multiple-snap-window-widths flag is set steps through the ideal widths +// in descending order as well as 90% and 50% of the work area's width. +TEST_F(SnapSizerTest, StepThroughSizes) { + if (!SupportsHostWindowResize()) + return; + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kAshMultipleSnapWindowWidths); + + UpdateDisplay("1024x800"); + const gfx::Rect kWorkAreaBounds = + ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); + + scoped_ptr<aura::Window> window( + CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); + wm::WindowState* window_state = wm::GetWindowState(window.get()); + + // Make sure that the work area is the size we expect it to be. + EXPECT_GT(kWorkAreaBounds.width() * 0.9, 768); + + // The first width should be 1024 * 0.9 because the larger ideal widths + // (1280, 1024) > 1024 * 0.9. + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(), + kWorkAreaBounds.y(), + kWorkAreaBounds.width() * 0.9, + kWorkAreaBounds.height()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + expected.set_width(768); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + expected.set_width(640); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + expected.set_width(kWorkAreaBounds.width() * 0.5); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + // Wrap around. + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + expected.set_width(kWorkAreaBounds.width() * 0.9); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + // Repeat the test snapping right. + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); + expected.set_width(kWorkAreaBounds.width() * 0.9); + expected.set_x(kWorkAreaBounds.right() - expected.width()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); + expected.set_width(768); + expected.set_x(kWorkAreaBounds.right() - expected.width()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); + expected.set_width(640); + expected.set_x(kWorkAreaBounds.right() - expected.width()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); + expected.set_width(kWorkAreaBounds.width() * 0.5); + expected.set_x(kWorkAreaBounds.right() - expected.width()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + // Wrap around. + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); + expected.set_width(kWorkAreaBounds.width() * 0.9); + expected.set_x(kWorkAreaBounds.right() - expected.width()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); +} + +// Test that a SnapSizer's target bounds always start from the widest possible +// bounds and that calling Update() steps through the ideal widths in descending +// order as well as 90% and 50% of the work area's width. +TEST_F(SnapSizerTest, Update) { + if (!SupportsHostWindowResize()) + return; + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kAshMultipleSnapWindowWidths); + UpdateDisplay("1024x800"); + const gfx::Rect kWorkAreaBounds = + ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); + + // Make sure that the work area is the size we expect it to be. + EXPECT_GT(kWorkAreaBounds.width() * 0.9, 768); + + scoped_ptr<aura::Window> window( + CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); + wm::WindowState* window_state = wm::GetWindowState(window.get()); + + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(), + kWorkAreaBounds.y(), + 768, + kWorkAreaBounds.height()); + + // The SnapSizer's target bounds should always start from the widest bounds + // (instead of the bounds with the next ideal width). + SnapSizer sizer(window_state, gfx::Point(800, 0), SnapSizer::LEFT_EDGE, + SnapSizer::OTHER_INPUT); + sizer.SnapWindowToTargetBounds(); + expected.set_width(kWorkAreaBounds.width() * .9); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + sizer.Update(gfx::Point(600, 0)); + sizer.SnapWindowToTargetBounds(); + expected.set_width(768); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + sizer.Update(gfx::Point(400, 0)); + sizer.SnapWindowToTargetBounds(); + expected.set_width(640); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + sizer.Update(gfx::Point(200, 0)); + sizer.SnapWindowToTargetBounds(); + expected.set_width(kWorkAreaBounds.width() * 0.5); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + // Do not wrap around. + sizer.Update(gfx::Point(0, 0)); + sizer.SnapWindowToTargetBounds(); + expected.set_width(kWorkAreaBounds.width() * 0.5); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); +} + +// Tests the SnapSizer's target bounds when resizing is disabled and the +// --ash-multiple-snap-window-widths flag is set. +TEST_F(SnapSizerTest, Default) { + if (!SupportsHostWindowResize()) + return; + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kAshMultipleSnapWindowWidths); + + scoped_ptr<aura::Window> window( + CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); + SnapSizer sizer(wm::GetWindowState(window.get()), gfx::Point(), + SnapSizer::LEFT_EDGE, SnapSizer::OTHER_INPUT); + + // For small workspace widths, we should snap to 90% of the workspace width + // because it is the largest width the window can snap to. + UpdateDisplay("0+0-800x600"); + sizer.SelectDefaultSizeAndDisableResize(); + + gfx::Rect work_area = + ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); + gfx::Rect expected(work_area); + expected.set_width(work_area.width() * 0.9); + EXPECT_EQ(expected.ToString(), + ScreenAsh::ConvertRectToScreen(window->parent(), + sizer.target_bounds()).ToString()); + + // If the largest width the window can snap to is between 1024 and 1280, we + // should snap to 1024. + UpdateDisplay("0+0-1280x800"); + sizer.SelectDefaultSizeAndDisableResize(); + sizer.SnapWindowToTargetBounds(); + EXPECT_EQ(1024, window->bounds().width()); + + // We should snap to a width of 50% of the work area if it is the largest + // width the window can snap to. + UpdateDisplay("0+0-2560x1080"); + work_area = ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); + sizer.SelectDefaultSizeAndDisableResize(); + sizer.SnapWindowToTargetBounds(); + EXPECT_EQ(work_area.width() / 2, window->bounds().width()); +} + +// Test that the window only snaps to 50% of the work area width when the +// --ash-multiple-snap-window-widths flag is not set. +TEST_F(SnapSizerTest, SingleSnapWindowWidth) { + if (!SupportsHostWindowResize()) + return; + + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAshMultipleSnapWindowWidths)) { + return; + } + + UpdateDisplay("0+0-800x600"); + const gfx::Rect kWorkAreaBounds = + ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); + + scoped_ptr<aura::Window> window( + CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); + wm::WindowState* window_state = wm::GetWindowState(window.get()); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(), + kWorkAreaBounds.y(), + kWorkAreaBounds.width() / 2, + kWorkAreaBounds.height()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + // Because a window can only be snapped to one size when using the alternate + // caption button style, a second call to SnapSizer::SnapWindow() should have + // no effect. + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + // It should still be possible to switch a window from being snapped to the + // left edge to being snapped to the right edge. + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); + expected.set_x(kWorkAreaBounds.right() - expected.width()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + // If resizing is disabled, the window should be snapped to 50% too. + SnapSizer sizer1(window_state, gfx::Point(), SnapSizer::RIGHT_EDGE, + SnapSizer::OTHER_INPUT); + sizer1.SelectDefaultSizeAndDisableResize(); + sizer1.SnapWindowToTargetBounds(); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); + + // Snapping to a SnapSizer's initial bounds snaps to 50% too. + SnapSizer sizer2(window_state, gfx::Point(), SnapSizer::LEFT_EDGE, + SnapSizer::OTHER_INPUT); + sizer2.SnapWindowToTargetBounds(); + expected.set_x(kWorkAreaBounds.x()); + EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); +} + +// Test that snapping left/right preserves the restore bounds. +TEST_F(SnapSizerTest, RestoreBounds) { + scoped_ptr<aura::Window> window( + CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); + wm::WindowState* window_state = wm::GetWindowState(window.get()); + + EXPECT_TRUE(window_state->IsNormalShowState()); + + // 1) Start with restored window with restore bounds set. + gfx::Rect restore_bounds = window->GetBoundsInScreen(); + restore_bounds.set_width(restore_bounds.width() + 1); + window_state->SetRestoreBoundsInScreen(restore_bounds); + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); + EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); + EXPECT_EQ(restore_bounds.ToString(), + window_state->GetRestoreBoundsInScreen().ToString()); + window_state->Restore(); + EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); + + // 2) Start with restored bounds set as a result of maximizing the window. + window_state->Maximize(); + gfx::Rect maximized_bounds = window->GetBoundsInScreen(); + EXPECT_NE(maximized_bounds.ToString(), restore_bounds.ToString()); + EXPECT_EQ(restore_bounds.ToString(), + window_state->GetRestoreBoundsInScreen().ToString()); + + SnapSizer::SnapWindow(window_state, SnapSizer::LEFT_EDGE); + EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); + EXPECT_NE(maximized_bounds.ToString(), + window->GetBoundsInScreen().ToString()); + EXPECT_EQ(restore_bounds.ToString(), + window_state->GetRestoreBoundsInScreen().ToString()); + + window_state->Restore(); + EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); +} + +// Test that maximizing an auto managed window, then snapping it puts the window +// at the snapped bounds and not at the auto-managed (centered) bounds. +TEST_F(SnapSizerTest, AutoManaged) { + scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); + wm::WindowState* window_state = wm::GetWindowState(window.get()); + window_state->set_window_position_managed(true); + window->Hide(); + window->SetBounds(gfx::Rect(100, 100, 100, 100)); + window->Show(); + + window_state->Maximize(); + SnapSizer::SnapWindow(window_state, SnapSizer::RIGHT_EDGE); + + const gfx::Rect kWorkAreaBounds = + ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); + gfx::Rect expected_snapped_bounds( + kWorkAreaBounds.right() - window->bounds().width(), + kWorkAreaBounds.y(), + window->bounds().width(), // No expectation for the width. + kWorkAreaBounds.height()); + EXPECT_EQ(expected_snapped_bounds.ToString(), + window->GetBoundsInScreen().ToString()); + + // The window should still be auto managed despite being right maximized. + EXPECT_TRUE(window_state->window_position_managed()); +} + +} // namespace ash |