- add sources.
[platform/framework/web/crosswalk.git] / src / ash / wm / window_state.cc
1 // Copyright 2013 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.
4
5 #include "ash/wm/window_state.h"
6
7 #include "ash/root_window_controller.h"
8 #include "ash/screen_ash.h"
9 #include "ash/shell_window_ids.h"
10 #include "ash/wm/window_properties.h"
11 #include "ash/wm/window_state_delegate.h"
12 #include "ash/wm/window_state_observer.h"
13 #include "ash/wm/window_util.h"
14 #include "ash/wm/wm_types.h"
15 #include "ui/aura/client/aura_constants.h"
16 #include "ui/aura/window.h"
17 #include "ui/aura/window_delegate.h"
18 #include "ui/gfx/display.h"
19 #include "ui/views/corewm/window_util.h"
20
21 namespace ash {
22 namespace wm {
23
24 // static
25 bool WindowState::IsMaximizedOrFullscreenState(ui::WindowShowState show_state) {
26   return show_state == ui::SHOW_STATE_FULLSCREEN ||
27       show_state == ui::SHOW_STATE_MAXIMIZED;
28 }
29
30 WindowState::WindowState(aura::Window* window)
31     : window_(window),
32       tracked_by_workspace_(true),
33       window_position_managed_(false),
34       bounds_changed_by_user_(false),
35       panel_attached_(true),
36       continue_drag_after_reparent_(false),
37       ignored_by_shelf_(false),
38       can_consume_system_keys_(false),
39       top_row_keys_are_function_keys_(false),
40       window_resizer_(NULL),
41       always_restores_to_restore_bounds_(false),
42       hide_shelf_when_fullscreen_(true),
43       animate_to_fullscreen_(true),
44       minimum_visibility_(false),
45       window_show_type_(ToWindowShowType(GetShowState())) {
46   window_->AddObserver(this);
47 }
48
49 WindowState::~WindowState() {
50 }
51
52 void WindowState::SetDelegate(scoped_ptr<WindowStateDelegate> delegate) {
53   DCHECK(!delegate_.get());
54   delegate_ = delegate.Pass();
55 }
56
57 ui::WindowShowState WindowState::GetShowState() const {
58   return window_->GetProperty(aura::client::kShowStateKey);
59 }
60
61 bool WindowState::IsMinimized() const {
62   return GetShowState() == ui::SHOW_STATE_MINIMIZED;
63 }
64
65 bool WindowState::IsMaximized() const {
66   return GetShowState() == ui::SHOW_STATE_MAXIMIZED;
67 }
68
69 bool WindowState::IsFullscreen() const {
70   return GetShowState() == ui::SHOW_STATE_FULLSCREEN;
71 }
72
73 bool WindowState::IsMaximizedOrFullscreen() const {
74   return IsMaximizedOrFullscreenState(GetShowState());
75 }
76
77 bool WindowState::IsNormalShowState() const {
78   ui::WindowShowState state = window_->GetProperty(aura::client::kShowStateKey);
79   return state == ui::SHOW_STATE_NORMAL || state == ui::SHOW_STATE_DEFAULT;
80 }
81
82 bool WindowState::IsActive() const {
83   return IsActiveWindow(window_);
84 }
85
86 bool WindowState::IsDocked() const {
87   return window_->parent() &&
88       window_->parent()->id() == internal::kShellWindowId_DockedContainer;
89 }
90
91 bool WindowState::CanMaximize() const {
92   return window_->GetProperty(aura::client::kCanMaximizeKey);
93 }
94
95 bool WindowState::CanMinimize() const {
96   internal::RootWindowController* controller =
97       internal::RootWindowController::ForWindow(window_);
98   if (!controller)
99     return false;
100   aura::Window* lockscreen = controller->GetContainer(
101       internal::kShellWindowId_LockScreenContainersContainer);
102   if (lockscreen->Contains(window_))
103     return false;
104
105   return true;
106 }
107
108 bool WindowState::CanResize() const {
109   return window_->GetProperty(aura::client::kCanResizeKey);
110 }
111
112 bool WindowState::CanActivate() const {
113   return views::corewm::CanActivateWindow(window_);
114 }
115
116 bool WindowState::CanSnap() const {
117   if (!CanResize() ||
118       window_->type() == aura::client::WINDOW_TYPE_PANEL ||
119       window_->transient_parent())
120     return false;
121   // If a window has a maximum size defined, snapping may make it too big.
122   return window_->delegate() ? window_->delegate()->GetMaximumSize().IsEmpty() :
123                               true;
124 }
125
126 bool WindowState::HasRestoreBounds() const {
127   return window_->GetProperty(aura::client::kRestoreBoundsKey) != NULL;
128 }
129
130 void WindowState::Maximize() {
131   window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
132 }
133
134 void WindowState::SnapLeft(const gfx::Rect& bounds) {
135   SnapWindow(SHOW_TYPE_LEFT_SNAPPED, bounds);
136 }
137
138 void WindowState::SnapRight(const gfx::Rect& bounds) {
139   SnapWindow(SHOW_TYPE_LEFT_SNAPPED, bounds);
140 }
141
142 void WindowState::Minimize() {
143   window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
144 }
145
146 void WindowState::Unminimize() {
147   window_->SetProperty(
148       aura::client::kShowStateKey,
149       window_->GetProperty(aura::client::kRestoreShowStateKey));
150   window_->ClearProperty(aura::client::kRestoreShowStateKey);
151 }
152
153 void WindowState::Activate() {
154   ActivateWindow(window_);
155 }
156
157 void WindowState::Deactivate() {
158   DeactivateWindow(window_);
159 }
160
161 void WindowState::Restore() {
162   window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
163 }
164
165 void WindowState::ToggleMaximized() {
166   if (IsMaximized())
167     Restore();
168   else if (CanMaximize())
169     Maximize();
170 }
171
172 void WindowState::ToggleFullscreen() {
173   // Window which cannot be maximized should not be fullscreened.
174   // It can, however, be restored if it was fullscreened.
175   bool is_fullscreen = IsFullscreen();
176   if (!is_fullscreen && !CanMaximize())
177     return;
178   if (delegate_ && delegate_->ToggleFullscreen(this))
179     return;
180   if (is_fullscreen) {
181     Restore();
182   } else {
183     window_->SetProperty(aura::client::kShowStateKey,
184                          ui::SHOW_STATE_FULLSCREEN);
185   }
186 }
187
188 void WindowState::SetBoundsInScreen(
189     const gfx::Rect& bounds_in_screen) {
190   gfx::Rect bounds_in_parent =
191       ScreenAsh::ConvertRectFromScreen(window_->parent(),
192                                        bounds_in_screen);
193   window_->SetBounds(bounds_in_parent);
194 }
195
196 void WindowState::SaveCurrentBoundsForRestore() {
197   gfx::Rect bounds_in_screen =
198       ScreenAsh::ConvertRectToScreen(window_->parent(),
199                                      window_->bounds());
200   SetRestoreBoundsInScreen(bounds_in_screen);
201 }
202
203 gfx::Rect WindowState::GetRestoreBoundsInScreen() const {
204   return *window_->GetProperty(aura::client::kRestoreBoundsKey);
205 }
206
207 gfx::Rect WindowState::GetRestoreBoundsInParent() const {
208   return ScreenAsh::ConvertRectFromScreen(window_->parent(),
209                                           GetRestoreBoundsInScreen());
210 }
211
212 void WindowState::SetRestoreBoundsInScreen(const gfx::Rect& bounds) {
213   window_->SetProperty(aura::client::kRestoreBoundsKey, new gfx::Rect(bounds));
214 }
215
216 void WindowState::SetRestoreBoundsInParent(const gfx::Rect& bounds) {
217   SetRestoreBoundsInScreen(
218       ScreenAsh::ConvertRectToScreen(window_->parent(), bounds));
219 }
220
221 void WindowState::ClearRestoreBounds() {
222   window_->ClearProperty(aura::client::kRestoreBoundsKey);
223 }
224
225 void WindowState::SetPreAutoManageWindowBounds(
226     const gfx::Rect& bounds) {
227   pre_auto_manage_window_bounds_.reset(new gfx::Rect(bounds));
228 }
229
230 void WindowState::AddObserver(WindowStateObserver* observer) {
231   observer_list_.AddObserver(observer);
232 }
233
234 void WindowState::RemoveObserver(WindowStateObserver* observer) {
235   observer_list_.RemoveObserver(observer);
236 }
237
238 void WindowState::SetTrackedByWorkspace(bool tracked_by_workspace) {
239   if (tracked_by_workspace_ == tracked_by_workspace)
240     return;
241   bool old = tracked_by_workspace_;
242   tracked_by_workspace_ = tracked_by_workspace;
243   FOR_EACH_OBSERVER(WindowStateObserver, observer_list_,
244                     OnTrackedByWorkspaceChanged(this, old));
245 }
246
247 void WindowState::OnWindowPropertyChanged(aura::Window* window,
248                                           const void* key,
249                                           intptr_t old) {
250   DCHECK_EQ(window, window_);
251   if (key == aura::client::kShowStateKey) {
252     window_show_type_ = ToWindowShowType(GetShowState());
253     ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old);
254     // TODO(oshima): Notify only when the state has changed.
255     // Doing so break a few tests now.
256     FOR_EACH_OBSERVER(
257         WindowStateObserver, observer_list_,
258         OnWindowShowTypeChanged(this, ToWindowShowType(old_state)));
259   }
260 }
261
262 void WindowState::OnWindowDestroying(aura::Window* window) {
263   window_->RemoveObserver(this);
264 }
265
266 void WindowState::SnapWindow(WindowShowType left_or_right,
267                              const gfx::Rect& bounds) {
268   if (IsMaximizedOrFullscreen()) {
269     // Before we can set the bounds we need to restore the window.
270     // Restoring the window will set the window to its restored bounds.
271     // To avoid an unnecessary bounds changes (which may have side effects)
272     // we set the restore bounds to the bounds we want, restore the window,
273     // then reset the restore bounds. This way no unnecessary bounds
274     // changes occurs and the original restore bounds is remembered.
275     gfx::Rect restore_bounds_in_screen =
276         GetRestoreBoundsInScreen();
277     SetRestoreBoundsInParent(bounds);
278     Restore();
279     SetRestoreBoundsInScreen(restore_bounds_in_screen);
280   } else {
281     window_->SetBounds(bounds);
282   }
283   DCHECK(left_or_right == SHOW_TYPE_LEFT_SNAPPED ||
284          left_or_right == SHOW_TYPE_RIGHT_SNAPPED);
285   window_show_type_ = left_or_right;
286 }
287
288 WindowState* GetActiveWindowState() {
289   aura::Window* active = GetActiveWindow();
290   return active ? GetWindowState(active) : NULL;
291 }
292
293 WindowState* GetWindowState(aura::Window* window) {
294   if (!window)
295     return NULL;
296   WindowState* settings = window->GetProperty(internal::kWindowStateKey);
297   if(!settings) {
298     settings = new WindowState(window);
299     window->SetProperty(internal::kWindowStateKey, settings);
300   }
301   return settings;
302 }
303
304 const WindowState* GetWindowState(const aura::Window* window) {
305   return GetWindowState(const_cast<aura::Window*>(window));
306 }
307
308 }  // namespace wm
309 }  // namespace ash