window_state.h revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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#ifndef ASH_WM_WINDOW_STATE_H_ 6#define ASH_WM_WINDOW_STATE_H_ 7 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" 17 18namespace aura { 19class Window; 20} 21 22namespace gfx { 23class Rect; 24} 25 26namespace ash { 27class WorkspaceLayoutManager; 28class MaximizeModeWindowState; 29 30namespace wm { 31class WindowStateDelegate; 32class WindowStateObserver; 33class WMEvent; 34 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. 46class ASH_EXPORT WindowState : public aura::WindowObserver { 47 public: 48 49 // A subclass of State class represents one of the window's states 50 // that corresponds to WindowStateType 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. 53 class State { 54 public: 55 State() {} 56 virtual ~State() {} 57 58 // Update WindowState based on |event|. 59 virtual void OnWMEvent(WindowState* window_state, const WMEvent* event) = 0; 60 61 virtual WindowStateType GetType() const = 0; 62 63 // Gets called when the state object became active and the managed window 64 // needs to be adjusted to the State's requirement. 65 // The passed |previous_state| may be used to properly implement state 66 // transitions such as bound animations from the previous state. 67 // Note: This only gets called when the state object gets changed. 68 virtual void AttachState(WindowState* window_state, 69 State* previous_state) = 0; 70 71 // Gets called before the state objects gets deactivated / detached from the 72 // window, so that it can save the various states it is interested in. 73 // Note: This only gets called when the state object gets changed. 74 virtual void DetachState(WindowState* window_state) = 0; 75 76 private: 77 DISALLOW_COPY_AND_ASSIGN(State); 78 }; 79 80 explicit WindowState(aura::Window* window); 81 virtual ~WindowState(); 82 83 aura::Window* window() { return window_; } 84 const aura::Window* window() const { return window_; } 85 86 bool HasDelegate() const; 87 void SetDelegate(scoped_ptr<WindowStateDelegate> delegate); 88 89 // Returns the window's current ash state type. 90 // Refer to WindowStateType definition in wm_types.h as for why Ash 91 // has its own state type. 92 WindowStateType GetStateType() const; 93 94 // Predicates to check window state. 95 bool IsMinimized() const; 96 bool IsMaximized() const; 97 bool IsFullscreen() const; 98 bool IsMaximizedOrFullscreen() const; 99 bool IsSnapped() const; 100 101 // True if the window's state type is WINDOW_STATE_TYPE_NORMAL or 102 // WINDOW_STATE_TYPE_DEFAULT. 103 bool IsNormalStateType() const; 104 105 bool IsNormalOrSnapped() const; 106 107 bool IsActive() const; 108 bool IsDocked() const; 109 110 // Checks if the window can change its state accordingly. 111 bool CanMaximize() const; 112 bool CanMinimize() const; 113 bool CanResize() const; 114 bool CanSnap() const; 115 bool CanActivate() const; 116 117 // Returns true if the window has restore bounds. 118 bool HasRestoreBounds() const; 119 120 // These methods use aura::WindowProperty to change the window's state 121 // instead of using WMEvent directly. This is to use the same mechanism as 122 // what views::Widget is using. 123 void Maximize(); 124 void Minimize(); 125 void Unminimize(); 126 127 void Activate(); 128 void Deactivate(); 129 130 // Set the window state to normal. 131 // TODO(oshima): Change to use RESTORE event. 132 void Restore(); 133 134 // Invoked when a WMevent occurs, which drives the internal 135 // state machine. 136 void OnWMEvent(const WMEvent* event); 137 138 // TODO(oshima): Try hiding these methods and making them accessible only to 139 // state impl. State changes should happen through events (as much 140 // as possible). 141 142 // Saves the current bounds to be used as a restore bounds. 143 void SaveCurrentBoundsForRestore(); 144 145 // Same as |GetRestoreBoundsInScreen| except that it returns the 146 // bounds in the parent's coordinates. 147 gfx::Rect GetRestoreBoundsInParent() const; 148 149 // Returns the restore bounds property on the window in the virtual screen 150 // coordinates. The bounds can be NULL if the bounds property does not 151 // exist for the window. The window owns the bounds object. 152 gfx::Rect GetRestoreBoundsInScreen() const; 153 154 // Same as |SetRestoreBoundsInScreen| except that the bounds is in the 155 // parent's coordinates. 156 void SetRestoreBoundsInParent(const gfx::Rect& bounds_in_parent); 157 158 // Sets the restore bounds property on the window in the virtual screen 159 // coordinates. Deletes existing bounds value if exists. 160 void SetRestoreBoundsInScreen(const gfx::Rect& bounds_in_screen); 161 162 // Deletes and clears the restore bounds property on the window. 163 void ClearRestoreBounds(); 164 165 // Replace the State object of a window with a state handler which can 166 // implement a new window manager type. The passed object will be owned 167 // by this object and the returned object will be owned by the caller. 168 scoped_ptr<State> SetStateObject(scoped_ptr<State> new_state); 169 170 // True if the window should be unminimized to the restore bounds, as 171 // opposed to the window's current bounds. |unminimized_to_restore_bounds_| is 172 // reset to the default value after the window is unminimized. 173 bool unminimize_to_restore_bounds() const { 174 return unminimize_to_restore_bounds_; 175 } 176 void set_unminimize_to_restore_bounds(bool value) { 177 unminimize_to_restore_bounds_ = value; 178 } 179 180 // Gets/sets whether the shelf should be hidden when this window is 181 // fullscreen. 182 bool hide_shelf_when_fullscreen() const { 183 return hide_shelf_when_fullscreen_; 184 } 185 186 void set_hide_shelf_when_fullscreen(bool value) { 187 hide_shelf_when_fullscreen_ = value; 188 } 189 190 // If the minimum visibilty is true, ash will try to keep a 191 // minimum amount of the window is always visible on the work area 192 // when shown. 193 // TODO(oshima): Consolidate this and window_position_managed 194 // into single parameter to control the window placement. 195 bool minimum_visibility() const { 196 return minimum_visibility_; 197 } 198 void set_minimum_visibility(bool minimum_visibility) { 199 minimum_visibility_ = minimum_visibility; 200 } 201 202 // Specifies if the window can be dragged by the user via the caption or not. 203 bool can_be_dragged() const { 204 return can_be_dragged_; 205 } 206 void set_can_be_dragged(bool can_be_dragged) { 207 can_be_dragged_ = can_be_dragged; 208 } 209 210 // Gets/Sets the bounds of the window before it was moved by the auto window 211 // management. As long as it was not auto-managed, it will return NULL. 212 const gfx::Rect* pre_auto_manage_window_bounds() const { 213 return pre_auto_manage_window_bounds_.get(); 214 } 215 void SetPreAutoManageWindowBounds(const gfx::Rect& bounds); 216 217 // Layout related properties 218 219 void AddObserver(WindowStateObserver* observer); 220 void RemoveObserver(WindowStateObserver* observer); 221 222 // Whether the window is being dragged. 223 bool is_dragged() const { 224 return drag_details_; 225 } 226 227 // Whether or not the window's position can be managed by the 228 // auto management logic. 229 bool window_position_managed() const { return window_position_managed_; } 230 void set_window_position_managed(bool window_position_managed) { 231 window_position_managed_ = window_position_managed; 232 } 233 234 // Whether or not the window's position or size was changed by a user. 235 bool bounds_changed_by_user() const { return bounds_changed_by_user_; } 236 void set_bounds_changed_by_user(bool bounds_changed_by_user) { 237 bounds_changed_by_user_ = bounds_changed_by_user; 238 } 239 240 // True if this window is an attached panel. 241 bool panel_attached() const { 242 return panel_attached_; 243 } 244 void set_panel_attached(bool panel_attached) { 245 panel_attached_ = panel_attached; 246 } 247 248 // True if the window is ignored by the shelf layout manager for 249 // purposes of darkening the shelf. 250 bool ignored_by_shelf() const { return ignored_by_shelf_; } 251 void set_ignored_by_shelf(bool ignored_by_shelf) { 252 ignored_by_shelf_ = ignored_by_shelf; 253 } 254 255 // True if the window should be offered a chance to consume special system 256 // keys such as brightness, volume, etc. that are usually handled by the 257 // shell. 258 bool can_consume_system_keys() const { return can_consume_system_keys_; } 259 void set_can_consume_system_keys(bool can_consume_system_keys) { 260 can_consume_system_keys_ = can_consume_system_keys; 261 } 262 263 // True if this window has requested that the top-row keys (back, forward, 264 // brightness, volume) should be treated as function keys. 265 bool top_row_keys_are_function_keys() const { 266 return top_row_keys_are_function_keys_; 267 } 268 void set_top_row_keys_are_function_keys(bool value) { 269 top_row_keys_are_function_keys_ = value; 270 } 271 272 // Creates and takes ownership of a pointer to DragDetails when resizing is 273 // active. This should be done before a resizer gets created. 274 void CreateDragDetails(aura::Window* window, 275 const gfx::Point& point_in_parent, 276 int window_component, 277 aura::client::WindowMoveSource source); 278 279 // Deletes and clears a pointer to DragDetails. This should be done when the 280 // resizer gets destroyed. 281 void DeleteDragDetails(); 282 283 // Sets the currently stored restore bounds and clears the restore bounds. 284 void SetAndClearRestoreBounds(); 285 286 // Returns a pointer to DragDetails during drag operations. 287 const DragDetails* drag_details() const { return drag_details_.get(); } 288 DragDetails* drag_details() { return drag_details_.get(); } 289 290 // aura::WindowObserver overrides: 291 virtual void OnWindowPropertyChanged(aura::Window* window, 292 const void* key, 293 intptr_t old) OVERRIDE; 294 295 private: 296 friend class DefaultState; 297 friend class ash::MaximizeModeWindowState; 298 FRIEND_TEST_ALL_PREFIXES(WindowAnimationsTest, CrossFadeToBounds); 299 300 WindowStateDelegate* delegate() { return delegate_.get(); } 301 302 // Returns the window's current show state. 303 ui::WindowShowState GetShowState() const; 304 305 // Sets the window's bounds in screen coordinates. 306 void SetBoundsInScreen(const gfx::Rect& bounds_in_screen); 307 308 // Adjusts the |bounds| so that they are flush with the edge of the 309 // workspace if the window represented by |window_state| is side snapped. 310 void AdjustSnappedBounds(gfx::Rect* bounds); 311 312 // Updates the window show state according to the current window state type. 313 // Note that this does not update the window bounds. 314 void UpdateWindowShowStateFromStateType(); 315 316 void NotifyPreStateTypeChange(WindowStateType old_window_state_type); 317 void NotifyPostStateTypeChange(WindowStateType old_window_state_type); 318 319 // Sets |bounds| as is. 320 void SetBoundsDirect(const gfx::Rect& bounds); 321 322 // Sets the window's |bounds| with constraint where the size of the 323 // new bounds will not exceeds the size of the work area. 324 void SetBoundsConstrained(const gfx::Rect& bounds); 325 326 // Sets the wndow's |bounds| and transitions to the new bounds with 327 // a scale animation. 328 void SetBoundsDirectAnimated(const gfx::Rect& bounds); 329 330 // Sets the window's |bounds| and transition to the new bounds with 331 // a cross fade animation. 332 void SetBoundsDirectCrossFade(const gfx::Rect& bounds); 333 334 // The owner of this window settings. 335 aura::Window* window_; 336 scoped_ptr<WindowStateDelegate> delegate_; 337 338 bool window_position_managed_; 339 bool bounds_changed_by_user_; 340 bool panel_attached_; 341 bool ignored_by_shelf_; 342 bool can_consume_system_keys_; 343 bool top_row_keys_are_function_keys_; 344 scoped_ptr<DragDetails> drag_details_; 345 346 bool unminimize_to_restore_bounds_; 347 bool hide_shelf_when_fullscreen_; 348 bool minimum_visibility_; 349 bool can_be_dragged_; 350 351 // A property to remember the window position which was set before the 352 // auto window position manager changed the window bounds, so that it can get 353 // restored when only this one window gets shown. 354 scoped_ptr<gfx::Rect> pre_auto_manage_window_bounds_; 355 356 ObserverList<WindowStateObserver> observer_list_; 357 358 // True to ignore a property change event to avoid reentrance in 359 // UpdateWindowStateType() 360 bool ignore_property_change_; 361 362 scoped_ptr<State> current_state_; 363 364 DISALLOW_COPY_AND_ASSIGN(WindowState); 365}; 366 367// Returns the WindowState for active window. Returns |NULL| 368// if there is no active window. 369ASH_EXPORT WindowState* GetActiveWindowState(); 370 371// Returns the WindowState for |window|. Creates WindowState 372// if it didn't exist. The settings object is owned by |window|. 373ASH_EXPORT WindowState* GetWindowState(aura::Window* window); 374 375// const version of GetWindowState. 376ASH_EXPORT const WindowState* 377GetWindowState(const aura::Window* window); 378 379} // namespace wm 380} // namespace ash 381 382#endif // ASH_WM_WINDOW_STATE_H_ 383