| 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 #include <functional> | 8 #include <functional> |
| 9 | 9 |
| 10 #include "ash/root_window_controller.h" | 10 #include "ash/root_window_controller.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 | 44 |
| 45 using aura::Window; | 45 using aura::Window; |
| 46 | 46 |
| 47 namespace ash { | 47 namespace ash { |
| 48 namespace internal { | 48 namespace internal { |
| 49 | 49 |
| 50 DEFINE_WINDOW_PROPERTY_KEY(Workspace*, kWorkspaceKey, NULL); | 50 DEFINE_WINDOW_PROPERTY_KEY(Workspace*, kWorkspaceKey, NULL); |
| 51 | 51 |
| 52 namespace { | 52 namespace { |
| 53 | 53 |
| 54 // Duration for fading out the desktop background when maximizing. | 54 // Duration for fading out the desktop background when fullscreen. |
| 55 const int kCrossFadeSwitchTimeMS = 700; | 55 const int kCrossFadeSwitchTimeMS = 700; |
| 56 | 56 |
| 57 // Amount of time to pause before animating anything. Only used during initial | 57 // Amount of time to pause before animating anything. Only used during initial |
| 58 // animation (when logging in). | 58 // animation (when logging in). |
| 59 const int kInitialPauseTimeMS = 750; | 59 const int kInitialPauseTimeMS = 750; |
| 60 | 60 |
| 61 // Changes the parent of |window| and all its transient children to | 61 // Changes the parent of |window| and all its transient children to |
| 62 // |new_parent|. If |stack_beneach| is non-NULL all the windows are stacked | 62 // |new_parent|. If |stack_beneach| is non-NULL all the windows are stacked |
| 63 // beneath it. | 63 // beneath it. |
| 64 void ReparentWindow(Window* window, | 64 void ReparentWindow(Window* window, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 std::for_each(pending_workspaces_.begin(), pending_workspaces_.end(), | 140 std::for_each(pending_workspaces_.begin(), pending_workspaces_.end(), |
| 141 std::mem_fun(&Workspace::ReleaseWindow)); | 141 std::mem_fun(&Workspace::ReleaseWindow)); |
| 142 std::for_each(to_delete_.begin(), to_delete_.end(), | 142 std::for_each(to_delete_.begin(), to_delete_.end(), |
| 143 std::mem_fun(&Workspace::ReleaseWindow)); | 143 std::mem_fun(&Workspace::ReleaseWindow)); |
| 144 STLDeleteElements(&workspaces_); | 144 STLDeleteElements(&workspaces_); |
| 145 STLDeleteElements(&pending_workspaces_); | 145 STLDeleteElements(&pending_workspaces_); |
| 146 STLDeleteElements(&to_delete_); | 146 STLDeleteElements(&to_delete_); |
| 147 } | 147 } |
| 148 | 148 |
| 149 // static | 149 // static |
| 150 bool WorkspaceManager::IsMaximized(Window* window) { | 150 bool WorkspaceManager::WillRestoreToWorkspace(Window* window) { |
| 151 return IsMaximizedState(window->GetProperty(aura::client::kShowStateKey)); | |
| 152 } | |
| 153 | |
| 154 // static | |
| 155 bool WorkspaceManager::IsMaximizedState(ui::WindowShowState state) { | |
| 156 return state == ui::SHOW_STATE_MAXIMIZED || | |
| 157 state == ui::SHOW_STATE_FULLSCREEN; | |
| 158 } | |
| 159 | |
| 160 // static | |
| 161 bool WorkspaceManager::WillRestoreMaximized(Window* window) { | |
| 162 return wm::IsWindowMinimized(window) && | 151 return wm::IsWindowMinimized(window) && |
| 163 IsMaximizedState(window->GetProperty(aura::client::kRestoreShowStateKey)); | 152 window->GetProperty(aura::client::kRestoreShowStateKey) == |
| 153 ui::SHOW_STATE_FULLSCREEN; |
| 164 } | 154 } |
| 165 | 155 |
| 166 WorkspaceWindowState WorkspaceManager::GetWindowState() const { | 156 WorkspaceWindowState WorkspaceManager::GetWindowState() const { |
| 167 if (!shelf_) | 157 if (!shelf_) |
| 168 return WORKSPACE_WINDOW_STATE_DEFAULT; | 158 return WORKSPACE_WINDOW_STATE_DEFAULT; |
| 169 | 159 |
| 170 const bool is_active_maximized = active_workspace_->is_maximized(); | 160 const bool is_active_fullscreen = active_workspace_->is_fullscreen(); |
| 171 const gfx::Rect shelf_bounds(shelf_->GetIdealBounds()); | 161 const gfx::Rect shelf_bounds(shelf_->GetIdealBounds()); |
| 172 const Window::Windows& windows(active_workspace_->window()->children()); | 162 const Window::Windows& windows(active_workspace_->window()->children()); |
| 173 bool window_overlaps_launcher = false; | 163 bool window_overlaps_launcher = false; |
| 174 bool has_maximized_window = false; | 164 bool has_maximized_window = false; |
| 175 for (Window::Windows::const_iterator i = windows.begin(); | 165 for (Window::Windows::const_iterator i = windows.begin(); |
| 176 i != windows.end(); ++i) { | 166 i != windows.end(); ++i) { |
| 177 if (GetIgnoredByShelf(*i)) | 167 if (GetIgnoredByShelf(*i)) |
| 178 continue; | 168 continue; |
| 179 ui::Layer* layer = (*i)->layer(); | 169 ui::Layer* layer = (*i)->layer(); |
| 180 if (!layer->GetTargetVisibility() || layer->GetTargetOpacity() == 0.0f) | 170 if (!layer->GetTargetVisibility() || layer->GetTargetOpacity() == 0.0f) |
| 181 continue; | 171 continue; |
| 182 // Ignore maximized/fullscreen windows if we're in the desktop. Such a state | 172 if (wm::IsWindowMaximized(*i)) { |
| 183 // is transitory and means we haven't yet switched. If we did consider such | 173 // An untracked window may still be fullscreen so we keep iterating when |
| 184 // windows we'll return the wrong thing, which can lead to prematurely | 174 // we hit a maximized window. |
| 185 // changing the launcher state and clobbering restore bounds. | 175 has_maximized_window = true; |
| 186 if (is_active_maximized) { | 176 } else if (is_active_fullscreen && wm::IsWindowFullscreen(*i)) { |
| 187 if (wm::IsWindowMaximized(*i)) { | 177 // Ignore fullscreen windows if we're in the desktop. Such a state |
| 188 // An untracked window may still be fullscreen so we keep iterating when | 178 // is transitory and means we haven't yet switched. If we did consider |
| 189 // we hit a maximized window. | 179 // such windows we'll return the wrong thing, which can lead to |
| 190 has_maximized_window = true; | 180 // prematurely anging the launcher state and clobbering restore bounds. |
| 191 } else if (wm::IsWindowFullscreen(*i)) { | 181 return WORKSPACE_WINDOW_STATE_FULL_SCREEN; |
| 192 return WORKSPACE_WINDOW_STATE_FULL_SCREEN; | |
| 193 } | |
| 194 } | 182 } |
| 195 if (!window_overlaps_launcher && (*i)->bounds().Intersects(shelf_bounds)) | 183 if (!window_overlaps_launcher && (*i)->bounds().Intersects(shelf_bounds)) |
| 196 window_overlaps_launcher = true; | 184 window_overlaps_launcher = true; |
| 197 } | 185 } |
| 198 if (has_maximized_window) | 186 if (has_maximized_window) |
| 199 return WORKSPACE_WINDOW_STATE_MAXIMIZED; | 187 return WORKSPACE_WINDOW_STATE_MAXIMIZED; |
| 200 | 188 |
| 201 return window_overlaps_launcher ? | 189 return window_overlaps_launcher ? |
| 202 WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF : | 190 WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF : |
| 203 WORKSPACE_WINDOW_STATE_DEFAULT; | 191 WORKSPACE_WINDOW_STATE_DEFAULT; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 214 | 202 |
| 215 if (workspace != active_workspace_) { | 203 if (workspace != active_workspace_) { |
| 216 // A window is being made active. In the following cases we reparent to | 204 // A window is being made active. In the following cases we reparent to |
| 217 // the active desktop: | 205 // the active desktop: |
| 218 // . The window is not tracked by workspace code. This is used for tab | 206 // . The window is not tracked by workspace code. This is used for tab |
| 219 // dragging. Since tab dragging needs to happen in the active workspace we | 207 // dragging. Since tab dragging needs to happen in the active workspace we |
| 220 // have to reparent the window (otherwise the window you dragged the tab | 208 // have to reparent the window (otherwise the window you dragged the tab |
| 221 // out of would disappear since the workspace changed). Since this case is | 209 // out of would disappear since the workspace changed). Since this case is |
| 222 // only transiently used (property reset on input release) we don't worry | 210 // only transiently used (property reset on input release) we don't worry |
| 223 // about window state. In fact we can't consider window state here as we | 211 // about window state. In fact we can't consider window state here as we |
| 224 // have to allow dragging of a maximized window to work in this case. | 212 // have to allow dragging of a fullscreen window to work in this case. |
| 225 // . The window persists across all workspaces. For example, the task | 213 // . The window persists across all workspaces. For example, the task |
| 226 // manager is in the desktop worskpace and the current workspace is | 214 // manager is in the desktop worskpace and the current workspace is |
| 227 // maximized. If we swapped to the desktop you would lose context. Instead | 215 // fullscreen. If we swapped to the desktop you would lose context. |
| 228 // we reparent. The exception to this is if the window is maximized (it | 216 // Instead we reparent. The exception to this is if the window is |
| 229 // needs its own workspace then) or we're in the process of maximizing. If | 217 // fullscreen (it needs its own workspace then) or we're in the process of |
| 230 // we're in the process of maximizing the window needs its own workspace. | 218 // fullscreen. If we're in the process of fullscreen the window needs its |
| 219 // own workspace. |
| 231 if (!GetTrackedByWorkspace(window) || | 220 if (!GetTrackedByWorkspace(window) || |
| 232 (GetPersistsAcrossAllWorkspaces(window) && !IsMaximized(window) && | 221 (GetPersistsAcrossAllWorkspaces(window) && |
| 233 !(wm::IsWindowMinimized(window) && WillRestoreMaximized(window)))) { | 222 !wm::IsWindowFullscreen(window) && !WillRestoreToWorkspace(window))) { |
| 234 ReparentWindow(window, active_workspace_->window(), NULL); | 223 ReparentWindow(window, active_workspace_->window(), NULL); |
| 235 } else { | 224 } else { |
| 236 SetActiveWorkspace(workspace, SWITCH_WINDOW_MADE_ACTIVE, | 225 SetActiveWorkspace(workspace, SWITCH_WINDOW_MADE_ACTIVE, |
| 237 base::TimeDelta()); | 226 base::TimeDelta()); |
| 238 } | 227 } |
| 239 } | 228 } |
| 240 if (workspace->is_maximized() && IsMaximized(window)) { | 229 if (workspace->is_fullscreen() && wm::IsWindowFullscreen(window)) { |
| 241 // Clicking on the maximized window in a maximized workspace. Force all | 230 // Clicking on the fullscreen window in a fullscreen workspace. Force all |
| 242 // other windows to drop to the desktop. | 231 // other windows to drop to the desktop. |
| 243 MoveChildrenToDesktop(workspace->window(), NULL); | 232 MoveChildrenToDesktop(workspace->window(), NULL); |
| 244 } | 233 } |
| 245 } | 234 } |
| 246 | 235 |
| 247 Window* WorkspaceManager::GetActiveWorkspaceWindow() { | 236 Window* WorkspaceManager::GetActiveWorkspaceWindow() { |
| 248 return active_workspace_->window(); | 237 return active_workspace_->window(); |
| 249 } | 238 } |
| 250 | 239 |
| 251 Window* WorkspaceManager::GetParentForNewWindow(Window* window) { | 240 Window* WorkspaceManager::GetParentForNewWindow(Window* window) { |
| 252 // Try to put windows with transient parents in the same workspace as their | 241 // Try to put windows with transient parents in the same workspace as their |
| 253 // transient parent. | 242 // transient parent. |
| 254 if (window->transient_parent() && !IsMaximized(window)) { | 243 if (window->transient_parent() && !wm::IsWindowFullscreen(window)) { |
| 255 Workspace* workspace = FindBy(window->transient_parent()); | 244 Workspace* workspace = FindBy(window->transient_parent()); |
| 256 if (workspace) | 245 if (workspace) |
| 257 return workspace->window(); | 246 return workspace->window(); |
| 258 // Fall through to normal logic. | 247 // Fall through to normal logic. |
| 259 } | 248 } |
| 260 | 249 |
| 261 if (!GetTrackedByWorkspace(window)) | 250 if (!GetTrackedByWorkspace(window)) |
| 262 return active_workspace_->window(); | 251 return active_workspace_->window(); |
| 263 | 252 |
| 264 if (IsMaximized(window)) { | 253 if (wm::IsWindowFullscreen(window)) { |
| 265 // Wait for the window to be made active before showing the workspace. | 254 // Wait for the window to be made active before showing the workspace. |
| 266 Workspace* workspace = CreateWorkspace(true); | 255 Workspace* workspace = CreateWorkspace(true); |
| 267 pending_workspaces_.insert(workspace); | 256 pending_workspaces_.insert(workspace); |
| 268 return workspace->window(); | 257 return workspace->window(); |
| 269 } | 258 } |
| 270 | 259 |
| 271 if (!GetTrackedByWorkspace(window) || GetPersistsAcrossAllWorkspaces(window)) | 260 if (!GetTrackedByWorkspace(window) || GetPersistsAcrossAllWorkspaces(window)) |
| 272 return active_workspace_->window(); | 261 return active_workspace_->window(); |
| 273 | 262 |
| 274 return desktop_workspace()->window(); | 263 return desktop_workspace()->window(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 292 | 281 |
| 293 // Activate the topmost window in the newly activated workspace as | 282 // Activate the topmost window in the newly activated workspace as |
| 294 // SetActiveWorkspace() does not do so. | 283 // SetActiveWorkspace() does not do so. |
| 295 aura::Window* topmost_activatable_window = | 284 aura::Window* topmost_activatable_window = |
| 296 workspace->GetTopmostActivatableWindow(); | 285 workspace->GetTopmostActivatableWindow(); |
| 297 if (topmost_activatable_window) | 286 if (topmost_activatable_window) |
| 298 wm::ActivateWindow(topmost_activatable_window); | 287 wm::ActivateWindow(topmost_activatable_window); |
| 299 } | 288 } |
| 300 | 289 |
| 301 void WorkspaceManager::DoInitialAnimation() { | 290 void WorkspaceManager::DoInitialAnimation() { |
| 302 if (active_workspace_->is_maximized()) { | 291 if (active_workspace_->is_fullscreen()) { |
| 303 RootWindowController* root_controller = GetRootWindowController( | 292 RootWindowController* root_controller = GetRootWindowController( |
| 304 contents_window_->GetRootWindow()); | 293 contents_window_->GetRootWindow()); |
| 305 if (root_controller) { | 294 if (root_controller) { |
| 306 aura::Window* background = root_controller->GetContainer( | 295 aura::Window* background = root_controller->GetContainer( |
| 307 kShellWindowId_DesktopBackgroundContainer); | 296 kShellWindowId_DesktopBackgroundContainer); |
| 308 background->Show(); | 297 background->Show(); |
| 309 ShowOrHideDesktopBackground(background, SWITCH_INITIAL, | 298 ShowOrHideDesktopBackground(background, SWITCH_INITIAL, |
| 310 base::TimeDelta(), false); | 299 base::TimeDelta(), false); |
| 311 } | 300 } |
| 312 } | 301 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 } | 345 } |
| 357 | 346 |
| 358 Workspace* last_active = active_workspace_; | 347 Workspace* last_active = active_workspace_; |
| 359 active_workspace_ = workspace; | 348 active_workspace_ = workspace; |
| 360 | 349 |
| 361 // The display work-area may have changed while |workspace| was not the active | 350 // The display work-area may have changed while |workspace| was not the active |
| 362 // workspace. Give it a chance to adjust its state for the new work-area. | 351 // workspace. Give it a chance to adjust its state for the new work-area. |
| 363 active_workspace_->workspace_layout_manager()-> | 352 active_workspace_->workspace_layout_manager()-> |
| 364 OnDisplayWorkAreaInsetsChanged(); | 353 OnDisplayWorkAreaInsetsChanged(); |
| 365 | 354 |
| 366 const bool is_unminimizing_maximized_window = | 355 const bool is_unminimizing_fullscreen_window = |
| 367 unminimizing_workspace_ && unminimizing_workspace_ == active_workspace_ && | 356 unminimizing_workspace_ && unminimizing_workspace_ == active_workspace_ && |
| 368 active_workspace_->is_maximized(); | 357 active_workspace_->is_fullscreen(); |
| 369 if (is_unminimizing_maximized_window) { | 358 if (is_unminimizing_fullscreen_window) { |
| 370 // If we're unminimizing a window it needs to be on the top, otherwise you | 359 // If we're unminimizing a window it needs to be on the top, otherwise you |
| 371 // won't see the animation. | 360 // won't see the animation. |
| 372 contents_window_->StackChildAtTop(active_workspace_->window()); | 361 contents_window_->StackChildAtTop(active_workspace_->window()); |
| 373 } else if (active_workspace_->is_maximized() && | 362 } else if (active_workspace_->is_fullscreen() && |
| 374 last_active->is_maximized() && | 363 last_active->is_fullscreen() && |
| 375 reason != SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE) { | 364 reason != SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE) { |
| 376 // When switching between maximized windows we need the last active | 365 // When switching between fullscreen windows we need the last active |
| 377 // workspace on top of the new, otherwise the animations won't look | 366 // workspace on top of the new, otherwise the animations won't look |
| 378 // right. Since only one workspace is visible at a time stacking order of | 367 // right. Since only one workspace is visible at a time stacking order of |
| 379 // the workspace windows ultimately doesn't matter. | 368 // the workspace windows ultimately doesn't matter. |
| 380 contents_window_->StackChildAtTop(last_active->window()); | 369 contents_window_->StackChildAtTop(last_active->window()); |
| 381 } | 370 } |
| 382 | 371 |
| 383 UpdateShelfVisibility(); | 372 UpdateShelfVisibility(); |
| 384 | 373 |
| 385 // NOTE: duration supplied to this method is only used for desktop background. | 374 // NOTE: duration supplied to this method is only used for desktop background. |
| 386 HideWorkspace(last_active, reason, is_unminimizing_maximized_window); | 375 HideWorkspace(last_active, reason, is_unminimizing_fullscreen_window); |
| 387 ShowWorkspace(workspace, last_active, reason); | 376 ShowWorkspace(workspace, last_active, reason); |
| 388 | 377 |
| 389 RootWindowController* root_controller = GetRootWindowController( | 378 RootWindowController* root_controller = GetRootWindowController( |
| 390 contents_window_->GetRootWindow()); | 379 contents_window_->GetRootWindow()); |
| 391 if (root_controller) { | 380 if (root_controller) { |
| 392 aura::Window* background = root_controller->GetContainer( | 381 aura::Window* background = root_controller->GetContainer( |
| 393 kShellWindowId_DesktopBackgroundContainer); | 382 kShellWindowId_DesktopBackgroundContainer); |
| 394 if (last_active == desktop_workspace()) { | 383 if (last_active == desktop_workspace()) { |
| 395 ShowOrHideDesktopBackground(background, reason, duration, false); | 384 ShowOrHideDesktopBackground(background, reason, duration, false); |
| 396 } else if (active_workspace_ == desktop_workspace() && !app_terminating_) { | 385 } else if (active_workspace_ == desktop_workspace() && !app_terminating_) { |
| 397 ShowOrHideDesktopBackground(background, reason, duration, true); | 386 ShowOrHideDesktopBackground(background, reason, duration, true); |
| 398 } | 387 } |
| 399 } | 388 } |
| 400 | 389 |
| 401 // Showing or hiding a workspace may change the "solo window" status of | 390 // Showing or hiding a workspace may change the "solo window" status of |
| 402 // a window, requiring the header to be updated. | 391 // a window, requiring the header to be updated. |
| 403 FramePainter::UpdateSoloWindowHeader(contents_window_->GetRootWindow()); | 392 FramePainter::UpdateSoloWindowHeader(contents_window_->GetRootWindow()); |
| 404 } | 393 } |
| 405 | 394 |
| 406 WorkspaceManager::Workspaces::iterator | 395 WorkspaceManager::Workspaces::iterator |
| 407 WorkspaceManager::FindWorkspace(Workspace* workspace) { | 396 WorkspaceManager::FindWorkspace(Workspace* workspace) { |
| 408 return std::find(workspaces_.begin(), workspaces_.end(), workspace); | 397 return std::find(workspaces_.begin(), workspaces_.end(), workspace); |
| 409 } | 398 } |
| 410 | 399 |
| 411 Workspace* WorkspaceManager::CreateWorkspace(bool maximized) { | 400 Workspace* WorkspaceManager::CreateWorkspace(bool fullscreen) { |
| 412 return new Workspace(this, contents_window_, maximized); | 401 return new Workspace(this, contents_window_, fullscreen); |
| 413 } | 402 } |
| 414 | 403 |
| 415 void WorkspaceManager::MoveWorkspaceToPendingOrDelete( | 404 void WorkspaceManager::MoveWorkspaceToPendingOrDelete( |
| 416 Workspace* workspace, | 405 Workspace* workspace, |
| 417 Window* stack_beneath, | 406 Window* stack_beneath, |
| 418 SwitchReason reason) { | 407 SwitchReason reason) { |
| 419 // We're all ready moving windows. | 408 // We're all ready moving windows. |
| 420 if (in_move_) | 409 if (in_move_) |
| 421 return; | 410 return; |
| 422 | 411 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 445 unminimizing_workspace_ = NULL; | 434 unminimizing_workspace_ = NULL; |
| 446 pending_workspaces_.erase(workspace); | 435 pending_workspaces_.erase(workspace); |
| 447 ScheduleDelete(workspace); | 436 ScheduleDelete(workspace); |
| 448 } else { | 437 } else { |
| 449 pending_workspaces_.insert(workspace); | 438 pending_workspaces_.insert(workspace); |
| 450 } | 439 } |
| 451 } | 440 } |
| 452 | 441 |
| 453 void WorkspaceManager::MoveChildrenToDesktop(aura::Window* window, | 442 void WorkspaceManager::MoveChildrenToDesktop(aura::Window* window, |
| 454 aura::Window* stack_beneath) { | 443 aura::Window* stack_beneath) { |
| 455 // Build the list of windows to move. Exclude maximized/fullscreen and windows | 444 // Build the list of windows to move. Exclude fullscreen and windows with |
| 456 // with transient parents. | 445 // transient parents. |
| 457 Window::Windows to_move; | 446 Window::Windows to_move; |
| 458 for (size_t i = 0; i < window->children().size(); ++i) { | 447 for (size_t i = 0; i < window->children().size(); ++i) { |
| 459 Window* child = window->children()[i]; | 448 Window* child = window->children()[i]; |
| 460 if (!child->transient_parent() && !IsMaximized(child) && | 449 if (!child->transient_parent() && !wm::IsWindowFullscreen(child) && |
| 461 !WillRestoreMaximized(child)) { | 450 !WillRestoreToWorkspace(child)) { |
| 462 to_move.push_back(child); | 451 to_move.push_back(child); |
| 463 } | 452 } |
| 464 } | 453 } |
| 465 // Move the windows, but make sure the window is still a child of |window| | 454 // Move the windows, but make sure the window is still a child of |window| |
| 466 // (moving may cascade and cause other windows to move). | 455 // (moving may cascade and cause other windows to move). |
| 467 for (size_t i = 0; i < to_move.size(); ++i) { | 456 for (size_t i = 0; i < to_move.size(); ++i) { |
| 468 if (std::find(window->children().begin(), window->children().end(), | 457 if (std::find(window->children().begin(), window->children().end(), |
| 469 to_move[i]) != window->children().end()) { | 458 to_move[i]) != window->children().end()) { |
| 470 ReparentWindow(to_move[i], desktop_workspace()->window(), | 459 ReparentWindow(to_move[i], desktop_workspace()->window(), |
| 471 stack_beneath); | 460 stack_beneath); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 // Remaining cases require no animation. | 591 // Remaining cases require no animation. |
| 603 default: | 592 default: |
| 604 break; | 593 break; |
| 605 } | 594 } |
| 606 ash::internal::ShowWorkspace(workspace->window(), details); | 595 ash::internal::ShowWorkspace(workspace->window(), details); |
| 607 } | 596 } |
| 608 | 597 |
| 609 void WorkspaceManager::HideWorkspace( | 598 void WorkspaceManager::HideWorkspace( |
| 610 Workspace* workspace, | 599 Workspace* workspace, |
| 611 SwitchReason reason, | 600 SwitchReason reason, |
| 612 bool is_unminimizing_maximized_window) const { | 601 bool is_unminimizing_fullscreen_window) const { |
| 613 WorkspaceAnimationDetails details; | 602 WorkspaceAnimationDetails details; |
| 614 details.direction = active_workspace_ == desktop_workspace() ? | 603 details.direction = active_workspace_ == desktop_workspace() ? |
| 615 WORKSPACE_ANIMATE_UP : WORKSPACE_ANIMATE_DOWN; | 604 WORKSPACE_ANIMATE_UP : WORKSPACE_ANIMATE_DOWN; |
| 616 switch (reason) { | 605 switch (reason) { |
| 617 case SWITCH_WINDOW_MADE_ACTIVE: | 606 case SWITCH_WINDOW_MADE_ACTIVE: |
| 618 case SWITCH_TRACKED_BY_WORKSPACE_CHANGED: | 607 case SWITCH_TRACKED_BY_WORKSPACE_CHANGED: |
| 619 details.animate_opacity = | 608 details.animate_opacity = |
| 620 ((active_workspace_ == desktop_workspace() || | 609 ((active_workspace_ == desktop_workspace() || |
| 621 workspace != desktop_workspace()) && | 610 workspace != desktop_workspace()) && |
| 622 !is_unminimizing_maximized_window); | 611 !is_unminimizing_fullscreen_window); |
| 623 details.animate_scale = true; | 612 details.animate_scale = true; |
| 624 details.animate = true; | 613 details.animate = true; |
| 625 break; | 614 break; |
| 626 | 615 |
| 627 case SWITCH_VISIBILITY_CHANGED: | 616 case SWITCH_VISIBILITY_CHANGED: |
| 628 // The window is most likely closing. Make the workspace visible for the | 617 // The window is most likely closing. Make the workspace visible for the |
| 629 // duration of the switch so that the close animation is visible. | 618 // duration of the switch so that the close animation is visible. |
| 630 details.animate = true; | 619 details.animate = true; |
| 631 details.animate_scale = true; | 620 details.animate_scale = true; |
| 632 break; | 621 break; |
| 633 | 622 |
| 634 case SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE: | 623 case SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE: |
| 635 case SWITCH_MAXIMIZED_OR_RESTORED: | 624 case SWITCH_MAXIMIZED_OR_RESTORED: |
| 636 if (active_workspace_->is_maximized()) { | 625 if (active_workspace_->is_fullscreen()) { |
| 637 // Delay the hide until the animation is done. | 626 // Delay the hide until the animation is done. |
| 638 details.duration = | 627 details.duration = |
| 639 base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS); | 628 base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS); |
| 640 details.animate = true; | 629 details.animate = true; |
| 641 } | 630 } |
| 642 break; | 631 break; |
| 643 | 632 |
| 644 // Remaining cases require no animation. | 633 // Remaining cases require no animation. |
| 645 default: | 634 default: |
| 646 break; | 635 break; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 UpdateShelfVisibility(); | 708 UpdateShelfVisibility(); |
| 720 } | 709 } |
| 721 | 710 |
| 722 void WorkspaceManager::OnWorkspaceWindowShowStateChanged( | 711 void WorkspaceManager::OnWorkspaceWindowShowStateChanged( |
| 723 Workspace* workspace, | 712 Workspace* workspace, |
| 724 Window* child, | 713 Window* child, |
| 725 ui::WindowShowState last_show_state, | 714 ui::WindowShowState last_show_state, |
| 726 ui::Layer* old_layer) { | 715 ui::Layer* old_layer) { |
| 727 // |child| better still be in |workspace| else things have gone wrong. | 716 // |child| better still be in |workspace| else things have gone wrong. |
| 728 DCHECK_EQ(workspace, child->GetProperty(kWorkspaceKey)); | 717 DCHECK_EQ(workspace, child->GetProperty(kWorkspaceKey)); |
| 718 |
| 719 // Show/hide state of the background has to be set here since maximized window |
| 720 // doesn't create its own workspace anymore. |
| 721 RootWindowController* root_controller = GetRootWindowController( |
| 722 contents_window_->GetRootWindow()); |
| 723 aura::Window* background = root_controller->GetContainer( |
| 724 kShellWindowId_DesktopBackgroundContainer);; |
| 725 if (wm::IsWindowMaximized(child)) { |
| 726 ShowOrHideDesktopBackground( |
| 727 background, |
| 728 SWITCH_MAXIMIZED_OR_RESTORED, |
| 729 base::TimeDelta(), |
| 730 false); |
| 731 } else if (last_show_state == ui::SHOW_STATE_MAXIMIZED) { |
| 732 ShowOrHideDesktopBackground( |
| 733 background, |
| 734 SWITCH_MINIMIZED, |
| 735 base::TimeDelta(), |
| 736 true); |
| 737 } |
| 738 |
| 729 if (wm::IsWindowMinimized(child)) { | 739 if (wm::IsWindowMinimized(child)) { |
| 730 if (workspace->ShouldMoveToPending()) | 740 if (workspace->ShouldMoveToPending()) |
| 731 MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_MINIMIZED); | 741 MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_MINIMIZED); |
| 732 DCHECK(!old_layer); | 742 DCHECK(!old_layer); |
| 733 } else { | 743 } else { |
| 734 // Set of cases to deal with: | 744 // Set of cases to deal with: |
| 735 // . More than one maximized window: move newly maximized window into | 745 // . More than one fullscreen window: move newly fullscreen window into |
| 736 // own workspace. | 746 // own workspace. |
| 737 // . One maximized window and not in a maximized workspace: move window | 747 // . One fullscreen window and not in a fullscreen workspace: move window |
| 738 // into own workspace. | 748 // into own workspace. |
| 739 // . No maximized window and not in desktop: move to desktop and further | 749 // . No fullscreen window and not in desktop: move to desktop and further |
| 740 // any existing windows are stacked beneath |child|. | 750 // any existing windows are stacked beneath |child|. |
| 741 const bool is_active = wm::IsActiveWindow(child); | 751 const bool is_active = wm::IsActiveWindow(child); |
| 742 Workspace* new_workspace = NULL; | 752 Workspace* new_workspace = NULL; |
| 743 const int max_count = workspace->GetNumMaximizedWindows(); | 753 const int full_count = workspace->GetNumFullscreenWindows(); |
| 744 base::TimeDelta duration = old_layer && !IsMaximized(child) ? | 754 base::TimeDelta duration = (old_layer && !wm::IsWindowFullscreen(child)) ? |
| 745 GetCrossFadeDuration(old_layer->bounds(), child->bounds()) : | 755 GetCrossFadeDuration(old_layer->bounds(), child->bounds()) : |
| 746 base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS); | 756 base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS); |
| 747 if (max_count == 0) { | 757 if (full_count == 0) { |
| 748 if (workspace != desktop_workspace()) { | 758 if (workspace != desktop_workspace()) { |
| 749 { | 759 { |
| 750 base::AutoReset<bool> setter(&in_move_, true); | 760 base::AutoReset<bool> setter(&in_move_, true); |
| 751 ReparentWindow(child, desktop_workspace()->window(), NULL); | 761 ReparentWindow(child, desktop_workspace()->window(), NULL); |
| 752 } | 762 } |
| 753 DCHECK(!is_active || old_layer); | 763 DCHECK(!is_active || old_layer); |
| 754 new_workspace = desktop_workspace(); | 764 new_workspace = desktop_workspace(); |
| 755 SetActiveWorkspace(new_workspace, SWITCH_MAXIMIZED_OR_RESTORED, | 765 SetActiveWorkspace(new_workspace, SWITCH_MAXIMIZED_OR_RESTORED, |
| 756 duration); | 766 duration); |
| 757 MoveWorkspaceToPendingOrDelete(workspace, child, | 767 MoveWorkspaceToPendingOrDelete(workspace, child, |
| 758 SWITCH_MAXIMIZED_OR_RESTORED); | 768 SWITCH_MAXIMIZED_OR_RESTORED); |
| 759 if (FindWorkspace(workspace) == workspaces_.end()) | 769 if (FindWorkspace(workspace) == workspaces_.end()) |
| 760 workspace = NULL; | 770 workspace = NULL; |
| 761 } | 771 } |
| 762 } else if ((max_count == 1 && workspace == desktop_workspace()) || | 772 } else if ((full_count == 1 && workspace == desktop_workspace()) || |
| 763 max_count > 1) { | 773 full_count > 1) { |
| 764 new_workspace = CreateWorkspace(true); | 774 new_workspace = CreateWorkspace(true); |
| 765 pending_workspaces_.insert(new_workspace); | 775 pending_workspaces_.insert(new_workspace); |
| 766 ReparentWindow(child, new_workspace->window(), NULL); | 776 ReparentWindow(child, new_workspace->window(), NULL); |
| 767 } | 777 } |
| 768 if (is_active && new_workspace) { | 778 if (is_active && new_workspace) { |
| 769 // |old_layer| may be NULL if as part of processing | 779 // |old_layer| may be NULL if as part of processing |
| 770 // WorkspaceLayoutManager::OnWindowPropertyChanged() the window is made | 780 // WorkspaceLayoutManager::OnWindowPropertyChanged() the window is made |
| 771 // active. | 781 // active. |
| 772 if (old_layer) { | 782 if (old_layer) { |
| 773 SetActiveWorkspace(new_workspace, | 783 SetActiveWorkspace(new_workspace, |
| 774 max_count >= 2 ? | 784 full_count >= 2 ? |
| 775 SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE : | 785 SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE : |
| 776 SWITCH_MAXIMIZED_OR_RESTORED, | 786 SWITCH_MAXIMIZED_OR_RESTORED, |
| 777 duration); | 787 duration); |
| 778 CrossFadeWindowBetweenWorkspaces(new_workspace->window(), child, | 788 CrossFadeWindowBetweenWorkspaces(new_workspace->window(), child, |
| 779 old_layer); | 789 old_layer); |
| 780 if (workspace == desktop_workspace() || | 790 if (workspace == desktop_workspace() || |
| 781 new_workspace == desktop_workspace()) { | 791 new_workspace == desktop_workspace()) { |
| 782 FadeDesktop(child, duration); | 792 FadeDesktop(child, duration); |
| 783 } | 793 } |
| 784 } else { | 794 } else { |
| 785 SetActiveWorkspace(new_workspace, SWITCH_OTHER, base::TimeDelta()); | 795 SetActiveWorkspace(new_workspace, SWITCH_OTHER, base::TimeDelta()); |
| 786 } | 796 } |
| 787 } else { | 797 } else { |
| 788 if (last_show_state == ui::SHOW_STATE_MINIMIZED) | 798 if (last_show_state == ui::SHOW_STATE_MINIMIZED) |
| 789 SetUnminimizingWorkspace(new_workspace ? new_workspace : workspace); | 799 SetUnminimizingWorkspace(new_workspace ? new_workspace : workspace); |
| 790 DCHECK(!old_layer); | 800 DCHECK(!old_layer); |
| 791 } | 801 } |
| 792 } | 802 } |
| 793 UpdateShelfVisibility(); | 803 UpdateShelfVisibility(); |
| 794 } | 804 } |
| 795 | 805 |
| 796 void WorkspaceManager::OnTrackedByWorkspaceChanged(Workspace* workspace, | 806 void WorkspaceManager::OnTrackedByWorkspaceChanged(Workspace* workspace, |
| 797 aura::Window* window) { | 807 aura::Window* window) { |
| 798 Workspace* new_workspace = NULL; | 808 Workspace* new_workspace = NULL; |
| 799 if (IsMaximized(window)) { | 809 if (wm::IsWindowFullscreen(window)) { |
| 800 if (workspace->is_maximized() && workspace->GetNumMaximizedWindows() == 1) { | 810 if (workspace->is_fullscreen() && |
| 801 // If |window| is the only window in a maximized workspace then leave | 811 workspace->GetNumFullscreenWindows() == 1) { |
| 812 // If |window| is the only window in a fullscreen workspace then leave |
| 802 // it there. Additionally animate it back to the origin. | 813 // it there. Additionally animate it back to the origin. |
| 803 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); | 814 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
| 804 // All bounds changes get routed through WorkspaceLayoutManager and since | 815 // All bounds changes get routed through WorkspaceLayoutManager and since |
| 805 // the window is maximized WorkspaceLayoutManager is going to force a | 816 // the window is fullscreen WorkspaceLayoutManager is going to force a |
| 806 // value. In other words, it doesn't matter what we supply to SetBounds() | 817 // value. In other words, it doesn't matter what we supply to SetBounds() |
| 807 // here. | 818 // here. |
| 808 window->SetBounds(gfx::Rect()); | 819 window->SetBounds(gfx::Rect()); |
| 809 return; | 820 return; |
| 810 } | 821 } |
| 811 new_workspace = CreateWorkspace(true); | 822 new_workspace = CreateWorkspace(true); |
| 812 pending_workspaces_.insert(new_workspace); | 823 pending_workspaces_.insert(new_workspace); |
| 813 } else if (workspace->is_maximized()) { | 824 } else if (workspace->is_fullscreen()) { |
| 814 new_workspace = desktop_workspace(); | 825 new_workspace = desktop_workspace(); |
| 815 } else { | 826 } else { |
| 816 return; | 827 return; |
| 817 } | 828 } |
| 818 // If the window is active we need to make sure the destination Workspace | 829 // If the window is active we need to make sure the destination Workspace |
| 819 // window is showing. Otherwise the window will be parented to a hidden window | 830 // window is showing. Otherwise the window will be parented to a hidden window |
| 820 // and lose activation. | 831 // and lose activation. |
| 821 const bool is_active = wm::IsActiveWindow(window); | 832 const bool is_active = wm::IsActiveWindow(window); |
| 822 if (is_active) | 833 if (is_active) |
| 823 new_workspace->window()->Show(); | 834 new_workspace->window()->Show(); |
| 824 ReparentWindow(window, new_workspace->window(), NULL); | 835 ReparentWindow(window, new_workspace->window(), NULL); |
| 825 if (is_active) { | 836 if (is_active) { |
| 826 SetActiveWorkspace(new_workspace, SWITCH_TRACKED_BY_WORKSPACE_CHANGED, | 837 SetActiveWorkspace(new_workspace, SWITCH_TRACKED_BY_WORKSPACE_CHANGED, |
| 827 base::TimeDelta()); | 838 base::TimeDelta()); |
| 828 } | 839 } |
| 829 } | 840 } |
| 830 | 841 |
| 831 } // namespace internal | 842 } // namespace internal |
| 832 } // namespace ash | 843 } // namespace ash |
| OLD | NEW |