1 // Copyright (c) 2012 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_WORKSPACE_WORKSPACE_MANAGER_H_
6 #define ASH_WM_WORKSPACE_WORKSPACE_MANAGER_H_
12 #include "ash/ash_export.h"
13 #include "ash/shell_observer.h"
14 #include "ash/wm/workspace/workspace_types.h"
15 #include "base/basictypes.h"
16 #include "base/compiler_specific.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/time.h"
19 #include "base/timer.h"
20 #include "ui/base/ui_base_types.h"
42 class DesktopBackgroundFadeController
;
43 class ShelfLayoutManager
;
44 class WorkspaceCycler
;
45 class WorkspaceCyclerAnimator
;
46 class WorkspaceLayoutManager
;
47 class WorkspaceManagerTest2
;
50 // WorkspaceManager manages multiple workspaces in the desktop. Workspaces are
51 // implicitly created as windows are maximized (or made fullscreen), and
52 // destroyed when maximized windows are closed or restored. There is always one
53 // workspace for the desktop.
54 // Internally WorkspaceManager creates a Window for each Workspace. As windows
55 // are maximized and restored they are reparented to the right Window.
56 class ASH_EXPORT WorkspaceManager
: public ash::ShellObserver
{
58 explicit WorkspaceManager(aura::Window
* viewport
);
59 virtual ~WorkspaceManager();
61 // Returns true if |window| is considered maximized and should exist in its
63 static bool IsMaximized(aura::Window
* window
);
64 static bool IsMaximizedState(ui::WindowShowState state
);
66 // Returns true if |window| is minimized and will restore to a maximized
68 static bool WillRestoreMaximized(aura::Window
* window
);
70 // Returns the current window state.
71 WorkspaceWindowState
GetWindowState() const;
73 void SetShelf(ShelfLayoutManager
* shelf
);
75 // Activates the workspace containing |window|. Does nothing if |window| is
76 // NULL or not contained in a workspace.
77 void SetActiveWorkspaceByWindow(aura::Window
* window
);
79 // Returns the container window for the active workspace, never NULL.
80 aura::Window
* GetActiveWorkspaceWindow();
82 // Returns the parent for |window|. This is invoked from StackingController
83 // when a new Window is being added.
84 aura::Window
* GetParentForNewWindow(aura::Window
* window
);
86 // Returns true if the user can start cycling through workspaces.
87 bool CanStartCyclingThroughWorkspaces() const;
89 // Initializes |animator| with the workspace manager's current state on
90 // behalf of the workspace cycler.
91 // This state should be cleared by the workspace cycler when
92 // WorkspaceCycler::AbortCycling() is called.
93 void InitWorkspaceCyclerAnimatorWithCurrentState(
94 WorkspaceCyclerAnimator
* animator
);
96 // Called by the workspace cycler to update the active workspace.
97 void SetActiveWorkspaceFromCycler(Workspace
* workspace
);
99 // Starts the animation that occurs on first login.
100 void DoInitialAnimation();
102 // ShellObserver overrides:
103 virtual void OnAppTerminating() OVERRIDE
;
106 friend class WorkspaceLayoutManager
;
107 friend class WorkspaceManagerTest
;
109 class LayoutManagerImpl
;
111 typedef std::vector
<Workspace
*> Workspaces
;
113 // Reason for the workspace switch. Used to determine the characterstics of
116 SWITCH_WINDOW_MADE_ACTIVE
,
117 SWITCH_WINDOW_REMOVED
,
118 SWITCH_VISIBILITY_CHANGED
,
120 SWITCH_MAXIMIZED_OR_RESTORED
,
121 SWITCH_TRACKED_BY_WORKSPACE_CHANGED
,
123 // Switch as the result of DoInitialAnimation(). This isn't a real switch,
124 // rather we run the animations as if a switch occurred.
127 // Switch as the result of the user selecting a new active workspace via the
129 SWITCH_WORKSPACE_CYCLER
,
131 // Edge case. See comment in OnWorkspaceWindowShowStateChanged(). Don't
132 // make other types randomly use this!
136 // Updates the visibility and whether any windows overlap the shelf.
137 void UpdateShelfVisibility();
139 // Returns the workspace that contains |window|.
140 Workspace
* FindBy(aura::Window
* window
) const;
142 // Sets the active workspace.
143 void SetActiveWorkspace(Workspace
* workspace
,
145 base::TimeDelta duration
);
147 // Returns the bounds of the work area.
148 gfx::Rect
GetWorkAreaBounds() const;
150 // Returns an iterator into |workspaces_| for |workspace|.
151 Workspaces::iterator
FindWorkspace(Workspace
* workspace
);
153 Workspace
* desktop_workspace() { return workspaces_
[0]; }
154 const Workspace
* desktop_workspace() const { return workspaces_
[0]; }
156 // Creates a new workspace. The Workspace is not added to anything and is
157 // owned by the caller.
158 Workspace
* CreateWorkspace(bool maximized
);
160 // Moves all the non-maximized child windows of |workspace| to the desktop
161 // stacked beneath |stack_beneath| (if non-NULL). After moving child windows
162 // if |workspace| contains no children it is deleted, otherwise it it moved to
163 // |pending_workspaces_|.
164 void MoveWorkspaceToPendingOrDelete(Workspace
* workspace
,
165 aura::Window
* stack_beneath
,
166 SwitchReason reason
);
168 // Moves the children of |window| to the desktop. This excludes certain
169 // windows. If |stack_beneath| is non-NULL the windows are stacked beneath it.
170 void MoveChildrenToDesktop(aura::Window
* window
, aura::Window
* stack_beneath
);
172 // Selects the next workspace.
173 void SelectNextWorkspace(SwitchReason reason
);
175 // Schedules |workspace| for deletion when it no longer contains any layers.
176 // See comments above |to_delete_| as to why we do this.
177 void ScheduleDelete(Workspace
* workspace
);
179 // Deletes any workspaces scheduled via ScheduleDelete() that don't contain
181 void ProcessDeletion();
183 // Sets |unminimizing_workspace_| to |workspace|.
184 void SetUnminimizingWorkspace(Workspace
* workspace
);
186 // Fades the desktop. This is only used when maximizing or restoring a
187 // window. The actual fade is handled by
188 // DesktopBackgroundFadeController. |window| is used when restoring and
189 // indicates the window to stack the DesktopBackgroundFadeController's window
191 void FadeDesktop(aura::Window
* window
, base::TimeDelta duration
);
193 // Shows or hides the desktop Window |window|.
194 void ShowOrHideDesktopBackground(aura::Window
* window
,
196 base::TimeDelta duration
,
199 // Shows/hides |workspace| animating as necessary.
200 void ShowWorkspace(Workspace
* workspace
,
201 Workspace
* last_active
,
202 SwitchReason reason
) const;
203 void HideWorkspace(Workspace
* workspace
,
205 bool is_unminimizing_maximized_window
) const;
207 // These methods are forwarded from the LayoutManager installed on the
208 // Workspace's window.
209 void OnWindowAddedToWorkspace(Workspace
* workspace
, aura::Window
* child
);
210 void OnWillRemoveWindowFromWorkspace(Workspace
* workspace
,
211 aura::Window
* child
);
212 void OnWindowRemovedFromWorkspace(Workspace
* workspace
, aura::Window
* child
);
213 void OnWorkspaceChildWindowVisibilityChanged(Workspace
* workspace
,
214 aura::Window
* child
);
215 void OnWorkspaceWindowChildBoundsChanged(Workspace
* workspace
,
216 aura::Window
* child
);
217 void OnWorkspaceWindowShowStateChanged(Workspace
* workspace
,
219 ui::WindowShowState last_show_state
,
220 ui::Layer
* old_layer
);
221 void OnTrackedByWorkspaceChanged(Workspace
* workspace
,
222 aura::Window
* window
);
224 aura::Window
* contents_view_
;
226 Workspace
* active_workspace_
;
228 // The set of active workspaces. There is always at least one in this stack,
229 // which identifies the desktop.
230 Workspaces workspaces_
;
232 // The set of workspaces not currently active. Workspaces ended up here in
234 // . Prior to adding a window a new worskpace is created for it. The
235 // Workspace is added to this set.
236 // . When the maximized window is minimized the workspace is added here.
237 // Once any window in the workspace is activated the workspace is moved to
239 std::set
<Workspace
*> pending_workspaces_
;
241 // Owned by the Shell. May be NULL.
242 ShelfLayoutManager
* shelf_
;
244 // Whether or not we're in MoveWorkspaceToPendingOrDelete(). As
245 // MoveWorkspaceToPendingOrDelete() may trigger another call to
246 // MoveWorkspaceToPendingOrDelete() we use this to avoid doing anything if
247 // already in MoveWorkspaceToPendingOrDelete().
250 // Ideally we would delete workspaces when not needed. Unfortunately doing so
251 // would effectively cancel animations. Instead when a workspace is no longer
252 // needed we add it here and start a timer. When the timer fires any windows
253 // no longer contain layers are deleted.
254 std::set
<Workspace
*> to_delete_
;
255 base::OneShotTimer
<WorkspaceManager
> delete_timer_
;
257 // See comments in SetUnminimizingWorkspace() for details.
258 base::WeakPtrFactory
<WorkspaceManager
> clear_unminimizing_workspace_factory_
;
260 // See comments in SetUnminimizingWorkspace() for details.
261 Workspace
* unminimizing_workspace_
;
263 // Set to true if the app is terminating. If true we don't animate the
264 // background, otherwise it can get stuck in the fading position when chrome
265 // exits (as the last frame we draw before exiting is a frame from the
267 bool app_terminating_
;
269 scoped_ptr
<DesktopBackgroundFadeController
> desktop_fade_controller_
;
271 // Set to true while in the process of creating a
272 // DesktopBackgroundFadeController.
275 // Cycles through the workspace manager's workspaces in response to a three
276 // finger vertical scroll.
277 scoped_ptr
<WorkspaceCycler
> workspace_cycler_
;
279 DISALLOW_COPY_AND_ASSIGN(WorkspaceManager
);
282 } // namespace internal
285 #endif // ASH_WM_WORKSPACE_WORKSPACE_MANAGER_H_