window_state_unittest.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ash { 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace wm { 1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace { 1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class AlwaysMaximizeTestState : public WindowState::State { 2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public: 2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) explicit AlwaysMaximizeTestState(WindowStateType initial_state_type) 2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : state_type_(initial_state_type) {} 2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual ~AlwaysMaximizeTestState() {} 2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // WindowState::State overrides: 2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void OnWMEvent(WindowState* window_state, 2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent* event) OVERRIDE { 2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // We don't do anything here. 2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual WindowStateType GetType() const OVERRIDE { 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return state_type_; 3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void AttachState( 3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state, 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState::State* previous_state) OVERRIDE { 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // We always maximize. 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (state_type_ != WINDOW_STATE_TYPE_MAXIMIZED) { 3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->Maximize(); 3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) state_type_ = WINDOW_STATE_TYPE_MAXIMIZED; 4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void DetachState(WindowState* window_state) OVERRIDE {} 4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private: 4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowStateType state_type_; 4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AlwaysMaximizeTestState); 4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}; 4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} // namespace 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)typedef test::AshTestBase WindowStateTest; 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test that a window gets properly snapped to the display's edges in a 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// multi monitor environment. 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WindowStateTest, SnapWindowBasic) { 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!SupportsMultipleDisplays()) 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateDisplay("0+0-500x400, 0+500-600x400"); 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect kPrimaryDisplayWorkAreaBounds = 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect kSecondaryDisplayWorkAreaBounds = 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScreenUtil::GetSecondaryDisplay().work_area(); 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<aura::Window> window( 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); 6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_left(WM_EVENT_SNAP_LEFT); 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_left); 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect expected = gfx::Rect( 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kPrimaryDisplayWorkAreaBounds.x(), 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kPrimaryDisplayWorkAreaBounds.y(), 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kPrimaryDisplayWorkAreaBounds.width() / 2, 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kPrimaryDisplayWorkAreaBounds.height()); 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_right(WM_EVENT_SNAP_RIGHT); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_right); 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) expected.set_x(kPrimaryDisplayWorkAreaBounds.right() - expected.width()); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Move the window to the secondary display. 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100), 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScreenUtil::GetSecondaryDisplay()); 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_right); 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) expected = gfx::Rect( 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kSecondaryDisplayWorkAreaBounds.x() + 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kSecondaryDisplayWorkAreaBounds.width() / 2, 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kSecondaryDisplayWorkAreaBounds.y(), 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kSecondaryDisplayWorkAreaBounds.width() / 2, 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kSecondaryDisplayWorkAreaBounds.height()); 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_left); 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) expected.set_x(kSecondaryDisplayWorkAreaBounds.x()); 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test how the minimum and maximum size specified by the aura::WindowDelegate 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// affect snapping. 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WindowStateTest, SnapWindowMinimumSize) { 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!SupportsHostWindowResize()) 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateDisplay("0+0-600x900"); 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect kWorkAreaBounds = 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::test::TestWindowDelegate delegate; 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate( 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &delegate, -1, gfx::Rect(0, 100, kWorkAreaBounds.width() - 1, 100))); 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // It should be possible to snap a window with a minimum size. 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) delegate.set_minimum_size(gfx::Size(kWorkAreaBounds.width() - 1, 0)); 11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(window_state->CanSnap()); 11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_right(WM_EVENT_SNAP_RIGHT); 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_right); 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x() + 1, 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.y(), 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.width() - 1, 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.height()); 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // It should not be possible to snap a window with a maximum size. 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) delegate.set_minimum_size(gfx::Size()); 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) delegate.set_maximum_size(gfx::Size(kWorkAreaBounds.width() - 1, INT_MAX)); 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(window_state->CanSnap()); 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test that setting the bounds of a snapped window keeps its snapped. 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WindowStateTest, SnapWindowSetBounds) { 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!SupportsHostWindowResize()) 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateDisplay("0+0-900x600"); 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect kWorkAreaBounds = 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<aura::Window> window( 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); 14423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 14523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_left(WM_EVENT_SNAP_LEFT); 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_left); 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType()); 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect expected = gfx::Rect(kWorkAreaBounds.x(), 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.y(), 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.width() / 2, 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.height()); 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Snapped windows can have any width. 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) expected.set_width(500); 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->SetBounds(gfx::Rect(10, 10, 500, 300)); 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected.ToString(), window->GetBoundsInScreen().ToString()); 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType()); 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test that snapping left/right preserves the restore bounds. 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WindowStateTest, RestoreBounds) { 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<aura::Window> window( 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100))); 16523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(window_state->IsNormalStateType()); 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 1) Start with restored window with restore bounds set. 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect restore_bounds = window->GetBoundsInScreen(); 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) restore_bounds.set_width(restore_bounds.width() + 1); 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->SetRestoreBoundsInScreen(restore_bounds); 17323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_left(WM_EVENT_SNAP_LEFT); 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_left); 17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_right(WM_EVENT_SNAP_RIGHT); 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_right); 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(restore_bounds.ToString(), 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->GetRestoreBoundsInScreen().ToString()); 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->Restore(); 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 2) Start with restored bounds set as a result of maximizing the window. 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->Maximize(); 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect maximized_bounds = window->GetBoundsInScreen(); 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_NE(maximized_bounds.ToString(), restore_bounds.ToString()); 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(restore_bounds.ToString(), 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->GetRestoreBoundsInScreen().ToString()); 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_left); 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_NE(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_NE(maximized_bounds.ToString(), 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->GetBoundsInScreen().ToString()); 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(restore_bounds.ToString(), 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->GetRestoreBoundsInScreen().ToString()); 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->Restore(); 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(restore_bounds.ToString(), window->GetBoundsInScreen().ToString()); 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test that maximizing an auto managed window, then snapping it puts the window 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// at the snapped bounds and not at the auto-managed (centered) bounds. 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(WindowStateTest, AutoManaged) { 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); 20523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->set_window_position_managed(true); 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->Hide(); 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->SetBounds(gfx::Rect(100, 100, 100, 100)); 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->Show(); 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->Maximize(); 21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const WMEvent snap_right(WM_EVENT_SNAP_RIGHT); 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->OnWMEvent(&snap_right); 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect kWorkAreaBounds = 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::Shell::GetScreen()->GetPrimaryDisplay().work_area(); 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect expected_snapped_bounds( 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.x() + kWorkAreaBounds.width() / 2, 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.y(), 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.width() / 2, 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kWorkAreaBounds.height()); 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(expected_snapped_bounds.ToString(), 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->GetBoundsInScreen().ToString()); 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The window should still be auto managed despite being right maximized. 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(window_state->window_position_managed()); 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 22923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Test that the replacement of a State object works as expected. 23023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(WindowStateTest, SimpleStateSwap) { 23123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); 23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 23323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_FALSE(window_state->IsMaximized()); 23423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->SetStateObject( 23523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<WindowState::State> (new AlwaysMaximizeTestState( 23623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->GetStateType()))); 23723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_TRUE(window_state->IsMaximized()); 23823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 23923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 24023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Test that the replacement of a state object, following a restore with the 24123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// original one restores the window to its original state. 24223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_F(WindowStateTest, StateSwapRestore) { 24323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); 24423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WindowState* window_state = GetWindowState(window.get()); 24523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_FALSE(window_state->IsMaximized()); 24623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<WindowState::State> old(window_state->SetStateObject( 24723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<WindowState::State> (new AlwaysMaximizeTestState( 24823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->GetStateType()))).Pass()); 24923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_TRUE(window_state->IsMaximized()); 25023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->SetStateObject(old.Pass()); 25123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_FALSE(window_state->IsMaximized()); 25223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 25323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 25423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// TODO(skuhne): Add more unit test to verify the correctness for the restore 25523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// operation. 25623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace wm 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace ash 259