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 a normal window in a maximized workspace to maximized.
122 SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE
,
123 SWITCH_TRACKED_BY_WORKSPACE_CHANGED
,
125 // Switch as the result of DoInitialAnimation(). This isn't a real switch,
126 // rather we run the animations as if a switch occurred.
129 // Switch as the result of the user selecting a new active workspace via the
131 SWITCH_WORKSPACE_CYCLER
,
133 // Edge case. See comment in OnWorkspaceWindowShowStateChanged(). Don't
134 // make other types randomly use this!
138 // Updates the visibility and whether any windows overlap the shelf.
139 void UpdateShelfVisibility();
141 // Returns the workspace that contains |window|.
142 Workspace
* FindBy(aura::Window
* window
) const;
144 // Sets the active workspace.
145 void SetActiveWorkspace(Workspace
* workspace
,
147 base::TimeDelta duration
);
149 // Returns the bounds of the work area.
150 gfx::Rect
GetWorkAreaBounds() const;
152 // Returns an iterator into |workspaces_| for |workspace|.
153 Workspaces::iterator
FindWorkspace(Workspace
* workspace
);
155 Workspace
* desktop_workspace() { return workspaces_
[0]; }
156 const Workspace
* desktop_workspace() const { return workspaces_
[0]; }
158 // Creates a new workspace. The Workspace is not added to anything and is
159 // owned by the caller.
160 Workspace
* CreateWorkspace(bool maximized
);
162 // Moves all the non-maximized child windows of |workspace| to the desktop
163 // stacked beneath |stack_beneath| (if non-NULL). After moving child windows
164 // if |workspace| contains no children it is deleted, otherwise it it moved to
165 // |pending_workspaces_|.
166 void MoveWorkspaceToPendingOrDelete(Workspace
* workspace
,
167 aura::Window
* stack_beneath
,
168 SwitchReason reason
);
170 // Moves the children of |window| to the desktop. This excludes certain
171 // windows. If |stack_beneath| is non-NULL the windows are stacked beneath it.
172 void MoveChildrenToDesktop(aura::Window
* window
, aura::Window
* stack_beneath
);
174 // Selects the next workspace.
175 void SelectNextWorkspace(SwitchReason reason
);
177 // Schedules |workspace| for deletion when it no longer contains any layers.
178 // See comments above |to_delete_| as to why we do this.
179 void ScheduleDelete(Workspace
* workspace
);
181 // Deletes any workspaces scheduled via ScheduleDelete() that don't contain
183 void ProcessDeletion();
185 // Sets |unminimizing_workspace_| to |workspace|.
186 void SetUnminimizingWorkspace(Workspace
* workspace
);
188 // Fades the desktop. This is only used when maximizing or restoring a
189 // window. The actual fade is handled by
190 // DesktopBackgroundFadeController. |window| is used when restoring and
191 // indicates the window to stack the DesktopBackgroundFadeController's window
193 void FadeDesktop(aura::Window
* window
, base::TimeDelta duration
);
195 // Shows or hides the desktop Window |window|.
196 void ShowOrHideDesktopBackground(aura::Window
* window
,
198 base::TimeDelta duration
,
201 // Shows/hides |workspace| animating as necessary.
202 void ShowWorkspace(Workspace
* workspace
,
203 Workspace
* last_active
,
204 SwitchReason reason
) const;
205 void HideWorkspace(Workspace
* workspace
,
207 bool is_unminimizing_maximized_window
) const;
209 // These methods are forwarded from the LayoutManager installed on the
210 // Workspace's window.
211 void OnWindowAddedToWorkspace(Workspace
* workspace
, aura::Window
* child
);
212 void OnWillRemoveWindowFromWorkspace(Workspace
* workspace
,
213 aura::Window
* child
);
214 void OnWindowRemovedFromWorkspace(Workspace
* workspace
, aura::Window
* child
);
215 void OnWorkspaceChildWindowVisibilityChanged(Workspace
* workspace
,
216 aura::Window
* child
);
217 void OnWorkspaceWindowChildBoundsChanged(Workspace
* workspace
,
218 aura::Window
* child
);
219 void OnWorkspaceWindowShowStateChanged(Workspace
* workspace
,
221 ui::WindowShowState last_show_state
,
222 ui::Layer
* old_layer
);
223 void OnTrackedByWorkspaceChanged(Workspace
* workspace
,
224 aura::Window
* window
);
226 aura::Window
* contents_window_
;
228 Workspace
* active_workspace_
;
230 // The set of active workspaces. There is always at least one in this stack,
231 // which identifies the desktop.
232 Workspaces workspaces_
;
234 // The set of workspaces not currently active. Workspaces ended up here in
236 // . Prior to adding a window a new workspace is created for it. The
237 // Workspace is added to this set.
238 // . When the maximized window is minimized the workspace is added here.
239 // Once any window in the workspace is activated the workspace is moved to
241 std::set
<Workspace
*> pending_workspaces_
;
243 // Owned by the Shell. May be NULL.
244 ShelfLayoutManager
* shelf_
;
246 // Whether or not we're in MoveWorkspaceToPendingOrDelete(). As
247 // MoveWorkspaceToPendingOrDelete() may trigger another call to
248 // MoveWorkspaceToPendingOrDelete() we use this to avoid doing anything if
249 // already in MoveWorkspaceToPendingOrDelete().
252 // Ideally we would delete workspaces when not needed. Unfortunately doing so
253 // would effectively cancel animations. Instead when a workspace is no longer
254 // needed we add it here and start a timer. When the timer fires any windows
255 // no longer contain layers are deleted.
256 std::set
<Workspace
*> to_delete_
;
257 base::OneShotTimer
<WorkspaceManager
> delete_timer_
;
259 // See comments in SetUnminimizingWorkspace() for details.
260 base::WeakPtrFactory
<WorkspaceManager
> clear_unminimizing_workspace_factory_
;
262 // See comments in SetUnminimizingWorkspace() for details.
263 Workspace
* unminimizing_workspace_
;
265 // Set to true if the app is terminating. If true we don't animate the
266 // background, otherwise it can get stuck in the fading position when chrome
267 // exits (as the last frame we draw before exiting is a frame from the
269 bool app_terminating_
;
271 scoped_ptr
<DesktopBackgroundFadeController
> desktop_fade_controller_
;
273 // Set to true while in the process of creating a
274 // DesktopBackgroundFadeController.
277 // Cycles through the workspace manager's workspaces in response to a three
278 // finger vertical scroll.
279 scoped_ptr
<WorkspaceCycler
> workspace_cycler_
;
281 DISALLOW_COPY_AND_ASSIGN(WorkspaceManager
);
284 } // namespace internal
287 #endif // ASH_WM_WORKSPACE_WORKSPACE_MANAGER_H_