1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/wm/lock_window_state.h"
7 #include "ash/screen_util.h"
9 #include "ash/wm/lock_layout_manager.h"
10 #include "ash/wm/window_animations.h"
11 #include "ash/wm/window_state.h"
12 #include "ash/wm/window_state_delegate.h"
13 #include "ash/wm/window_state_util.h"
14 #include "ash/wm/window_util.h"
15 #include "ash/wm/wm_event.h"
16 #include "ui/aura/window.h"
17 #include "ui/aura/window_delegate.h"
18 #include "ui/gfx/rect.h"
19 #include "ui/keyboard/keyboard_controller.h"
20 #include "ui/keyboard/keyboard_util.h"
21 #include "ui/wm/core/window_animations.h"
25 LockWindowState::LockWindowState(aura::Window
* window
)
26 : current_state_type_(wm::GetWindowState(window
)->GetStateType()) {
29 LockWindowState::~LockWindowState() {
32 void LockWindowState::OnWMEvent(wm::WindowState
* window_state
,
33 const wm::WMEvent
* event
) {
34 aura::Window
* window
= window_state
->window();
35 gfx::Rect bounds
= window
->bounds();
37 switch (event
->type()) {
38 case wm::WM_EVENT_TOGGLE_FULLSCREEN
:
39 ToggleFullScreen(window_state
, window_state
->delegate());
41 case wm::WM_EVENT_FULLSCREEN
:
42 UpdateWindow(window_state
, wm::WINDOW_STATE_TYPE_FULLSCREEN
);
44 case wm::WM_EVENT_TOGGLE_MAXIMIZE_CAPTION
:
45 case wm::WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE
:
46 case wm::WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE
:
47 case wm::WM_EVENT_TOGGLE_MAXIMIZE
:
48 case wm::WM_EVENT_CENTER
:
49 case wm::WM_EVENT_SNAP_LEFT
:
50 case wm::WM_EVENT_SNAP_RIGHT
:
51 case wm::WM_EVENT_NORMAL
:
52 case wm::WM_EVENT_MAXIMIZE
:
53 UpdateWindow(window_state
,
54 GetMaximizedOrCenteredWindowType(window_state
));
56 case wm::WM_EVENT_MINIMIZE
:
57 UpdateWindow(window_state
, wm::WINDOW_STATE_TYPE_MINIMIZED
);
59 case wm::WM_EVENT_SHOW_INACTIVE
:
61 case wm::WM_EVENT_SET_BOUNDS
:
62 if (window_state
->IsMaximized() || window_state
->IsFullscreen()) {
63 UpdateBounds(window_state
);
65 const ash::wm::SetBoundsEvent
* bounds_event
=
66 static_cast<const ash::wm::SetBoundsEvent
*>(event
);
67 window_state
->SetBoundsConstrained(bounds_event
->requested_bounds());
70 case wm::WM_EVENT_ADDED_TO_WORKSPACE
:
71 if (current_state_type_
!= wm::WINDOW_STATE_TYPE_MAXIMIZED
&&
72 current_state_type_
!= wm::WINDOW_STATE_TYPE_MINIMIZED
&&
73 current_state_type_
!= wm::WINDOW_STATE_TYPE_FULLSCREEN
) {
74 UpdateWindow(window_state
,
75 GetMaximizedOrCenteredWindowType(window_state
));
78 case wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED
:
79 case wm::WM_EVENT_DISPLAY_BOUNDS_CHANGED
:
80 UpdateBounds(window_state
);
85 wm::WindowStateType
LockWindowState::GetType() const {
86 return current_state_type_
;
89 void LockWindowState::AttachState(wm::WindowState
* window_state
,
90 wm::WindowState::State
* previous_state
) {
91 current_state_type_
= previous_state
->GetType();
93 // Initialize the state to a good preset.
94 if (current_state_type_
!= wm::WINDOW_STATE_TYPE_MAXIMIZED
&&
95 current_state_type_
!= wm::WINDOW_STATE_TYPE_MINIMIZED
&&
96 current_state_type_
!= wm::WINDOW_STATE_TYPE_FULLSCREEN
) {
97 UpdateWindow(window_state
,
98 GetMaximizedOrCenteredWindowType(window_state
));
102 void LockWindowState::DetachState(wm::WindowState
* window_state
) {
106 wm::WindowState
* LockWindowState::SetLockWindowState(aura::Window
* window
) {
107 scoped_ptr
<wm::WindowState::State
> lock_state(new LockWindowState(window
));
108 scoped_ptr
<wm::WindowState::State
> old_state(
109 wm::GetWindowState(window
)->SetStateObject(lock_state
.Pass()));
110 return wm::GetWindowState(window
);
113 void LockWindowState::UpdateWindow(wm::WindowState
* window_state
,
114 wm::WindowStateType target_state
) {
115 DCHECK(target_state
== wm::WINDOW_STATE_TYPE_MINIMIZED
||
116 target_state
== wm::WINDOW_STATE_TYPE_MAXIMIZED
||
117 (target_state
== wm::WINDOW_STATE_TYPE_NORMAL
&&
118 !window_state
->CanMaximize()) ||
119 target_state
== wm::WINDOW_STATE_TYPE_FULLSCREEN
);
121 if (target_state
== wm::WINDOW_STATE_TYPE_MINIMIZED
) {
122 if (current_state_type_
== wm::WINDOW_STATE_TYPE_MINIMIZED
)
125 current_state_type_
= target_state
;
126 ::wm::SetWindowVisibilityAnimationType(
127 window_state
->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE
);
128 window_state
->window()->Hide();
129 if (window_state
->IsActive())
130 window_state
->Deactivate();
134 if (current_state_type_
== target_state
) {
135 // If the state type did not change, update it accordingly.
136 UpdateBounds(window_state
);
140 const wm::WindowStateType old_state_type
= current_state_type_
;
141 current_state_type_
= target_state
;
142 window_state
->UpdateWindowShowStateFromStateType();
143 window_state
->NotifyPreStateTypeChange(old_state_type
);
144 UpdateBounds(window_state
);
145 window_state
->NotifyPostStateTypeChange(old_state_type
);
147 if ((window_state
->window()->TargetVisibility() ||
148 old_state_type
== wm::WINDOW_STATE_TYPE_MINIMIZED
) &&
149 !window_state
->window()->layer()->visible()) {
150 // The layer may be hidden if the window was previously minimized. Make
151 // sure it's visible.
152 window_state
->window()->Show();
156 wm::WindowStateType
LockWindowState::GetMaximizedOrCenteredWindowType(
157 wm::WindowState
* window_state
) {
158 return window_state
->CanMaximize() ? wm::WINDOW_STATE_TYPE_MAXIMIZED
:
159 wm::WINDOW_STATE_TYPE_NORMAL
;
162 void LockWindowState::UpdateBounds(wm::WindowState
* window_state
) {
163 if (!window_state
->IsMaximized() && !window_state
->IsFullscreen())
166 keyboard::KeyboardController
* keyboard_controller
=
167 keyboard::KeyboardController::GetInstance();
168 gfx::Rect keyboard_bounds
;
170 if (keyboard_controller
&& !keyboard::IsKeyboardOverscrollEnabled())
171 keyboard_bounds
= keyboard_controller
->current_keyboard_bounds();
174 ScreenUtil::GetDisplayBoundsInParent(window_state
->window());
175 bounds
.set_height(bounds
.height() - keyboard_bounds
.height());
176 window_state
->SetBoundsDirect(bounds
);