123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// found in the LICENSE file. 423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/wm/maximize_mode/maximize_mode_window_state.h" 623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/display/display_controller.h" 823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/screen_util.h" 923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/shell.h" 1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/shell_window_ids.h" 1123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/wm/coordinate_conversion.h" 1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/wm/maximize_mode/maximize_mode_window_manager.h" 1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/wm/window_animations.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ash/wm/window_properties.h" 1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/wm/window_state_delegate.h" 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/wm/window_state_util.h" 1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/wm/window_util.h" 1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/wm/wm_event.h" 1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ash/wm/workspace/workspace_window_resizer.h" 2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/aura/client/aura_constants.h" 2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/aura/window.h" 2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/aura/window_delegate.h" 2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/gfx/display.h" 2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/gfx/rect.h" 25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/views/view_constants_aura.h" 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/views/widget/widget.h" 2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace ash { 2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace { 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Returns the biggest possible size for a window which is about to be 3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// maximized. 3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)gfx::Size GetMaximumSizeOfWindow(wm::WindowState* window_state) { 34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(window_state->CanMaximize() || window_state->CanResize()); 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Size workspace_size = ScreenUtil::GetMaximizedWindowBoundsInParent( 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->window()).size(); 3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) aura::WindowDelegate* delegate = window_state->window()->delegate(); 4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!delegate) 4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return workspace_size; 4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Size size = delegate->GetMaximumSize(); 4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (size.IsEmpty()) 4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return workspace_size; 4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) size.SetToMin(workspace_size); 4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return size; 4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Returns the centered bounds of the given bounds in the work area. 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liugfx::Rect GetCenteredBounds(const gfx::Rect& bounds_in_parent, 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wm::WindowState* state_object) { 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect work_area_in_parent = 555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ScreenUtil::GetDisplayWorkAreaBoundsInParent(state_object->window()); 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu work_area_in_parent.ClampToCenteredSize(bounds_in_parent.size()); 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return work_area_in_parent; 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Returns the maximized/full screen and/or centered bounds of a window. 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liugfx::Rect GetBoundsInMaximizedMode(wm::WindowState* state_object) { 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (state_object->IsFullscreen()) 635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return ScreenUtil::GetDisplayBoundsInParent(state_object->window()); 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Rect bounds_in_parent; 66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Make the window as big as possible. 67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (state_object->CanMaximize() || state_object->CanResize()) { 6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bounds_in_parent.set_size(GetMaximumSizeOfWindow(state_object)); 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else { 7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // We prefer the user given window dimensions over the current windows 7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // dimensions since they are likely to be the result from some other state 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // object logic. 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (state_object->HasRestoreBounds()) 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bounds_in_parent = state_object->GetRestoreBoundsInParent(); 7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) else 7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bounds_in_parent = state_object->window()->bounds(); 7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return GetCenteredBounds(bounds_in_parent, state_object); 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} // namespace 8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// static 8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void MaximizeModeWindowState::UpdateWindowPosition( 8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) wm::WindowState* window_state, bool animated) { 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect bounds_in_parent = GetBoundsInMaximizedMode(window_state); 8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (bounds_in_parent == window_state->window()->bounds()) 8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (animated) 9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->SetBoundsDirect(bounds_in_parent); 9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) else 9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->SetBoundsDirectAnimated(bounds_in_parent); 9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)MaximizeModeWindowState::MaximizeModeWindowState( 9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) aura::Window* window, MaximizeModeWindowManager* creator) 9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : window_(window), 10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) creator_(creator), 10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) current_state_type_(wm::GetWindowState(window)->GetStateType()) { 10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) old_state_.reset( 10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) wm::GetWindowState(window)->SetStateObject( 10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<State>(this).Pass()).release()); 10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)MaximizeModeWindowState::~MaximizeModeWindowState() { 10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) creator_->WindowStateDestroyed(window_); 10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void MaximizeModeWindowState::LeaveMaximizeMode(wm::WindowState* window_state) { 11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Note: When we return we will destroy ourselves with the |our_reference|. 11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<wm::WindowState::State> our_reference = 11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->SetStateObject(old_state_.Pass()); 11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void MaximizeModeWindowState::OnWMEvent(wm::WindowState* window_state, 11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const wm::WMEvent* event) { 11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) switch (event->type()) { 1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case wm::WM_EVENT_TOGGLE_FULLSCREEN: 1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ToggleFullScreen(window_state, window_state->delegate()); 1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case wm::WM_EVENT_FULLSCREEN: 1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UpdateWindow(window_state, wm::WINDOW_STATE_TYPE_FULLSCREEN, true); 1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_TOGGLE_MAXIMIZE_CAPTION: 12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE: 12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE: 12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_TOGGLE_MAXIMIZE: 13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_CENTER: 13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_SNAP_LEFT: 13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_SNAP_RIGHT: 13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_NORMAL: 13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_MAXIMIZE: 1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UpdateWindow(window_state, 1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GetMaximizedOrCenteredWindowType(window_state), 1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu true); 13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_MINIMIZE: 1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UpdateWindow(window_state, wm::WINDOW_STATE_TYPE_MINIMIZED, true); 14123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 14223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_SHOW_INACTIVE: 14323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 14423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_SET_BOUNDS: 145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (current_state_type_ == wm::WINDOW_STATE_TYPE_MAXIMIZED) { 146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Having a maximized window, it could have been created with an empty 147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // size and the caller should get his size upon leaving the maximized 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // mode. As such we set the restore bounds to the requested bounds. 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect bounds_in_parent = 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (static_cast<const wm::SetBoundsEvent*>(event))->requested_bounds(); 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!bounds_in_parent.IsEmpty()) 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_state->SetRestoreBoundsInParent(bounds_in_parent); 153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED && 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED && 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) current_state_type_ != wm::WINDOW_STATE_TYPE_FULLSCREEN) { 156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // In all other cases (except for minimized windows) we respect the 157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // requested bounds and center it to a fully visible area on the screen. 15823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Rect bounds_in_parent = 15923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) (static_cast<const wm::SetBoundsEvent*>(event))->requested_bounds(); 1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bounds_in_parent = GetCenteredBounds(bounds_in_parent, window_state); 1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (bounds_in_parent != window_state->window()->bounds()) { 1625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (window_state->window()->IsVisible()) 1635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window_state->SetBoundsDirectAnimated(bounds_in_parent); 1645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu else 1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window_state->SetBoundsDirect(bounds_in_parent); 1665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 16723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 16823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 16923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_ADDED_TO_WORKSPACE: 1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED && 1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu current_state_type_ != wm::WINDOW_STATE_TYPE_FULLSCREEN && 1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED) { 1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wm::WindowStateType new_state = 1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GetMaximizedOrCenteredWindowType(window_state); 1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UpdateWindow(window_state, new_state, true); 1765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 17723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 17823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED: 17923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED) 1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UpdateBounds(window_state, true); 18123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case wm::WM_EVENT_DISPLAY_BOUNDS_CHANGED: 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Don't animate on a screen rotation - just snap to new size. 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED) 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UpdateBounds(window_state, false); 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 18723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 18823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 18923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 19023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)wm::WindowStateType MaximizeModeWindowState::GetType() const { 19123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return current_state_type_; 19223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 19323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 19423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void MaximizeModeWindowState::AttachState( 19523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) wm::WindowState* window_state, 19623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) wm::WindowState::State* previous_state) { 19723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) current_state_type_ = previous_state->GetType(); 19823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) views::Widget* widget = 200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) views::Widget::GetWidgetForNativeWindow(window_state->window()); 201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (widget) { 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect bounds = widget->GetRestoredBounds(); 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!bounds.IsEmpty()) { 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // We do not want to do a session restore to our window states. Therefore 205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // we tell the window to use the current default states instead. 206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_state->window()->SetProperty(ash::kRestoreShowStateOverrideKey, 207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_state->GetShowState()); 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_state->window()->SetProperty(ash::kRestoreBoundsOverrideKey, 209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new gfx::Rect(widget->GetRestoredBounds())); 210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Initialize the state to a good preset. 21423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED && 2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED && 2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu current_state_type_ != wm::WINDOW_STATE_TYPE_FULLSCREEN) { 2175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UpdateWindow(window_state, 2185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GetMaximizedOrCenteredWindowType(window_state), 2195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu true); 22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 22223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->set_can_be_dragged(false); 22323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 22523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void MaximizeModeWindowState::DetachState(wm::WindowState* window_state) { 226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // From now on, we can use the default session restore mechanism again. 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_state->window()->ClearProperty(ash::kRestoreBoundsOverrideKey); 22823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->set_can_be_dragged(true); 22923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 23023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid MaximizeModeWindowState::UpdateWindow(wm::WindowState* window_state, 2325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wm::WindowStateType target_state, 2335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool animated) { 2345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(target_state == wm::WINDOW_STATE_TYPE_MINIMIZED || 2355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu target_state == wm::WINDOW_STATE_TYPE_MAXIMIZED || 2365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu (target_state == wm::WINDOW_STATE_TYPE_NORMAL && 2375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu !window_state->CanMaximize()) || 2385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu target_state == wm::WINDOW_STATE_TYPE_FULLSCREEN); 2395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (target_state == wm::WINDOW_STATE_TYPE_MINIMIZED) { 2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (current_state_type_ == wm::WINDOW_STATE_TYPE_MINIMIZED) 2425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 24323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 24423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) current_state_type_ = target_state; 2455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ::wm::SetWindowVisibilityAnimationType( 2465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window_state->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE); 2475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window_state->window()->Hide(); 2485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (window_state->IsActive()) 2495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window_state->Deactivate(); 2505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 2515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (current_state_type_ == target_state) { 2545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // If the state type did not change, update it accordingly. 2555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UpdateBounds(window_state, animated); 2565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 25723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 25823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const wm::WindowStateType old_state_type = current_state_type_; 2605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu current_state_type_ = target_state; 2615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window_state->UpdateWindowShowStateFromStateType(); 2625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window_state->NotifyPreStateTypeChange(old_state_type); 2635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UpdateBounds(window_state, animated); 2645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window_state->NotifyPostStateTypeChange(old_state_type); 2655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 26623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if ((window_state->window()->TargetVisibility() || 26723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) old_state_type == wm::WINDOW_STATE_TYPE_MINIMIZED) && 26823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) !window_state->window()->layer()->visible()) { 26923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // The layer may be hidden if the window was previously minimized. Make 27023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // sure it's visible. 27123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) window_state->window()->Show(); 27223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 27323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 27423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuwm::WindowStateType MaximizeModeWindowState::GetMaximizedOrCenteredWindowType( 2765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wm::WindowState* window_state) { 2775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return window_state->CanMaximize() ? wm::WINDOW_STATE_TYPE_MAXIMIZED : 2785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu wm::WINDOW_STATE_TYPE_NORMAL; 2795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid MaximizeModeWindowState::UpdateBounds(wm::WindowState* window_state, 2825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool animated) { 2835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect bounds_in_parent = GetBoundsInMaximizedMode(window_state); 2845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // If we have a target bounds rectangle, we center it and set it 2855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // accordingly. 2865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!bounds_in_parent.IsEmpty() && 2875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bounds_in_parent != window_state->window()->bounds()) { 2885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (current_state_type_ == wm::WINDOW_STATE_TYPE_MINIMIZED || 2895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu !window_state->window()->IsVisible() || 2905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu !animated) { 2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu window_state->SetBoundsDirect(bounds_in_parent); 2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else { 293010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If we animate (to) maximized mode, we want to use the cross fade to 294010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // avoid flashing. 295010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (window_state->IsMaximized()) 296010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_state->SetBoundsDirectCrossFade(bounds_in_parent); 297010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else 298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_state->SetBoundsDirectAnimated(bounds_in_parent); 2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 3005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 30323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} // namespace ash 304