window_state.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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) 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/ash_switches.h" 868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/root_window_controller.h" 968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/screen_ash.h" 1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/shell_window_ids.h" 1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_properties.h" 121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ash/wm/window_state_delegate.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/window_state_observer.h" 1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_util.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/wm_types.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/auto_reset.h" 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/command_line.h" 1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/aura/client/aura_constants.h" 1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/aura/window.h" 2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/aura/window_delegate.h" 2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/display.h" 2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/views/corewm/window_util.h" 2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace ash { 2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace wm { 2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// static 2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsMaximizedOrFullscreenState(ui::WindowShowState show_state) { 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return show_state == ui::SHOW_STATE_FULLSCREEN || 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) show_state == ui::SHOW_STATE_MAXIMIZED; 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState::WindowState(aura::Window* window) 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : window_(window), 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_position_managed_(false), 3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds_changed_by_user_(false), 3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) panel_attached_(true), 3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) continue_drag_after_reparent_(false), 3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ignored_by_shelf_(false), 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) can_consume_system_keys_(false), 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) top_row_keys_are_function_keys_(false), 421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) window_resizer_(NULL), 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) always_restores_to_restore_bounds_(false), 441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) hide_shelf_when_fullscreen_(true), 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) animate_to_fullscreen_(true), 460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) minimum_visibility_(false), 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) in_set_window_show_type_(false), 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_show_type_(ToWindowShowType(GetShowState())) { 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_->AddObserver(this); 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_CHROMEOS) 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // NOTE(pkotwicz): Animating to immersive fullscreen does not look good. When 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // the kAshEnableImmersiveFullscreenForAllWindows flag is set most windows 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // can be put into immersive fullscreen. It is not worth the added complexity 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // to only animate to fullscreen if the window is put into immersive 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // fullscreen. 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) animate_to_fullscreen_ = !CommandLine::ForCurrentProcess()->HasSwitch( 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) switches::kAshEnableImmersiveFullscreenForAllWindows); 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState::~WindowState() { 6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool WindowState::HasDelegate() const { 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return delegate_; 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void WindowState::SetDelegate(scoped_ptr<WindowStateDelegate> delegate) { 701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(!delegate_.get()); 711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) delegate_ = delegate.Pass(); 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ui::WindowShowState WindowState::GetShowState() const { 7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return window_->GetProperty(aura::client::kShowStateKey); 7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsMinimized() const { 7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetShowState() == ui::SHOW_STATE_MINIMIZED; 8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsMaximized() const { 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetShowState() == ui::SHOW_STATE_MAXIMIZED; 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsFullscreen() const { 8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetShowState() == ui::SHOW_STATE_FULLSCREEN; 8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsMaximizedOrFullscreen() const { 9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return IsMaximizedOrFullscreenState(GetShowState()); 9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsNormalShowState() const { 9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ui::WindowShowState state = window_->GetProperty(aura::client::kShowStateKey); 9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return state == ui::SHOW_STATE_NORMAL || state == ui::SHOW_STATE_DEFAULT; 9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsActive() const { 10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return IsActiveWindow(window_); 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool WindowState::IsDocked() const { 1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return window_->parent() && 1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) window_->parent()->id() == internal::kShellWindowId_DockedContainer; 1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool WindowState::IsSnapped() const { 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return window_show_type_ == SHOW_TYPE_LEFT_SNAPPED || 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) window_show_type_ == SHOW_TYPE_RIGHT_SNAPPED; 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanMaximize() const { 11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return window_->GetProperty(aura::client::kCanMaximizeKey); 11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanMinimize() const { 11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) internal::RootWindowController* controller = 11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) internal::RootWindowController::ForWindow(window_); 12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!controller) 12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) aura::Window* lockscreen = controller->GetContainer( 12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) internal::kShellWindowId_LockScreenContainersContainer); 12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (lockscreen->Contains(window_)) 12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return true; 12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanResize() const { 13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return window_->GetProperty(aura::client::kCanResizeKey); 13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanActivate() const { 13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return views::corewm::CanActivateWindow(window_); 13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanSnap() const { 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!CanResize() || 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_->type() == aura::client::WINDOW_TYPE_PANEL || 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_->transient_parent()) 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If a window has a maximum size defined, snapping may make it too big. 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return window_->delegate() ? window_->delegate()->GetMaximumSize().IsEmpty() : 14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) true; 14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::HasRestoreBounds() const { 14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return window_->GetProperty(aura::client::kRestoreBoundsKey) != NULL; 15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Maximize() { 15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::SnapLeft(const gfx::Rect& bounds) { 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SnapWindow(SHOW_TYPE_LEFT_SNAPPED, bounds); 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::SnapRight(const gfx::Rect& bounds) { 161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SnapWindow(SHOW_TYPE_RIGHT_SNAPPED, bounds); 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Minimize() { 16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); 16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Unminimize() { 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetProperty( 17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) aura::client::kShowStateKey, 17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->GetProperty(aura::client::kRestoreShowStateKey)); 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->ClearProperty(aura::client::kRestoreShowStateKey); 17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Activate() { 17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ActivateWindow(window_); 17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Deactivate() { 18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DeactivateWindow(window_); 18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Restore() { 18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::ToggleMaximized() { 18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (IsMaximized()) 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Restore(); 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else if (CanMaximize()) 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Maximize(); 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void WindowState::ToggleFullscreen() { 1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Window which cannot be maximized should not be fullscreened. 1961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // It can, however, be restored if it was fullscreened. 1971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool is_fullscreen = IsFullscreen(); 1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!is_fullscreen && !CanMaximize()) 1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (delegate_ && delegate_->ToggleFullscreen(this)) 2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (is_fullscreen) { 2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Restore(); 2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 2051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) window_->SetProperty(aura::client::kShowStateKey, 2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ui::SHOW_STATE_FULLSCREEN); 2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetBoundsInScreen( 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const gfx::Rect& bounds_in_screen) { 21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect bounds_in_parent = 21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScreenAsh::ConvertRectFromScreen(window_->parent(), 21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds_in_screen); 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetBounds(bounds_in_parent); 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SaveCurrentBoundsForRestore() { 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect bounds_in_screen = 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScreenAsh::ConvertRectToScreen(window_->parent(), 22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->bounds()); 22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SetRestoreBoundsInScreen(bounds_in_screen); 22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)gfx::Rect WindowState::GetRestoreBoundsInScreen() const { 22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return *window_->GetProperty(aura::client::kRestoreBoundsKey); 22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)gfx::Rect WindowState::GetRestoreBoundsInParent() const { 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return ScreenAsh::ConvertRectFromScreen(window_->parent(), 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetRestoreBoundsInScreen()); 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetRestoreBoundsInScreen(const gfx::Rect& bounds) { 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->SetProperty(aura::client::kRestoreBoundsKey, new gfx::Rect(bounds)); 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetRestoreBoundsInParent(const gfx::Rect& bounds) { 23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SetRestoreBoundsInScreen( 24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScreenAsh::ConvertRectToScreen(window_->parent(), bounds)); 24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 24268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 24368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::ClearRestoreBounds() { 24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window_->ClearProperty(aura::client::kRestoreBoundsKey); 24568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 24668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetPreAutoManageWindowBounds( 24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const gfx::Rect& bounds) { 24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pre_auto_manage_window_bounds_.reset(new gfx::Rect(bounds)); 25068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 25168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::AddObserver(WindowStateObserver* observer) { 25368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) observer_list_.AddObserver(observer); 25468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::RemoveObserver(WindowStateObserver* observer) { 25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) observer_list_.RemoveObserver(observer); 25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 25968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::OnWindowPropertyChanged(aura::Window* window, 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const void* key, 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) intptr_t old) { 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(window, window_); 264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (key == aura::client::kShowStateKey) 265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetWindowShowType(ToWindowShowType(GetShowState())); 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::SnapWindow(WindowShowType left_or_right, 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const gfx::Rect& bounds) { 270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (window_show_type_ == left_or_right) { 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_->SetBounds(bounds); 272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Compute the bounds that the window will restore to. If the window does not 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // already have restore bounds, it will be restored (when un-snapped) to the 277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // last bounds that it had before getting snapped. 278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect restore_bounds_in_screen(HasRestoreBounds() ? 279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GetRestoreBoundsInScreen() : window_->GetBoundsInScreen()); 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Set the window's restore bounds so that WorkspaceLayoutManager knows 281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // which width to use when the snapped window is moved to the edge. 282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetRestoreBoundsInParent(bounds); 283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool was_maximized = IsMaximizedOrFullscreen(); 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Before we can set the bounds we need to restore the window. 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Restoring the window will set the window to its restored bounds set above. 287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Restore will cause OnWindowPropertyChanged() so it needs to be done 288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // before notifying that the WindowShowType has changed to |left_or_right|. 289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (was_maximized) 290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Restore(); 2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(left_or_right == SHOW_TYPE_LEFT_SNAPPED || 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) left_or_right == SHOW_TYPE_RIGHT_SNAPPED); 293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetWindowShowType(left_or_right); 294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // TODO(varkha): Ideally the bounds should be changed in a LayoutManager upon 295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // observing the WindowShowType change. 296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If the window is a child of kShellWindowId_DockedContainer such as during 297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // a drag, the window's bounds are not set in 298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // WorkspaceLayoutManager::OnWindowShowTypeChanged(). Set them here. Skip 299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // setting the bounds otherwise to avoid stopping the slide animation which 300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // was started as a result of OnWindowShowTypeChanged(). 301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (IsDocked()) 302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) window_->SetBounds(bounds); 303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetRestoreBoundsInScreen(restore_bounds_in_screen); 304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void WindowState::SetWindowShowType(WindowShowType new_window_show_type) { 307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (in_set_window_show_type_) 308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::AutoReset<bool> resetter(&in_set_window_show_type_, true); 310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui::WindowShowState new_window_state = 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ToWindowShowState(new_window_show_type); 313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (new_window_state != GetShowState()) 314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) window_->SetProperty(aura::client::kShowStateKey, new_window_state); 315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) WindowShowType old_window_show_type = window_show_type_; 316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) window_show_type_ = new_window_show_type; 317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (old_window_show_type != window_show_type_) { 318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FOR_EACH_OBSERVER(WindowStateObserver, observer_list_, 319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnWindowShowTypeChanged(this, old_window_show_type)); 320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 32168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 32268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 32368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState* GetActiveWindowState() { 32468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) aura::Window* active = GetActiveWindow(); 32568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return active ? GetWindowState(active) : NULL; 32668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 32768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 32868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState* GetWindowState(aura::Window* window) { 32968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!window) 33068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return NULL; 33168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WindowState* settings = window->GetProperty(internal::kWindowStateKey); 33268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if(!settings) { 33368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) settings = new WindowState(window); 33468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) window->SetProperty(internal::kWindowStateKey, settings); 33568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 33668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return settings; 33768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 33868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 33968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const WindowState* GetWindowState(const aura::Window* window) { 34068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetWindowState(const_cast<aura::Window*>(window)); 34168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 34268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 34368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace wm 34468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace ash 345