window_state.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file. 468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h" 668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/root_window_controller.h" 868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/screen_ash.h" 968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/shell_window_ids.h" 1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_properties.h" 111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ash/wm/window_state_delegate.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/window_state_observer.h" 1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_util.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/wm_types.h" 1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/aura/client/aura_constants.h" 1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/aura/window.h" 1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/aura/window_delegate.h" 1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/display.h" 1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/views/corewm/window_util.h" 2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace ash { 2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace wm { 2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// static 2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsMaximizedOrFullscreenState(ui::WindowShowState show_state) { 2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return show_state == ui::SHOW_STATE_FULLSCREEN || 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) show_state == ui::SHOW_STATE_MAXIMIZED; 2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState::WindowState(aura::Window* window) 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : window_(window), 3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) tracked_by_workspace_(true), 3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_position_managed_(false), 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds_changed_by_user_(false), 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) panel_attached_(true), 3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) continue_drag_after_reparent_(false), 3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ignored_by_shelf_(false), 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) can_consume_system_keys_(false), 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) top_row_keys_are_function_keys_(false), 401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) window_resizer_(NULL), 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) always_restores_to_restore_bounds_(false), 421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) hide_shelf_when_fullscreen_(true), 431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) animate_to_fullscreen_(true), 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_show_type_(ToWindowShowType(GetShowState())) { 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_->AddObserver(this); 4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState::~WindowState() { 4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void WindowState::SetDelegate(scoped_ptr<WindowStateDelegate> delegate) { 521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(!delegate_.get()); 531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) delegate_ = delegate.Pass(); 541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ui::WindowShowState WindowState::GetShowState() const { 5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return window_->GetProperty(aura::client::kShowStateKey); 5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsMinimized() const { 6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetShowState() == ui::SHOW_STATE_MINIMIZED; 6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsMaximized() const { 6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetShowState() == ui::SHOW_STATE_MAXIMIZED; 6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsFullscreen() const { 6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetShowState() == ui::SHOW_STATE_FULLSCREEN; 7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsMaximizedOrFullscreen() const { 7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return IsMaximizedOrFullscreenState(GetShowState()); 7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsNormalShowState() const { 7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ui::WindowShowState state = window_->GetProperty(aura::client::kShowStateKey); 7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return state == ui::SHOW_STATE_NORMAL || state == ui::SHOW_STATE_DEFAULT; 7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsActive() const { 8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return IsActiveWindow(window_); 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool WindowState::IsDocked() const { 861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return window_->parent() && 871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) window_->parent()->id() == internal::kShellWindowId_DockedContainer; 881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanMaximize() const { 9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return window_->GetProperty(aura::client::kCanMaximizeKey); 9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanMinimize() const { 9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) internal::RootWindowController* controller = 9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) internal::RootWindowController::ForWindow(window_); 9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!controller) 9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) aura::Window* lockscreen = controller->GetContainer( 10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) internal::kShellWindowId_LockScreenContainersContainer); 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (lockscreen->Contains(window_)) 10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return true; 10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanResize() const { 10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return window_->GetProperty(aura::client::kCanResizeKey); 10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanActivate() const { 11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return views::corewm::CanActivateWindow(window_); 11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanSnap() const { 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!CanResize() || 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_->type() == aura::client::WINDOW_TYPE_PANEL || 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_->transient_parent()) 11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If a window has a maximum size defined, snapping may make it too big. 12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return window_->delegate() ? window_->delegate()->GetMaximumSize().IsEmpty() : 12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) true; 12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::HasRestoreBounds() const { 12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return window_->GetProperty(aura::client::kRestoreBoundsKey) != NULL; 12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Maximize() { 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::SnapLeft(const gfx::Rect& bounds) { 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SnapWindow(SHOW_TYPE_LEFT_SNAPPED, bounds); 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::SnapRight(const gfx::Rect& bounds) { 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SnapWindow(SHOW_TYPE_LEFT_SNAPPED, bounds); 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Minimize() { 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Unminimize() { 14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetProperty( 14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) aura::client::kShowStateKey, 14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->GetProperty(aura::client::kRestoreShowStateKey)); 14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->ClearProperty(aura::client::kRestoreShowStateKey); 15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Activate() { 15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ActivateWindow(window_); 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Deactivate() { 15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DeactivateWindow(window_); 15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Restore() { 16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); 16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::ToggleMaximized() { 16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (IsMaximized()) 16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Restore(); 16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else if (CanMaximize()) 16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Maximize(); 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void WindowState::ToggleFullscreen() { 1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Window which cannot be maximized should not be fullscreened. 1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // It can, however, be restored if it was fullscreened. 1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool is_fullscreen = IsFullscreen(); 1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!is_fullscreen && !CanMaximize()) 1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (delegate_ && delegate_->ToggleFullscreen(this)) 1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (is_fullscreen) { 1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Restore(); 1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) window_->SetProperty(aura::client::kShowStateKey, 1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ui::SHOW_STATE_FULLSCREEN); 1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetBoundsInScreen( 18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const gfx::Rect& bounds_in_screen) { 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect bounds_in_parent = 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScreenAsh::ConvertRectFromScreen(window_->parent(), 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds_in_screen); 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetBounds(bounds_in_parent); 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SaveCurrentBoundsForRestore() { 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect bounds_in_screen = 19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScreenAsh::ConvertRectToScreen(window_->parent(), 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->bounds()); 19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SetRestoreBoundsInScreen(bounds_in_screen); 20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)gfx::Rect WindowState::GetRestoreBoundsInScreen() const { 20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return *window_->GetProperty(aura::client::kRestoreBoundsKey); 20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)gfx::Rect WindowState::GetRestoreBoundsInParent() const { 20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return ScreenAsh::ConvertRectFromScreen(window_->parent(), 20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetRestoreBoundsInScreen()); 20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetRestoreBoundsInScreen(const gfx::Rect& bounds) { 21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetProperty(aura::client::kRestoreBoundsKey, new gfx::Rect(bounds)); 21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetRestoreBoundsInParent(const gfx::Rect& bounds) { 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SetRestoreBoundsInScreen( 21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScreenAsh::ConvertRectToScreen(window_->parent(), bounds)); 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::ClearRestoreBounds() { 22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->ClearProperty(aura::client::kRestoreBoundsKey); 22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetPreAutoManageWindowBounds( 22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const gfx::Rect& bounds) { 22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pre_auto_manage_window_bounds_.reset(new gfx::Rect(bounds)); 22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::AddObserver(WindowStateObserver* observer) { 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) observer_list_.AddObserver(observer); 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::RemoveObserver(WindowStateObserver* observer) { 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) observer_list_.RemoveObserver(observer); 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetTrackedByWorkspace(bool tracked_by_workspace) { 23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (tracked_by_workspace_ == tracked_by_workspace) 23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool old = tracked_by_workspace_; 24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) tracked_by_workspace_ = tracked_by_workspace; 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FOR_EACH_OBSERVER(WindowStateObserver, observer_list_, 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OnTrackedByWorkspaceChanged(this, old)); 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::OnWindowPropertyChanged(aura::Window* window, 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const void* key, 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) intptr_t old) { 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(window, window_); 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (key == aura::client::kShowStateKey) { 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_show_type_ = ToWindowShowType(GetShowState()); 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old); 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TODO(oshima): Notify only when the state has changed. 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Doing so break a few tests now. 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FOR_EACH_OBSERVER( 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WindowStateObserver, observer_list_, 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OnWindowShowTypeChanged(this, ToWindowShowType(old_state))); 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::OnWindowDestroying(aura::Window* window) { 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_->RemoveObserver(this); 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::SnapWindow(WindowShowType left_or_right, 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const gfx::Rect& bounds) { 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsMaximizedOrFullscreen()) { 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Before we can set the bounds we need to restore the window. 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Restoring the window will set the window to its restored bounds. 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // To avoid an unnecessary bounds changes (which may have side effects) 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // we set the restore bounds to the bounds we want, restore the window, 2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // then reset the restore bounds. This way no unnecessary bounds 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // changes occurs and the original restore bounds is remembered. 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Rect restore_bounds_in_screen = 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GetRestoreBoundsInScreen(); 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SetRestoreBoundsInParent(bounds); 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Restore(); 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SetRestoreBoundsInScreen(restore_bounds_in_screen); 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_->SetBounds(bounds); 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(left_or_right == SHOW_TYPE_LEFT_SNAPPED || 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) left_or_right == SHOW_TYPE_RIGHT_SNAPPED); 2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_show_type_ = left_or_right; 28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 28668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 28768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState* GetActiveWindowState() { 28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) aura::Window* active = GetActiveWindow(); 28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return active ? GetWindowState(active) : NULL; 29068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 29168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 29268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState* GetWindowState(aura::Window* window) { 29368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!window) 29468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return NULL; 29568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WindowState* settings = window->GetProperty(internal::kWindowStateKey); 29668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if(!settings) { 29768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) settings = new WindowState(window); 29868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window->SetProperty(internal::kWindowStateKey, settings); 29968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 30068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return settings; 30168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 30368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const WindowState* GetWindowState(const aura::Window* window) { 30468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetWindowState(const_cast<aura::Window*>(window)); 30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace wm 30868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace ash 309