window_state_unittest.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/window_state.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/screen_util.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/shell.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/test/ash_test_base.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/window_state.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/wm_event.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/aura/client/aura_constants.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ash { 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace wm { 1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace { 1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class AlwaysMaximizeTestState : public WindowState::State { 2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public: 2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) explicit AlwaysMaximizeTestState(WindowStateType initial_state_type) 2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : state_type_(initial_state_type) {} 2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual ~AlwaysMaximizeTestState() {} 2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // WindowState::State overrides: 2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void OnWMEvent(WindowState* window_state, 2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent* event) OVERRIDE { 2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // We don't do anything here. 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual WindowStateType GetType() const OVERRIDE { 3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return state_type_; 3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void AttachState( 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state, 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState::State* previous_state) OVERRIDE { 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // We always maximize. 3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (state_type_ != WINDOW_STATE_TYPE_MAXIMIZED) { 3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->Maximize(); 4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) state_type_ = WINDOW_STATE_TYPE_MAXIMIZED; 4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void DetachState(WindowState* window_state) OVERRIDE {} 4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private: 4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowStateType state_type_; 4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AlwaysMaximizeTestState); 4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}; 5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 5123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} // namespace 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)typedef test::AshTestBase WindowStateTest; 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test that a window gets properly snapped to the display's edges in a 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// multi monitor environment. 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WindowStateTest, SnapWindowBasic) { 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!SupportsMultipleDisplays()) 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateDisplay("0+0-500x400, 0+500-600x400"); 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect kPrimaryDisplayWorkAreaBounds = 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect kSecondaryDisplayWorkAreaBounds = 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScreenUtil::GetSecondaryDisplay().work_area(); 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<aura::Window> window( 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_left(WM_EVENT_SNAP_LEFT); 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_left); 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect expected = gfx::Rect( 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kPrimaryDisplayWorkAreaBounds.x(), 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kPrimaryDisplayWorkAreaBounds.y(), 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kPrimaryDisplayWorkAreaBounds.width() / 2, 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kPrimaryDisplayWorkAreaBounds.height()); 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_right(WM_EVENT_SNAP_RIGHT); 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_right); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) expected.set_x(kPrimaryDisplayWorkAreaBounds.right() - expected.width()); 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Move the window to the secondary display. 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100), 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScreenUtil::GetSecondaryDisplay()); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_right); 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) expected = gfx::Rect( 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kSecondaryDisplayWorkAreaBounds.x() + 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kSecondaryDisplayWorkAreaBounds.width() / 2, 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kSecondaryDisplayWorkAreaBounds.y(), 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kSecondaryDisplayWorkAreaBounds.width() / 2, 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kSecondaryDisplayWorkAreaBounds.height()); 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_left); 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) expected.set_x(kSecondaryDisplayWorkAreaBounds.x()); 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test how the minimum and maximum size specified by the aura::WindowDelegate 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// affect snapping. 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WindowStateTest, SnapWindowMinimumSize) { 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!SupportsHostWindowResize()) 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateDisplay("0+0-600x900"); 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect kWorkAreaBounds = 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::test::TestWindowDelegate delegate; 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate( 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &delegate, -1, gfx::Rect(0, 100, kWorkAreaBounds.width() - 1, 100))); 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // It should be possible to snap a window with a minimum size. 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) delegate.set_minimum_size(gfx::Size(kWorkAreaBounds.width() - 1, 0)); 11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(window_state->CanSnap()); 12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_right(WM_EVENT_SNAP_RIGHT); 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_right); 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x() + 1, 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.y(), 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.width() - 1, 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.height()); 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // It should not be possible to snap a window with a maximum size, or if it 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // cannot be maximized. 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate.set_maximum_size(gfx::Size(kWorkAreaBounds.width() - 1, 0)); 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(window_state->CanSnap()); 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate.set_maximum_size(gfx::Size(0, kWorkAreaBounds.height() - 1)); 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(window_state->CanSnap()); 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate.set_maximum_size(gfx::Size()); 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci window->SetProperty(aura::client::kCanMaximizeKey, false); 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(window_state->CanSnap()); 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Test that the minimum size specified by aura::WindowDelegate gets respected. 1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(WindowStateTest, TestRespectMinimumSize) { 1415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!SupportsHostWindowResize()) 1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UpdateDisplay("0+0-1024x768"); 1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu aura::test::TestWindowDelegate delegate; 1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const gfx::Size minimum_size(gfx::Size(500, 300)); 1485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu delegate.set_minimum_size(minimum_size); 1495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate( 1515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &delegate, -1, gfx::Rect(0, 100, 100, 100))); 1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Check that the window has the correct minimum size. 1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(minimum_size.ToString(), window->bounds().size().ToString()); 1555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Set the size to something bigger - that should work. 1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect bigger_bounds(700, 500, 700, 500); 1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window->SetBounds(bigger_bounds); 1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(bigger_bounds.ToString(), window->bounds().ToString()); 1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Set the size to something smaller - that should only resize to the smallest 1625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // possible size. 1635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect smaller_bounds(700, 500, 100, 100); 1645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window->SetBounds(smaller_bounds); 1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(minimum_size.ToString(), window->bounds().size().ToString()); 1665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Test that the minimum window size specified by aura::WindowDelegate does not 1695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// exceed the screen size. 1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(WindowStateTest, TestIgnoreTooBigMinimumSize) { 1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!SupportsHostWindowResize()) 1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UpdateDisplay("0+0-1024x768"); 1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const gfx::Size work_area_size = 1765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ash::Shell::GetScreen()->GetPrimaryDisplay().work_area().size(); 1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const gfx::Size illegal_size(1280, 960); 1785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const gfx::Rect illegal_bounds(gfx::Point(0, 0), illegal_size); 1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu aura::test::TestWindowDelegate delegate; 1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const gfx::Size minimum_size(illegal_size); 1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu delegate.set_minimum_size(minimum_size); 1835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // The creation should force the window to respect the screen size. 1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate( 1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &delegate, -1, illegal_bounds)); 1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(work_area_size.ToString(), window->bounds().size().ToString()); 1885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Trying to set the size to something bigger then the screen size should be 1905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // ignored. 1915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window->SetBounds(illegal_bounds); 1925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(work_area_size.ToString(), window->bounds().size().ToString()); 1935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Maximizing the window should not allow it to go bigger than that either. 1955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu WindowState* window_state = GetWindowState(window.get()); 1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window_state->Maximize(); 1975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(work_area_size.ToString(), window->bounds().size().ToString()); 1985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test that setting the bounds of a snapped window keeps its snapped. 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WindowStateTest, SnapWindowSetBounds) { 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!SupportsHostWindowResize()) 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateDisplay("0+0-900x600"); 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect kWorkAreaBounds = 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<aura::Window> window( 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); 21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_left(WM_EVENT_SNAP_LEFT); 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_left); 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType()); 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(), 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.y(), 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.width() / 2, 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.height()); 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Snapped windows can have any width. 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) expected.set_width(500); 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->SetBounds(gfx::Rect(10, 10, 500, 300)); 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType()); 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test that snapping left/right preserves the restore bounds. 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WindowStateTest, RestoreBounds) { 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<aura::Window> window( 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); 23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(window_state->IsNormalStateType()); 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 1) Start with restored window with restore bounds set. 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect restore_bounds = window->GetBoundsInScreen(); 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) restore_bounds.set_width(restore_bounds.width() + 1); 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->SetRestoreBoundsInScreen(restore_bounds); 24023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_left(WM_EVENT_SNAP_LEFT); 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_left); 24223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_right(WM_EVENT_SNAP_RIGHT); 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_right); 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(restore_bounds.ToString(), 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->GetRestoreBoundsInScreen().ToString()); 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->Restore(); 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 2) Start with restored bounds set as a result of maximizing the window. 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->Maximize(); 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect maximized_bounds = window->GetBoundsInScreen(); 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_NE(maximized_bounds.ToString(), restore_bounds.ToString()); 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(restore_bounds.ToString(), 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->GetRestoreBoundsInScreen().ToString()); 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_left); 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_NE(maximized_bounds.ToString(), 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->GetBoundsInScreen().ToString()); 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(restore_bounds.ToString(), 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->GetRestoreBoundsInScreen().ToString()); 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->Restore(); 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test that maximizing an auto managed window, then snapping it puts the window 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// at the snapped bounds and not at the auto-managed (centered) bounds. 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WindowStateTest, AutoManaged) { 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); 27223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->set_window_position_managed(true); 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->Hide(); 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->SetBounds(gfx::Rect(100, 100, 100, 100)); 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->Show(); 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->Maximize(); 27923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_right(WM_EVENT_SNAP_RIGHT); 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_right); 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect kWorkAreaBounds = 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect expected_snapped_bounds( 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.x() + kWorkAreaBounds.width() / 2, 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.y(), 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.width() / 2, 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.height()); 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected_snapped_bounds.ToString(), 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->GetBoundsInScreen().ToString()); 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The window should still be auto managed despite being right maximized. 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(window_state->window_position_managed()); 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 29623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Test that the replacement of a State object works as expected. 29723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(WindowStateTest, SimpleStateSwap) { 29823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); 29923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 30023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_FALSE(window_state->IsMaximized()); 30123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->SetStateObject( 30223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<WindowState::State> (new AlwaysMaximizeTestState( 30323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->GetStateType()))); 30423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_TRUE(window_state->IsMaximized()); 30523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 30623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 30723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Test that the replacement of a state object, following a restore with the 30823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// original one restores the window to its original state. 30923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(WindowStateTest, StateSwapRestore) { 31023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); 31123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 31223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_FALSE(window_state->IsMaximized()); 31323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<WindowState::State> old(window_state->SetStateObject( 31423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<WindowState::State> (new AlwaysMaximizeTestState( 31523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->GetStateType()))).Pass()); 31623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_TRUE(window_state->IsMaximized()); 31723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->SetStateObject(old.Pass()); 31823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_FALSE(window_state->IsMaximized()); 31923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 32023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Tests that a window that had same bounds as the work area shrinks after the 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// window is maximized and then restored. 3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(WindowStateTest, RestoredWindowBoundsShrink) { 3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); 3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(window_state->IsMaximized()); 3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::Rect work_area = 3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); 3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) window->SetBounds(work_area); 3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) window_state->Maximize(); 3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_TRUE(window_state->IsMaximized()); 3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(work_area.ToString(), window->bounds().ToString()); 3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) window_state->Restore(); 3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(window_state->IsMaximized()); 3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_NE(work_area.ToString(), window->bounds().ToString()); 3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_TRUE(work_area.Contains(window->bounds())); 3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 34123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// TODO(skuhne): Add more unit test to verify the correctness for the restore 34223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// operation. 34323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace wm 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace ash 346