| 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 |