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