OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/wm/workspace/workspace_manager.h" | 5 #include "ash/wm/workspace/workspace_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "ash/screen_ash.h" | 9 #include "ash/screen_ash.h" |
10 #include "ash/shell.h" | 10 #include "ash/shell.h" |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 | 63 |
64 namespace ash { | 64 namespace ash { |
65 namespace internal { | 65 namespace internal { |
66 | 66 |
67 //////////////////////////////////////////////////////////////////////////////// | 67 //////////////////////////////////////////////////////////////////////////////// |
68 // WindowManager, public: | 68 // WindowManager, public: |
69 | 69 |
70 WorkspaceManager::WorkspaceManager(aura::Window* contents_view) | 70 WorkspaceManager::WorkspaceManager(aura::Window* contents_view) |
71 : contents_view_(contents_view), | 71 : contents_view_(contents_view), |
72 active_workspace_(NULL), | 72 active_workspace_(NULL), |
73 workspace_size_( | |
74 gfx::Screen::GetMonitorAreaNearestWindow(contents_view_).size()), | |
75 is_overview_(false), | 73 is_overview_(false), |
76 ignored_window_(NULL), | 74 ignored_window_(NULL), |
77 grid_size_(0), | 75 grid_size_(0), |
78 shelf_(NULL) { | 76 shelf_(NULL) { |
79 DCHECK(contents_view); | 77 DCHECK(contents_view); |
80 } | 78 } |
81 | 79 |
82 WorkspaceManager::~WorkspaceManager() { | 80 WorkspaceManager::~WorkspaceManager() { |
83 std::vector<Workspace*> copy_to_delete(workspaces_); | 81 std::vector<Workspace*> copy_to_delete(workspaces_); |
84 STLDeleteElements(©_to_delete); | 82 STLDeleteElements(©_to_delete); |
(...skipping 13 matching lines...) Expand all Loading... |
98 | 96 |
99 Workspace* current_workspace = FindBy(window); | 97 Workspace* current_workspace = FindBy(window); |
100 if (current_workspace) { | 98 if (current_workspace) { |
101 // Already know about this window. Make sure the workspace is active. | 99 // Already know about this window. Make sure the workspace is active. |
102 if (active_workspace_ != current_workspace) { | 100 if (active_workspace_ != current_workspace) { |
103 if (active_workspace_) | 101 if (active_workspace_) |
104 window->layer()->GetAnimator()->StopAnimating(); | 102 window->layer()->GetAnimator()->StopAnimating(); |
105 current_workspace->Activate(); | 103 current_workspace->Activate(); |
106 } | 104 } |
107 window->Show(); | 105 window->Show(); |
| 106 UpdateShelfVisibility(); |
108 return; | 107 return; |
109 } | 108 } |
110 | 109 |
111 if (wm::IsWindowNormal(window) && grid_size_ > 1) | 110 if (wm::IsWindowNormal(window) && grid_size_ > 1) |
112 SetWindowBounds(window, AlignBoundsToGrid(window->GetTargetBounds())); | 111 SetWindowBounds(window, AlignBoundsToGrid(window->GetTargetBounds())); |
113 | 112 |
114 Workspace* workspace = NULL; | 113 Workspace* workspace = NULL; |
115 Workspace::Type type_for_window = Workspace::TypeForWindow(window); | 114 Workspace::Type type_for_window = Workspace::TypeForWindow(window); |
116 switch (type_for_window) { | 115 switch (type_for_window) { |
117 case Workspace::TYPE_MANAGED: | 116 case Workspace::TYPE_MANAGED: |
118 // All normal windows go in the same workspace. | 117 // All normal windows go in the same workspace. |
119 workspace = GetManagedWorkspace(); | 118 workspace = GetManagedWorkspace(); |
120 break; | 119 break; |
121 | 120 |
122 case Workspace::TYPE_MAXIMIZED: | 121 case Workspace::TYPE_MAXIMIZED: |
123 // All maximized windows go in their own workspace. | 122 // All maximized windows go in their own workspace. |
124 break; | 123 break; |
125 } | 124 } |
126 | 125 |
127 if (!workspace) | 126 if (!workspace) |
128 workspace = CreateWorkspace(type_for_window); | 127 workspace = CreateWorkspace(type_for_window); |
129 workspace->AddWindowAfter(window, NULL); | 128 workspace->AddWindowAfter(window, NULL); |
130 workspace->Activate(); | 129 workspace->Activate(); |
| 130 UpdateShelfVisibility(); |
131 } | 131 } |
132 | 132 |
133 void WorkspaceManager::RemoveWindow(aura::Window* window) { | 133 void WorkspaceManager::RemoveWindow(aura::Window* window) { |
134 Workspace* workspace = FindBy(window); | 134 Workspace* workspace = FindBy(window); |
135 if (!workspace) | 135 if (!workspace) |
136 return; | 136 return; |
137 workspace->RemoveWindow(window); | 137 workspace->RemoveWindow(window); |
138 CleanupWorkspace(workspace); | 138 CleanupWorkspace(workspace); |
| 139 UpdateShelfVisibility(); |
139 } | 140 } |
140 | 141 |
141 void WorkspaceManager::SetActiveWorkspaceByWindow(aura::Window* window) { | 142 void WorkspaceManager::SetActiveWorkspaceByWindow(aura::Window* window) { |
142 Workspace* workspace = FindBy(window); | 143 Workspace* workspace = FindBy(window); |
143 if (workspace) | 144 if (workspace) |
144 workspace->Activate(); | 145 workspace->Activate(); |
145 } | 146 } |
146 | 147 |
147 gfx::Rect WorkspaceManager::GetDragAreaBounds() { | |
148 return GetWorkAreaBounds(); | |
149 } | |
150 | |
151 void WorkspaceManager::SetOverview(bool overview) { | 148 void WorkspaceManager::SetOverview(bool overview) { |
152 if (is_overview_ == overview) | 149 if (is_overview_ == overview) |
153 return; | 150 return; |
154 NOTIMPLEMENTED(); | 151 NOTIMPLEMENTED(); |
155 } | 152 } |
156 | 153 |
157 void WorkspaceManager::SetWorkspaceSize(const gfx::Size& workspace_size) { | |
158 if (workspace_size == workspace_size_) | |
159 return; | |
160 workspace_size_ = workspace_size; | |
161 SetWorkspaceBounds(); | |
162 } | |
163 | |
164 void WorkspaceManager::OnMonitorWorkAreaInsetsChanged() { | |
165 SetWorkspaceBounds(); | |
166 } | |
167 | |
168 gfx::Rect WorkspaceManager::AlignBoundsToGrid(const gfx::Rect& bounds) { | 154 gfx::Rect WorkspaceManager::AlignBoundsToGrid(const gfx::Rect& bounds) { |
169 if (grid_size_ <= 1) | 155 if (grid_size_ <= 1) |
170 return bounds; | 156 return bounds; |
171 return AlignRectToGrid(bounds, grid_size_); | 157 return AlignRectToGrid(bounds, grid_size_); |
172 } | 158 } |
173 | 159 |
| 160 void WorkspaceManager::UpdateShelfVisibility() { |
| 161 if (!shelf_ || !active_workspace_) { |
| 162 shelf_->SetState(ShelfLayoutManager::VISIBLE, |
| 163 ShelfLayoutManager::AUTO_HIDE_SHOWN); |
| 164 shelf_->SetWindowOverlapsShelf(false); |
| 165 return; |
| 166 } |
| 167 |
| 168 // TODO: this code needs to be made multi-monitor aware. |
| 169 gfx::Rect bounds(gfx::Screen::GetMonitorAreaNearestWindow(contents_view_)); |
| 170 bounds.set_height(bounds.height() - shelf_->shelf_height()); |
| 171 const aura::Window::Windows& windows(contents_view_->children()); |
| 172 bool has_full_screen_window = false; |
| 173 bool has_max_window = false; |
| 174 bool window_overlaps_launcher = false; |
| 175 for (aura::Window::Windows::const_iterator i = windows.begin(); |
| 176 i != windows.end(); ++i) { |
| 177 if (!IsManagingWindow(*i)) |
| 178 continue; |
| 179 ui::Layer* layer = (*i)->layer(); |
| 180 if (!layer->GetTargetVisibility() || layer->GetTargetOpacity() == 0.0f) |
| 181 continue; |
| 182 if (wm::IsWindowMaximized(*i)) { |
| 183 has_max_window = true; |
| 184 break; |
| 185 } |
| 186 if (wm::IsWindowFullscreen(*i)) { |
| 187 has_full_screen_window = true; |
| 188 break; |
| 189 } |
| 190 if (!window_overlaps_launcher && (*i)->bounds().bottom() > bounds.bottom()) |
| 191 window_overlaps_launcher = true; |
| 192 } |
| 193 |
| 194 ShelfLayoutManager::VisibilityState visibility_state = |
| 195 ShelfLayoutManager::VISIBLE; |
| 196 ShelfLayoutManager::AutoHideState auto_hide_state = |
| 197 shelf_->auto_hide_state(); |
| 198 if (has_full_screen_window) { |
| 199 visibility_state = ShelfLayoutManager::HIDDEN; |
| 200 } else if (has_max_window) { |
| 201 visibility_state = ShelfLayoutManager::AUTO_HIDE; |
| 202 } |
| 203 shelf_->SetState(visibility_state, auto_hide_state); |
| 204 shelf_->SetWindowOverlapsShelf(window_overlaps_launcher); |
| 205 } |
| 206 |
174 void WorkspaceManager::ShowStateChanged(aura::Window* window) { | 207 void WorkspaceManager::ShowStateChanged(aura::Window* window) { |
175 if (!IsManagedWindow(window) || !FindBy(window)) | 208 if (!IsManagedWindow(window) || !FindBy(window)) |
176 return; | 209 return; |
177 | 210 |
178 Workspace::Type old_type = FindBy(window)->type(); | 211 Workspace::Type old_type = FindBy(window)->type(); |
179 Workspace::Type new_type = Workspace::TypeForWindow(window); | 212 Workspace::Type new_type = Workspace::TypeForWindow(window); |
180 if (new_type != old_type) | 213 if (new_type != old_type) |
181 OnTypeOfWorkspacedNeededChanged(window); | 214 OnTypeOfWorkspacedNeededChanged(window); |
182 UpdateShelfVisibility(); | 215 UpdateShelfVisibility(); |
183 } | 216 } |
184 | 217 |
185 //////////////////////////////////////////////////////////////////////////////// | 218 //////////////////////////////////////////////////////////////////////////////// |
186 // WorkspaceManager, private: | 219 // WorkspaceManager, private: |
187 | 220 |
188 void WorkspaceManager::AddWorkspace(Workspace* workspace) { | 221 void WorkspaceManager::AddWorkspace(Workspace* workspace) { |
189 DCHECK(std::find(workspaces_.begin(), workspaces_.end(), | 222 DCHECK(std::find(workspaces_.begin(), workspaces_.end(), |
190 workspace) == workspaces_.end()); | 223 workspace) == workspaces_.end()); |
191 workspace->SetBounds(GetWorkAreaBounds()); | |
192 if (active_workspace_) { | 224 if (active_workspace_) { |
193 // New workspaces go right after current workspace. | 225 // New workspaces go right after current workspace. |
194 Workspaces::iterator i = std::find(workspaces_.begin(), workspaces_.end(), | 226 Workspaces::iterator i = std::find(workspaces_.begin(), workspaces_.end(), |
195 active_workspace_); | 227 active_workspace_); |
196 workspaces_.insert(++i, workspace); | 228 workspaces_.insert(++i, workspace); |
197 } else { | 229 } else { |
198 workspaces_.push_back(workspace); | 230 workspaces_.push_back(workspace); |
199 } | 231 } |
200 } | 232 } |
201 | 233 |
202 void WorkspaceManager::RemoveWorkspace(Workspace* workspace) { | 234 void WorkspaceManager::RemoveWorkspace(Workspace* workspace) { |
203 Workspaces::iterator i = std::find(workspaces_.begin(), | 235 Workspaces::iterator i = std::find(workspaces_.begin(), |
204 workspaces_.end(), | 236 workspaces_.end(), |
205 workspace); | 237 workspace); |
206 DCHECK(i != workspaces_.end()); | 238 DCHECK(i != workspaces_.end()); |
207 i = workspaces_.erase(i); | 239 i = workspaces_.erase(i); |
208 if (active_workspace_ == workspace) { | 240 if (active_workspace_ == workspace) { |
209 // TODO: need mru order. | 241 // TODO: need mru order. |
210 if (i != workspaces_.end()) | 242 if (i != workspaces_.end()) |
211 SetActiveWorkspace(*i); | 243 SetActiveWorkspace(*i); |
212 else if (!workspaces_.empty()) | 244 else if (!workspaces_.empty()) |
213 SetActiveWorkspace(workspaces_.back()); | 245 SetActiveWorkspace(workspaces_.back()); |
214 else | 246 else |
215 active_workspace_ = NULL; | 247 active_workspace_ = NULL; |
216 } | 248 } |
217 } | 249 } |
218 | 250 |
219 void WorkspaceManager::UpdateShelfVisibility() { | |
220 if (!shelf_ || !active_workspace_) | |
221 return; | |
222 std::set<aura::Window*> windows; | |
223 windows.insert(active_workspace_->windows().begin(), | |
224 active_workspace_->windows().end()); | |
225 shelf_->SetVisible(!wm::HasFullscreenWindow(windows)); | |
226 } | |
227 | |
228 void WorkspaceManager::SetVisibilityOfWorkspaceWindows( | 251 void WorkspaceManager::SetVisibilityOfWorkspaceWindows( |
229 ash::internal::Workspace* workspace, | 252 ash::internal::Workspace* workspace, |
230 AnimateChangeType change_type, | 253 AnimateChangeType change_type, |
231 bool value) { | 254 bool value) { |
232 std::vector<aura::Window*> children; | 255 std::vector<aura::Window*> children; |
233 BuildWindowList(workspace->windows(), &children); | 256 BuildWindowList(workspace->windows(), &children); |
234 SetWindowLayerVisibility(children, change_type, value); | 257 SetWindowLayerVisibility(children, change_type, value); |
235 } | 258 } |
236 | 259 |
237 void WorkspaceManager::SetWindowLayerVisibility( | 260 void WorkspaceManager::SetWindowLayerVisibility( |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 active_workspace_ = workspace; | 307 active_workspace_ = workspace; |
285 if (active_workspace_) { | 308 if (active_workspace_) { |
286 SetVisibilityOfWorkspaceWindows(active_workspace_, | 309 SetVisibilityOfWorkspaceWindows(active_workspace_, |
287 last_active ? ANIMATE : DONT_ANIMATE, true); | 310 last_active ? ANIMATE : DONT_ANIMATE, true); |
288 UpdateShelfVisibility(); | 311 UpdateShelfVisibility(); |
289 } | 312 } |
290 | 313 |
291 is_overview_ = false; | 314 is_overview_ = false; |
292 } | 315 } |
293 | 316 |
294 gfx::Rect WorkspaceManager::GetWorkAreaBounds() const { | |
295 gfx::Rect bounds(workspace_size_); | |
296 const aura::MonitorManager* monitor_manager = | |
297 aura::Env::GetInstance()->monitor_manager(); | |
298 const aura::Monitor* monitor = | |
299 monitor_manager->GetMonitorNearestWindow(contents_view_); | |
300 bounds.Inset(monitor->work_area_insets()); | |
301 return bounds; | |
302 } | |
303 | |
304 // Returns the index of the workspace that contains the |window|. | 317 // Returns the index of the workspace that contains the |window|. |
305 int WorkspaceManager::GetWorkspaceIndexContaining(aura::Window* window) const { | 318 int WorkspaceManager::GetWorkspaceIndexContaining(aura::Window* window) const { |
306 for (Workspaces::const_iterator i = workspaces_.begin(); | 319 for (Workspaces::const_iterator i = workspaces_.begin(); |
307 i != workspaces_.end(); | 320 i != workspaces_.end(); |
308 ++i) { | 321 ++i) { |
309 if ((*i)->Contains(window)) | 322 if ((*i)->Contains(window)) |
310 return i - workspaces_.begin(); | 323 return i - workspaces_.begin(); |
311 } | 324 } |
312 return -1; | 325 return -1; |
313 } | 326 } |
314 | 327 |
315 void WorkspaceManager::SetWindowBounds(aura::Window* window, | 328 void WorkspaceManager::SetWindowBounds(aura::Window* window, |
316 const gfx::Rect& bounds) { | 329 const gfx::Rect& bounds) { |
317 ignored_window_ = window; | 330 ignored_window_ = window; |
318 window->SetBounds(bounds); | 331 window->SetBounds(bounds); |
319 ignored_window_ = NULL; | 332 ignored_window_ = NULL; |
320 } | 333 } |
321 | 334 |
322 void WorkspaceManager::SetWorkspaceBounds() { | |
323 for (Workspaces::const_iterator i = workspaces_.begin(); | |
324 i != workspaces_.end(); ++i) { | |
325 (*i)->SetBounds(GetWorkAreaBounds()); | |
326 } | |
327 } | |
328 | |
329 void WorkspaceManager::OnTypeOfWorkspacedNeededChanged(aura::Window* window) { | 335 void WorkspaceManager::OnTypeOfWorkspacedNeededChanged(aura::Window* window) { |
330 DCHECK(IsManagedWindow(window)); | 336 DCHECK(IsManagedWindow(window)); |
331 Workspace* current_workspace = FindBy(window); | 337 Workspace* current_workspace = FindBy(window); |
332 DCHECK(current_workspace); | 338 DCHECK(current_workspace); |
333 Workspace* new_workspace = NULL; | 339 Workspace* new_workspace = NULL; |
334 if (Workspace::TypeForWindow(window) == Workspace::TYPE_MAXIMIZED) { | 340 if (Workspace::TypeForWindow(window) == Workspace::TYPE_MAXIMIZED) { |
335 // Unmaximized -> maximized; create a new workspace. | 341 // Unmaximized -> maximized; create a new workspace. |
336 current_workspace->RemoveWindow(window); | 342 current_workspace->RemoveWindow(window); |
337 new_workspace = CreateWorkspace(Workspace::TYPE_MAXIMIZED); | 343 new_workspace = CreateWorkspace(Workspace::TYPE_MAXIMIZED); |
338 new_workspace->AddWindowAfter(window, NULL); | 344 new_workspace->AddWindowAfter(window, NULL); |
(...skipping 30 matching lines...) Expand all Loading... |
369 return workspace; | 375 return workspace; |
370 } | 376 } |
371 | 377 |
372 void WorkspaceManager::CleanupWorkspace(Workspace* workspace) { | 378 void WorkspaceManager::CleanupWorkspace(Workspace* workspace) { |
373 if (workspace->type() != Workspace::TYPE_MANAGED && workspace->is_empty()) | 379 if (workspace->type() != Workspace::TYPE_MANAGED && workspace->is_empty()) |
374 delete workspace; | 380 delete workspace; |
375 } | 381 } |
376 | 382 |
377 } // namespace internal | 383 } // namespace internal |
378 } // namespace ash | 384 } // namespace ash |
OLD | NEW |