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.
5 #ifndef ASH_WM_WINDOW_STATE_H_
6 #define ASH_WM_WINDOW_STATE_H_
8 #include "ash/ash_export.h"
9 #include "ash/wm/drag_details.h"
10 #include "ash/wm/wm_types.h"
11 #include "base/basictypes.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/observer_list.h"
15 #include "ui/aura/window_observer.h"
16 #include "ui/base/ui_base_types.h"
28 class WorkspaceLayoutManager
;
32 class WindowStateDelegate
;
33 class WindowStateObserver
;
35 // WindowState manages and defines ash specific window state and
36 // behavior. Ash specific per-window state (such as ones that controls
37 // window manager behavior) and ash specific window behavior (such as
38 // maximize, minimize, snap sizing etc) should be added here instead
39 // of defining separate functions (like |MaximizeWindow(aura::Window*
40 // window)|) or using aura Window property.
41 // The WindowState gets created when first accessed by
42 // |wm::GetWindowState|, and deleted when the window is deleted.
43 // Prefer using this class instead of passing aura::Window* around in
44 // ash code as this is often what you need to interact with, and
45 // accessing the window using |window()| is cheap.
46 class ASH_EXPORT WindowState
: public aura::WindowObserver
{
49 // A subclass of State class represents one of the window's states
50 // that corresponds WnidowShowType to in Ash environment, e.g.
51 // maximized, minimized or side snapped, as subclass.
52 // Each subclass defines its own behavior and transition for each WMEvent.
58 // Update WindowState based on |event|.
59 virtual void OnWMEvent(WindowState
* state
, WMEvent event
) = 0;
61 // See WindowState::RequestBounds.
62 virtual void RequestBounds(WindowState
* state
,
63 const gfx::Rect
& requested_bounds
) = 0;
66 DISALLOW_COPY_AND_ASSIGN(State
);
69 explicit WindowState(aura::Window
* window
);
70 virtual ~WindowState();
72 aura::Window
* window() { return window_
; }
73 const aura::Window
* window() const { return window_
; }
75 bool HasDelegate() const;
76 void SetDelegate(scoped_ptr
<WindowStateDelegate
> delegate
);
78 // Returns the window's current show state.
79 ui::WindowShowState
GetShowState() const;
81 // Returns the window's current ash show type.
82 // Refer to WindowShowType definition in wm_types.h as for why Ash
83 // has its own show type.
84 WindowShowType
window_show_type() const { return window_show_type_
; }
86 // Predicates to check window state.
87 bool IsMinimized() const;
88 bool IsMaximized() const;
89 bool IsFullscreen() const;
90 bool IsMaximizedOrFullscreen() const;
91 bool IsSnapped() const;
93 // True if the window's show type is SHOW_TYPE_NORMAL or SHOW_TYPE_DEFAULT.
94 bool IsNormalShowType() const;
96 bool IsNormalOrSnapped() const;
98 bool IsActive() const;
99 bool IsDocked() const;
101 // Checks if the window can change its state accordingly.
102 bool CanMaximize() const;
103 bool CanMinimize() const;
104 bool CanResize() const;
105 bool CanSnap() const;
106 bool CanActivate() const;
108 // Returns true if the window has restore bounds.
109 bool HasRestoreBounds() const;
117 void ToggleFullscreen();
118 void SnapLeftWithDefaultWidth();
119 void SnapRightWithDefaultWidth();
121 // A window is requested to be the given bounds. The request may or
122 // may not be fulfilled depending on the requested bounds and window's
124 // TODO(oshima): Convert this to a WMEvent.
125 void RequestBounds(const gfx::Rect
& bounds
);
127 // Invoked when a WMevent occurs, which drives the internal
129 void OnWMEvent(WMEvent event
);
131 // Sets the window's bounds in screen coordinates.
132 void SetBoundsInScreen(const gfx::Rect
& bounds_in_screen
);
134 // Saves the current bounds to be used as a restore bounds.
135 void SaveCurrentBoundsForRestore();
137 // Same as |GetRestoreBoundsInScreen| except that it returns the
138 // bounds in the parent's coordinates.
139 gfx::Rect
GetRestoreBoundsInParent() const;
141 // Returns the restore bounds property on the window in the virtual screen
142 // coordinates. The bounds can be NULL if the bounds property does not
143 // exist for the window. The window owns the bounds object.
144 gfx::Rect
GetRestoreBoundsInScreen() const;
146 // Same as |SetRestoreBoundsInScreen| except that the bounds is in the
147 // parent's coordinates.
148 void SetRestoreBoundsInParent(const gfx::Rect
& bounds_in_parent
);
150 // Sets the restore bounds property on the window in the virtual screen
151 // coordinates. Deletes existing bounds value if exists.
152 void SetRestoreBoundsInScreen(const gfx::Rect
& bounds_in_screen
);
154 // Deletes and clears the restore bounds property on the window.
155 void ClearRestoreBounds();
157 // True if the window should be unminimized to the restore bounds, as
158 // opposed to the window's current bounds. |unminimized_to_restore_bounds_| is
159 // reset to the default value after the window is unminimized.
160 bool unminimize_to_restore_bounds() const {
161 return unminimize_to_restore_bounds_
;
163 void set_unminimize_to_restore_bounds(bool value
) {
164 unminimize_to_restore_bounds_
= value
;
167 // Gets/sets whether the shelf should be hidden when this window is
169 bool hide_shelf_when_fullscreen() const {
170 return hide_shelf_when_fullscreen_
;
173 void set_hide_shelf_when_fullscreen(bool value
) {
174 hide_shelf_when_fullscreen_
= value
;
177 // Sets/gets the flag to suppress the cross-fade animation for
178 // the transition to the fullscreen state.
179 bool animate_to_fullscreen() const {
180 return animate_to_fullscreen_
;
182 void set_animate_to_fullscreen(bool value
) {
183 animate_to_fullscreen_
= value
;
186 // If the minimum visibilty is true, ash will try to keep a
187 // minimum amount of the window is always visible on the work area
189 // TODO(oshima): Consolidate this and window_position_managed
190 // into single parameter to control the window placement.
191 bool minimum_visibility() const {
192 return minimum_visibility_
;
194 void set_minimum_visibility(bool minimum_visibility
) {
195 minimum_visibility_
= minimum_visibility
;
198 // Gets/Sets the bounds of the window before it was moved by the auto window
199 // management. As long as it was not auto-managed, it will return NULL.
200 const gfx::Rect
* pre_auto_manage_window_bounds() const {
201 return pre_auto_manage_window_bounds_
.get();
203 void SetPreAutoManageWindowBounds(const gfx::Rect
& bounds
);
205 // Layout related properties
207 void AddObserver(WindowStateObserver
* observer
);
208 void RemoveObserver(WindowStateObserver
* observer
);
210 // Whether the window is being dragged.
211 bool is_dragged() const {
212 return drag_details_
;
215 // Whether or not the window's position can be managed by the
216 // auto management logic.
217 bool window_position_managed() const { return window_position_managed_
; }
218 void set_window_position_managed(bool window_position_managed
) {
219 window_position_managed_
= window_position_managed
;
222 // Whether or not the window's position or size was changed by a user.
223 bool bounds_changed_by_user() const { return bounds_changed_by_user_
; }
224 void set_bounds_changed_by_user(bool bounds_changed_by_user
) {
225 bounds_changed_by_user_
= bounds_changed_by_user
;
228 // True if this window is an attached panel.
229 bool panel_attached() const {
230 return panel_attached_
;
232 void set_panel_attached(bool panel_attached
) {
233 panel_attached_
= panel_attached
;
236 // True if the window is ignored by the shelf layout manager for
237 // purposes of darkening the shelf.
238 bool ignored_by_shelf() const { return ignored_by_shelf_
; }
239 void set_ignored_by_shelf(bool ignored_by_shelf
) {
240 ignored_by_shelf_
= ignored_by_shelf
;
243 // True if the window should be offered a chance to consume special system
244 // keys such as brightness, volume, etc. that are usually handled by the
246 bool can_consume_system_keys() const { return can_consume_system_keys_
; }
247 void set_can_consume_system_keys(bool can_consume_system_keys
) {
248 can_consume_system_keys_
= can_consume_system_keys
;
251 // True if this window has requested that the top-row keys (back, forward,
252 // brightness, volume) should be treated as function keys.
253 bool top_row_keys_are_function_keys() const {
254 return top_row_keys_are_function_keys_
;
256 void set_top_row_keys_are_function_keys(bool value
) {
257 top_row_keys_are_function_keys_
= value
;
260 // Creates and takes ownership of a pointer to DragDetails when resizing is
261 // active. This should be done before a resizer gets created.
262 void CreateDragDetails(aura::Window
* window
,
263 const gfx::Point
& point_in_parent
,
264 int window_component
,
265 aura::client::WindowMoveSource source
);
267 // Deletes and clears a pointer to DragDetails. This should be done when the
268 // resizer gets destroyed.
269 void DeleteDragDetails();
271 // Sets the currently stored restore bounds and clears the restore bounds.
272 void SetAndClearRestoreBounds();
274 // Returns a pointer to DragDetails during drag operations.
275 const DragDetails
* drag_details() const { return drag_details_
.get(); }
276 DragDetails
* drag_details() { return drag_details_
.get(); }
278 // aura::WindowObserver overrides:
279 virtual void OnWindowPropertyChanged(aura::Window
* window
,
281 intptr_t old
) OVERRIDE
;
284 friend class DefaultState
;
285 FRIEND_TEST_ALL_PREFIXES(WindowAnimationsTest
, CrossFadeToBounds
);
287 WindowStateDelegate
* delegate() { return delegate_
.get(); }
289 // Adjusts the |bounds| so that they are flush with the edge of the
290 // workspace if the window represented by |window_state| is side snapped.
291 void AdjustSnappedBounds(gfx::Rect
* bounds
);
293 // Snaps the window left or right with the default width.
294 void SnapWindowWithDefaultWidth(WindowShowType left_or_right
);
296 // Sets the window show type and updates the show state if necessary.
297 // Note that this does not update the window bounds.
298 void UpdateWindowShowType(WindowShowType new_window_show_type
);
300 void NotifyPreShowTypeChange(WindowShowType old_window_show_type
);
301 void NotifyPostShowTypeChange(WindowShowType old_window_show_type
);
303 // Sets |bounds| as is.
304 void SetBoundsDirect(const gfx::Rect
& bounds
);
306 // Sets the window's |bounds| with constraint where the size of the
307 // new bounds will not exceeds the size of the work area.
308 void SetBoundsConstrained(const gfx::Rect
& bounds
);
310 // Sets the wndow's |bounds| and transitions to the new bounds with
311 // a scale animation.
312 void SetBoundsDirectAnimated(const gfx::Rect
& bounds
);
314 // Sets the window's |bounds| and transition to the new bounds with
315 // a cross fade animation.
316 void SetBoundsDirectCrossFade(const gfx::Rect
& bounds
);
318 // The owner of this window settings.
319 aura::Window
* window_
;
320 scoped_ptr
<WindowStateDelegate
> delegate_
;
322 bool window_position_managed_
;
323 bool bounds_changed_by_user_
;
324 bool panel_attached_
;
325 bool ignored_by_shelf_
;
326 bool can_consume_system_keys_
;
327 bool top_row_keys_are_function_keys_
;
328 scoped_ptr
<DragDetails
> drag_details_
;
330 bool unminimize_to_restore_bounds_
;
331 bool hide_shelf_when_fullscreen_
;
332 bool animate_to_fullscreen_
;
333 bool minimum_visibility_
;
335 // A property to remember the window position which was set before the
336 // auto window position manager changed the window bounds, so that it can get
337 // restored when only this one window gets shown.
338 scoped_ptr
<gfx::Rect
> pre_auto_manage_window_bounds_
;
340 ObserverList
<WindowStateObserver
> observer_list_
;
342 // True to ignore a property change event to avoid reentrance in
343 // UpdateWindowShowType()
344 bool ignore_property_change_
;
346 WindowShowType window_show_type_
;
348 scoped_ptr
<State
> current_state_
;
350 DISALLOW_COPY_AND_ASSIGN(WindowState
);
353 // Returns the WindowState for active window. Returns |NULL|
354 // if there is no active window.
355 ASH_EXPORT WindowState
* GetActiveWindowState();
357 // Returns the WindowState for |window|. Creates WindowState
358 // if it didn't exist. The settings object is owned by |window|.
359 ASH_EXPORT WindowState
* GetWindowState(aura::Window
* window
);
361 // const version of GetWindowState.
362 ASH_EXPORT
const WindowState
*
363 GetWindowState(const aura::Window
* window
);
368 #endif // ASH_WM_WINDOW_STATE_H_