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_COMMON_WINDOW_STATE_H_ | |
6 #define ASH_WM_COMMON_WINDOW_STATE_H_ | |
7 | |
8 #include <memory> | |
9 | |
10 #include "ash/ash_export.h" | |
11 #include "ash/wm/common/drag_details.h" | |
12 #include "ash/wm/common/wm_types.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 #include "ui/gfx/geometry/insets.h" | |
18 | |
19 namespace aura { | |
20 class Window; | |
21 } | |
22 | |
23 namespace gfx { | |
24 class Rect; | |
25 } | |
26 | |
27 namespace ash { | |
28 class LockWindowState; | |
29 class MaximizeModeWindowState; | |
30 | |
31 namespace wm { | |
32 class WindowStateDelegate; | |
33 class WindowStateObserver; | |
34 class WMEvent; | |
35 class WmWindow; | |
36 | |
37 // WindowState manages and defines ash specific window state and | |
38 // behavior. Ash specific per-window state (such as ones that controls | |
39 // window manager behavior) and ash specific window behavior (such as | |
40 // maximize, minimize, snap sizing etc) should be added here instead | |
41 // of defining separate functions (like |MaximizeWindow(aura::Window* | |
42 // window)|) or using aura Window property. | |
43 // The WindowState gets created when first accessed by | |
44 // |wm::GetWindowState|, and deleted when the window is deleted. | |
45 // Prefer using this class instead of passing aura::Window* around in | |
46 // ash code as this is often what you need to interact with, and | |
47 // accessing the window using |window()| is cheap. | |
48 class ASH_EXPORT WindowState { | |
49 public: | |
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 virtual ~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 { return minimum_visibility_; } | |
207 void set_minimum_visibility(bool minimum_visibility) { | |
208 minimum_visibility_ = minimum_visibility; | |
209 } | |
210 | |
211 // Specifies if the window can be dragged by the user via the caption or not. | |
212 bool can_be_dragged() const { return can_be_dragged_; } | |
213 void set_can_be_dragged(bool can_be_dragged) { | |
214 can_be_dragged_ = can_be_dragged; | |
215 } | |
216 | |
217 // Gets/Sets the bounds of the window before it was moved by the auto window | |
218 // management. As long as it was not auto-managed, it will return NULL. | |
219 const gfx::Rect* pre_auto_manage_window_bounds() const { | |
220 return pre_auto_manage_window_bounds_.get(); | |
221 } | |
222 void SetPreAutoManageWindowBounds(const gfx::Rect& bounds); | |
223 | |
224 // Layout related properties | |
225 | |
226 void AddObserver(WindowStateObserver* observer); | |
227 void RemoveObserver(WindowStateObserver* observer); | |
228 | |
229 // Whether the window is being dragged. | |
230 bool is_dragged() const { return !!drag_details_; } | |
231 | |
232 // Whether or not the window's position can be managed by the | |
233 // auto management logic. | |
234 bool window_position_managed() const { return window_position_managed_; } | |
235 void set_window_position_managed(bool window_position_managed) { | |
236 window_position_managed_ = window_position_managed; | |
237 } | |
238 | |
239 // Whether or not the window's position or size was changed by a user. | |
240 bool bounds_changed_by_user() const { return bounds_changed_by_user_; } | |
241 void set_bounds_changed_by_user(bool bounds_changed_by_user); | |
242 | |
243 // True if this window is an attached panel. | |
244 bool panel_attached() const { return panel_attached_; } | |
245 void set_panel_attached(bool panel_attached) { | |
246 panel_attached_ = panel_attached; | |
247 } | |
248 | |
249 // True if the window is ignored by the shelf layout manager for | |
250 // purposes of darkening the shelf. | |
251 bool ignored_by_shelf() const { return ignored_by_shelf_; } | |
252 void set_ignored_by_shelf(bool ignored_by_shelf) { | |
253 ignored_by_shelf_ = ignored_by_shelf; | |
254 } | |
255 | |
256 // True if the window should be offered a chance to consume special system | |
257 // keys such as brightness, volume, etc. that are usually handled by the | |
258 // shell. | |
259 bool can_consume_system_keys() const { return can_consume_system_keys_; } | |
260 void set_can_consume_system_keys(bool can_consume_system_keys) { | |
261 can_consume_system_keys_ = can_consume_system_keys; | |
262 } | |
263 | |
264 // True if this window has requested that the top-row keys (back, forward, | |
265 // brightness, volume) should be treated as function keys. | |
266 bool top_row_keys_are_function_keys() const { | |
267 return top_row_keys_are_function_keys_; | |
268 } | |
269 void set_top_row_keys_are_function_keys(bool value) { | |
270 top_row_keys_are_function_keys_ = value; | |
271 } | |
272 | |
273 // True if the window is in "immersive full screen mode" which is slightly | |
274 // different from the normal fullscreen mode by allowing the user to reveal | |
275 // the top portion of the window through a touch / mouse gesture. It might | |
276 // also allow the shelf to be shown in some situations. | |
277 bool in_immersive_fullscreen() const { return in_immersive_fullscreen_; } | |
278 void set_in_immersive_fullscreen(bool enable) { | |
279 in_immersive_fullscreen_ = enable; | |
280 } | |
281 | |
282 // Gets/sets the transparent insets of the window for purposes of darkening | |
283 // the shelf appropriately. | |
284 gfx::Insets transparent_insets() const { return transparent_insets_; } | |
285 void set_transparent_insets(const gfx::Insets& insets) { | |
286 transparent_insets_ = insets; | |
287 } | |
288 | |
289 // Creates and takes ownership of a pointer to DragDetails when resizing is | |
290 // active. This should be done before a resizer gets created. | |
291 void CreateDragDetails(const gfx::Point& point_in_parent, | |
292 int window_component, | |
293 aura::client::WindowMoveSource source); | |
294 | |
295 // Deletes and clears a pointer to DragDetails. This should be done when the | |
296 // resizer gets destroyed. | |
297 void DeleteDragDetails(); | |
298 | |
299 // Sets the currently stored restore bounds and clears the restore bounds. | |
300 void SetAndClearRestoreBounds(); | |
301 | |
302 // Returns a pointer to DragDetails during drag operations. | |
303 const DragDetails* drag_details() const { return drag_details_.get(); } | |
304 DragDetails* drag_details() { return drag_details_.get(); } | |
305 | |
306 // Called from the associated WmWindow once the show state changes. | |
307 void OnWindowShowStateChanged(); | |
308 | |
309 protected: | |
310 explicit WindowState(WmWindow* window); | |
311 | |
312 private: | |
313 friend class DefaultState; | |
314 friend class ash::LockWindowState; | |
315 friend class ash::MaximizeModeWindowState; | |
316 FRIEND_TEST_ALL_PREFIXES(WindowAnimationsTest, CrossFadeToBounds); | |
317 FRIEND_TEST_ALL_PREFIXES(WindowAnimationsTest, | |
318 CrossFadeToBoundsFromTransform); | |
319 | |
320 WindowStateDelegate* delegate() { return delegate_.get(); } | |
321 | |
322 // Returns the window's current always_on_top state. | |
323 bool GetAlwaysOnTop() const; | |
324 | |
325 // Returns the window's current show state. | |
326 ui::WindowShowState GetShowState() const; | |
327 | |
328 // Sets the window's bounds in screen coordinates. | |
329 void SetBoundsInScreen(const gfx::Rect& bounds_in_screen); | |
330 | |
331 // Adjusts the |bounds| so that they are flush with the edge of the | |
332 // workspace if the window represented by |window_state| is side snapped. | |
333 void AdjustSnappedBounds(gfx::Rect* bounds); | |
334 | |
335 // Updates the window show state according to the current window state type. | |
336 // Note that this does not update the window bounds. | |
337 void UpdateWindowShowStateFromStateType(); | |
338 | |
339 void NotifyPreStateTypeChange(WindowStateType old_window_state_type); | |
340 void NotifyPostStateTypeChange(WindowStateType old_window_state_type); | |
341 | |
342 // Sets |bounds| as is and ensure the layer is aligned with pixel boundary. | |
343 void SetBoundsDirect(const gfx::Rect& bounds); | |
344 | |
345 // Sets the window's |bounds| with constraint where the size of the | |
346 // new bounds will not exceeds the size of the work area. | |
347 void SetBoundsConstrained(const gfx::Rect& bounds); | |
348 | |
349 // Sets the wndow's |bounds| and transitions to the new bounds with | |
350 // a scale animation. | |
351 void SetBoundsDirectAnimated(const gfx::Rect& bounds); | |
352 | |
353 // Sets the window's |bounds| and transition to the new bounds with | |
354 // a cross fade animation. | |
355 void SetBoundsDirectCrossFade(const gfx::Rect& bounds); | |
356 | |
357 // The owner of this window settings. | |
358 WmWindow* window_; | |
359 std::unique_ptr<WindowStateDelegate> delegate_; | |
360 | |
361 bool window_position_managed_; | |
362 bool bounds_changed_by_user_; | |
363 bool panel_attached_; | |
364 bool ignored_by_shelf_; | |
365 bool can_consume_system_keys_; | |
366 bool top_row_keys_are_function_keys_; | |
367 std::unique_ptr<DragDetails> drag_details_; | |
368 | |
369 bool unminimize_to_restore_bounds_; | |
370 bool in_immersive_fullscreen_; | |
371 bool hide_shelf_when_fullscreen_; | |
372 bool minimum_visibility_; | |
373 bool can_be_dragged_; | |
374 bool cached_always_on_top_; | |
375 | |
376 // A property to remember the window position which was set before the | |
377 // auto window position manager changed the window bounds, so that it can get | |
378 // restored when only this one window gets shown. | |
379 std::unique_ptr<gfx::Rect> pre_auto_manage_window_bounds_; | |
380 | |
381 // A property that can be set on windows with transparent insets, so that | |
382 // layout manager related code can handle these windows more appropriately. | |
383 gfx::Insets transparent_insets_; | |
384 | |
385 base::ObserverList<WindowStateObserver> observer_list_; | |
386 | |
387 // True to ignore a property change event to avoid reentrance in | |
388 // UpdateWindowStateType() | |
389 bool ignore_property_change_; | |
390 | |
391 std::unique_ptr<State> current_state_; | |
392 | |
393 DISALLOW_COPY_AND_ASSIGN(WindowState); | |
394 }; | |
395 | |
396 } // namespace wm | |
397 } // namespace ash | |
398 | |
399 #endif // ASH_WM_COMMON_WINDOW_STATE_H_ | |
OLD | NEW |