window_state.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
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"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/screen_util.h"
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/shell_window_ids.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/default_state.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/window_animations.h"
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_properties.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ash/wm/window_state_delegate.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/window_state_observer.h"
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_util.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/wm_event.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/auto_reset.h"
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/command_line.h"
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/aura/client/aura_constants.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/layout_manager.h"
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/aura/window.h"
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/aura/window_delegate.h"
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/compositor/layer_tree_owner.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h"
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/display.h"
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/gfx/screen.h"
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_util.h"
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace ash {
3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace wm {
3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A tentative class to set the bounds on the window.
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(oshima): Once all logic is cleaned up, move this to the real layout
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// manager with proper friendship.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BoundsSetter : public aura::LayoutManager {
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BoundsSetter() {}
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~BoundsSetter() {}
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // aura::LayoutManager overrides:
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowResized() OVERRIDE {}
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE {}
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {}
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {}
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnChildWindowVisibilityChanged(
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      aura::Window* child, bool visible) OVERRIDE {}
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetChildBounds(
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      aura::Window* child, const gfx::Rect& requested_bounds) OVERRIDE {}
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetBounds(aura::Window* window, const gfx::Rect& bounds) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetChildBoundsDirect(window, bounds);
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BoundsSetter);
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WMEventType WMEventTypeFromShowState(ui::WindowShowState requested_show_state) {
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (requested_show_state) {
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ui::SHOW_STATE_DEFAULT:
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ui::SHOW_STATE_NORMAL:
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return WM_EVENT_NORMAL;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ui::SHOW_STATE_MINIMIZED:
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return WM_EVENT_MINIMIZE;
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ui::SHOW_STATE_MAXIMIZED:
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return WM_EVENT_MAXIMIZE;
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ui::SHOW_STATE_FULLSCREEN:
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return WM_EVENT_FULLSCREEN;
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ui::SHOW_STATE_INACTIVE:
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return WM_EVENT_SHOW_INACTIVE;
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ui::SHOW_STATE_DETACHED:
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ui::SHOW_STATE_END:
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NOTREACHED() << "No WMEvent defined for the show state:"
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   << requested_show_state;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return WM_EVENT_NORMAL;
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState::WindowState(aura::Window* window)
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : window_(window),
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      window_position_managed_(false),
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      bounds_changed_by_user_(false),
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      panel_attached_(true),
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ignored_by_shelf_(false),
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      can_consume_system_keys_(false),
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      top_row_keys_are_function_keys_(false),
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      unminimize_to_restore_bounds_(false),
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      hide_shelf_when_fullscreen_(true),
940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      minimum_visibility_(false),
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      can_be_dragged_(true),
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ignore_property_change_(false),
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      current_state_(new DefaultState(ToWindowStateType(GetShowState()))) {
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  window_->AddObserver(this);
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState::~WindowState() {
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool WindowState::HasDelegate() const {
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return delegate_;
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void WindowState::SetDelegate(scoped_ptr<WindowStateDelegate> delegate) {
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!delegate_.get());
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  delegate_ = delegate.Pass();
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WindowStateType WindowState::GetStateType() const {
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return current_state_->GetType();
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsMinimized() const {
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetStateType() == WINDOW_STATE_TYPE_MINIMIZED;
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsMaximized() const {
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetStateType() == WINDOW_STATE_TYPE_MAXIMIZED;
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsFullscreen() const {
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetStateType() == WINDOW_STATE_TYPE_FULLSCREEN;
12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsMaximizedOrFullscreen() const {
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetStateType() == WINDOW_STATE_TYPE_FULLSCREEN ||
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetStateType() == WINDOW_STATE_TYPE_MAXIMIZED;
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool WindowState::IsSnapped() const {
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetStateType() == WINDOW_STATE_TYPE_LEFT_SNAPPED ||
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetStateType() == WINDOW_STATE_TYPE_RIGHT_SNAPPED;
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool WindowState::IsNormalStateType() const {
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetStateType() == WINDOW_STATE_TYPE_NORMAL ||
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetStateType() == WINDOW_STATE_TYPE_DEFAULT;
14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool WindowState::IsNormalOrSnapped() const {
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return IsNormalStateType() || IsSnapped();
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::IsActive() const {
14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return IsActiveWindow(window_);
15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool WindowState::IsDocked() const {
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return window_->parent() &&
154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch         window_->parent()->id() == kShellWindowId_DockedContainer;
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanMaximize() const {
15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return window_->GetProperty(aura::client::kCanMaximizeKey);
15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanMinimize() const {
162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RootWindowController* controller = RootWindowController::ForWindow(window_);
16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!controller)
16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return false;
165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  aura::Window* lockscreen =
166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      controller->GetContainer(kShellWindowId_LockScreenContainersContainer);
16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (lockscreen->Contains(window_))
16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return false;
16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return true;
17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanResize() const {
17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return window_->GetProperty(aura::client::kCanResizeKey);
17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanActivate() const {
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return ::wm::CanActivateWindow(window_);
17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::CanSnap() const {
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!CanResize() || window_->type() == ui::wm::WINDOW_TYPE_PANEL ||
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ::wm::GetTransientParent(window_))
18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return false;
18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // If a window has a maximum size defined, snapping may make it too big.
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(oshima): We probably should snap if possible.
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return window_->delegate() ? window_->delegate()->GetMaximumSize().IsEmpty() :
18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                              true;
18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool WindowState::HasRestoreBounds() const {
19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return window_->GetProperty(aura::client::kRestoreBoundsKey) != NULL;
19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Maximize() {
19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Minimize() {
20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Unminimize() {
20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_->SetProperty(
20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      aura::client::kShowStateKey,
20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      window_->GetProperty(aura::client::kRestoreShowStateKey));
20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_->ClearProperty(aura::client::kRestoreShowStateKey);
20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Activate() {
21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ActivateWindow(window_);
21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Deactivate() {
21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DeactivateWindow(window_);
21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::Restore() {
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!IsNormalStateType()) {
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const WMEvent event(WM_EVENT_NORMAL);
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    OnWMEvent(&event);
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowState::OnWMEvent(const WMEvent* event) {
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  current_state_->OnWMEvent(this, event);
2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SaveCurrentBoundsForRestore() {
23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect bounds_in_screen =
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::ConvertRectToScreen(window_->parent(),
23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                      window_->bounds());
23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SetRestoreBoundsInScreen(bounds_in_screen);
23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)gfx::Rect WindowState::GetRestoreBoundsInScreen() const {
23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return *window_->GetProperty(aura::client::kRestoreBoundsKey);
23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)gfx::Rect WindowState::GetRestoreBoundsInParent() const {
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ScreenUtil::ConvertRectFromScreen(window_->parent(),
24268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                          GetRestoreBoundsInScreen());
24368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
24568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetRestoreBoundsInScreen(const gfx::Rect& bounds) {
24668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_->SetProperty(aura::client::kRestoreBoundsKey, new gfx::Rect(bounds));
24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetRestoreBoundsInParent(const gfx::Rect& bounds) {
25068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SetRestoreBoundsInScreen(
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::ConvertRectToScreen(window_->parent(), bounds));
25268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
25368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
25468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::ClearRestoreBounds() {
25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_->ClearProperty(aura::client::kRestoreBoundsKey);
25668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
25823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)scoped_ptr<WindowState::State> WindowState::SetStateObject(
25923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    scoped_ptr<WindowState::State> new_state) {
26023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  current_state_->DetachState(this);
26123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<WindowState::State> old_object = current_state_.Pass();
26223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  current_state_ = new_state.Pass();
26323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  current_state_->AttachState(this, old_object.get());
26423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return old_object.Pass();
26523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
26623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
26768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WindowState::SetPreAutoManageWindowBounds(
26868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const gfx::Rect& bounds) {
26968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  pre_auto_manage_window_bounds_.reset(new gfx::Rect(bounds));
27068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
27168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::AddObserver(WindowStateObserver* observer) {
27368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  observer_list_.AddObserver(observer);
27468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
27568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowState::RemoveObserver(WindowStateObserver* observer) {
27768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  observer_list_.RemoveObserver(observer);
27868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
27968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid WindowState::set_bounds_changed_by_user(bool bounds_changed_by_user) {
2815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bounds_changed_by_user_ = bounds_changed_by_user;
2825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (bounds_changed_by_user)
2835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    pre_auto_manage_window_bounds_.reset();
2845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
2855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowState::CreateDragDetails(aura::Window* window,
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    const gfx::Point& point_in_parent,
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    int window_component,
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    aura::client::WindowMoveSource source) {
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  drag_details_.reset(
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new DragDetails(window, point_in_parent, window_component, source));
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowState::DeleteDragDetails() {
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  drag_details_.reset();
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowState::SetAndClearRestoreBounds() {
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(HasRestoreBounds());
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetBoundsInScreen(GetRestoreBoundsInScreen());
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ClearRestoreBounds();
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowState::OnWindowPropertyChanged(aura::Window* window,
305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                          const void* key,
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                          intptr_t old) {
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(window, window_);
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (key == aura::client::kShowStateKey && !ignore_property_change_) {
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    WMEvent event(WMEventTypeFromShowState(GetShowState()));
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    OnWMEvent(&event);
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowState::SetBoundsInScreen(
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const gfx::Rect& bounds_in_screen) {
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Rect bounds_in_parent =
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ScreenUtil::ConvertRectFromScreen(window_->parent(),
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       bounds_in_screen);
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window_->SetBounds(bounds_in_parent);
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ui::WindowShowState WindowState::GetShowState() const {
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return window_->GetProperty(aura::client::kShowStateKey);
324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowState::AdjustSnappedBounds(gfx::Rect* bounds) {
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_dragged() || !IsSnapped())
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect maximized_bounds = ScreenUtil::GetMaximizedWindowBoundsInParent(
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      window_);
331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (GetStateType() == WINDOW_STATE_TYPE_LEFT_SNAPPED)
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bounds->set_x(maximized_bounds.x());
333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else if (GetStateType() == WINDOW_STATE_TYPE_RIGHT_SNAPPED)
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bounds->set_x(maximized_bounds.right() - bounds->width());
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bounds->set_y(maximized_bounds.y());
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bounds->set_height(maximized_bounds.height());
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowState::UpdateWindowShowStateFromStateType() {
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ui::WindowShowState new_window_state =
341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ToWindowShowState(current_state_->GetType());
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (new_window_state != GetShowState()) {
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::AutoReset<bool> resetter(&ignore_property_change_, true);
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    window_->SetProperty(aura::client::kShowStateKey, new_window_state);
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowState::NotifyPreStateTypeChange(
349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    WindowStateType old_window_state_type) {
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FOR_EACH_OBSERVER(WindowStateObserver, observer_list_,
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    OnPreWindowStateTypeChange(this, old_window_state_type));
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowState::NotifyPostStateTypeChange(
355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    WindowStateType old_window_state_type) {
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FOR_EACH_OBSERVER(WindowStateObserver, observer_list_,
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    OnPostWindowStateTypeChange(this, old_window_state_type));
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowState::SetBoundsDirect(const gfx::Rect& bounds) {
3615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  gfx::Rect actual_new_bounds(bounds);
3625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Ensure we don't go smaller than our minimum bounds in "normal" window
3635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // modes
3645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (window_->delegate() && !IsMaximized() && !IsFullscreen()) {
3655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Get the minimum usable size of the minimum size and the screen size.
3665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    gfx::Size min_size = window_->delegate()->GetMinimumSize();
3675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    min_size.SetToMin(gfx::Screen::GetScreenFor(
3685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        window_)->GetDisplayNearestWindow(window_).work_area().size());
3695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    actual_new_bounds.set_width(
3715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        std::max(min_size.width(), actual_new_bounds.width()));
3725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    actual_new_bounds.set_height(
3735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        std::max(min_size.height(), actual_new_bounds.height()));
3745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
3755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  BoundsSetter().SetBounds(window_, actual_new_bounds);
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowState::SetBoundsConstrained(const gfx::Rect& bounds) {
379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Rect work_area_in_parent =
380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_);
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Rect child_bounds(bounds);
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AdjustBoundsSmallerThan(work_area_in_parent.size(), &child_bounds);
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetBoundsDirect(child_bounds);
384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowState::SetBoundsDirectAnimated(const gfx::Rect& bounds) {
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kBoundsChangeSlideDurationMs = 120;
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::Layer* layer = window_->layer();
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator());
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  slide_settings.SetPreemptionStrategy(
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  slide_settings.SetTransitionDuration(
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kBoundsChangeSlideDurationMs));
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetBoundsDirect(bounds);
39668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
39768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowState::SetBoundsDirectCrossFade(const gfx::Rect& new_bounds) {
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Some test results in invoking CrossFadeToBounds when window is not visible.
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No animation is necessary in that case, thus just change the bounds and
401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // quit.
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!window_->TargetVisibility()) {
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SetBoundsConstrained(new_bounds);
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const gfx::Rect old_bounds = window_->bounds();
408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Create fresh layers for the window and all its children to paint into.
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Takes ownership of the old layer and all its children, which will be
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // cleaned up after the animation completes.
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Specify |set_bounds| to true here to keep the old bounds in the child
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // windows of |window|.
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<ui::LayerTreeOwner> old_layer_owner =
415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ::wm::RecreateLayers(window_);
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ui::Layer* old_layer = old_layer_owner->root();
417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(old_layer);
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ui::Layer* new_layer = window_->layer();
419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Resize the window to the new size, which will force a layout and paint.
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetBoundsDirect(new_bounds);
422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Ensure the higher-resolution layer is on top.
424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool old_on_top = (old_bounds.width() > new_bounds.width());
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (old_on_top)
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    old_layer->parent()->StackBelow(new_layer, old_layer);
427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else
428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    old_layer->parent()->StackAbove(new_layer, old_layer);
429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CrossFadeAnimation(window_, old_layer_owner.Pass(), gfx::Tween::EASE_OUT);
431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
43368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState* GetActiveWindowState() {
43468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  aura::Window* active = GetActiveWindow();
43568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return active ? GetWindowState(active) : NULL;
43668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
43768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
43868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)WindowState* GetWindowState(aura::Window* window) {
43968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!window)
44068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return NULL;
441c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  WindowState* settings = window->GetProperty(kWindowStateKey);
44268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if(!settings) {
44368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    settings = new WindowState(window);
444c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    window->SetProperty(kWindowStateKey, settings);
44568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
44668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return settings;
44768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
44868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
44968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const WindowState* GetWindowState(const aura::Window* window) {
45068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return GetWindowState(const_cast<aura::Window*>(window));
45168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
45268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
45368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace wm
45468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace ash
455