| 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_layout_manager.h" | 5 #include "ash/wm/workspace/workspace_layout_manager.h" |
| 6 | 6 |
| 7 #include "ash/display/display_controller.h" | 7 #include "ash/display/display_controller.h" |
| 8 #include "ash/root_window_controller.h" | 8 #include "ash/root_window_controller.h" |
| 9 #include "ash/screen_ash.h" | 9 #include "ash/screen_util.h" |
| 10 #include "ash/shelf/shelf_layout_manager.h" | 10 #include "ash/shelf/shelf_layout_manager.h" |
| 11 #include "ash/shell.h" | 11 #include "ash/shell.h" |
| 12 #include "ash/wm/always_on_top_controller.h" | 12 #include "ash/wm/always_on_top_controller.h" |
| 13 #include "ash/wm/base_layout_manager.h" | 13 #include "ash/wm/base_layout_manager.h" |
| 14 #include "ash/wm/window_animations.h" | 14 #include "ash/wm/window_animations.h" |
| 15 #include "ash/wm/window_positioner.h" | 15 #include "ash/wm/window_positioner.h" |
| 16 #include "ash/wm/window_properties.h" | 16 #include "ash/wm/window_properties.h" |
| 17 #include "ash/wm/window_state.h" | 17 #include "ash/wm/window_state.h" |
| 18 #include "ash/wm/window_util.h" | 18 #include "ash/wm/window_util.h" |
| 19 #include "ui/aura/client/aura_constants.h" | 19 #include "ui/aura/client/aura_constants.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 44 // Move only if the restore bounds is outside of | 44 // Move only if the restore bounds is outside of |
| 45 // the display. There is no information about in which | 45 // the display. There is no information about in which |
| 46 // display it should be restored, so this is best guess. | 46 // display it should be restored, so this is best guess. |
| 47 // TODO(oshima): Restore information should contain the | 47 // TODO(oshima): Restore information should contain the |
| 48 // work area information like WindowResizer does for the | 48 // work area information like WindowResizer does for the |
| 49 // last window location. | 49 // last window location. |
| 50 gfx::Rect display_area = Shell::GetScreen()->GetDisplayNearestWindow( | 50 gfx::Rect display_area = Shell::GetScreen()->GetDisplayNearestWindow( |
| 51 window_state->window()).bounds(); | 51 window_state->window()).bounds(); |
| 52 | 52 |
| 53 if (!display_area.Intersects(restore_bounds)) { | 53 if (!display_area.Intersects(restore_bounds)) { |
| 54 const gfx::Display& display = |
| 55 Shell::GetScreen()->GetDisplayMatching(restore_bounds); |
| 54 DisplayController* display_controller = | 56 DisplayController* display_controller = |
| 55 Shell::GetInstance()->display_controller(); | 57 Shell::GetInstance()->display_controller(); |
| 56 const gfx::Display& display = | |
| 57 display_controller->GetDisplayMatching(restore_bounds); | |
| 58 aura::Window* new_root = | 58 aura::Window* new_root = |
| 59 display_controller->GetRootWindowForDisplayId(display.id()); | 59 display_controller->GetRootWindowForDisplayId(display.id()); |
| 60 if (new_root != window_state->window()->GetRootWindow()) { | 60 if (new_root != window_state->window()->GetRootWindow()) { |
| 61 aura::Window* new_container = | 61 aura::Window* new_container = |
| 62 Shell::GetContainer(new_root, window_state->window()->parent()->id()); | 62 Shell::GetContainer(new_root, window_state->window()->parent()->id()); |
| 63 new_container->AddChild(window_state->window()); | 63 new_container->AddChild(window_state->window()); |
| 64 } | 64 } |
| 65 } | 65 } |
| 66 } | 66 } |
| 67 | 67 |
| 68 } // namespace | 68 } // namespace |
| 69 | 69 |
| 70 WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window) | 70 WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window) |
| 71 : BaseLayoutManager(window->GetRootWindow()), | 71 : BaseLayoutManager(window->GetRootWindow()), |
| 72 shelf_(NULL), | 72 shelf_(NULL), |
| 73 window_(window), | 73 window_(window), |
| 74 work_area_in_parent_(ScreenAsh::GetDisplayWorkAreaBoundsInParent( | 74 work_area_in_parent_(ScreenUtil::GetDisplayWorkAreaBoundsInParent( |
| 75 window->parent())), | 75 window->parent())), |
| 76 is_fullscreen_(GetRootWindowController( | 76 is_fullscreen_(GetRootWindowController( |
| 77 window->GetRootWindow())->GetWindowForFullscreenMode() != NULL) { | 77 window->GetRootWindow())->GetWindowForFullscreenMode() != NULL) { |
| 78 } | 78 } |
| 79 | 79 |
| 80 WorkspaceLayoutManager::~WorkspaceLayoutManager() { | 80 WorkspaceLayoutManager::~WorkspaceLayoutManager() { |
| 81 } | 81 } |
| 82 | 82 |
| 83 void WorkspaceLayoutManager::SetShelf(internal::ShelfLayoutManager* shelf) { | 83 void WorkspaceLayoutManager::SetShelf(internal::ShelfLayoutManager* shelf) { |
| 84 shelf_ = shelf; | 84 shelf_ = shelf; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 child_bounds.width())); | 132 child_bounds.width())); |
| 133 child_bounds.set_height(std::min(work_area_in_parent_.height(), | 133 child_bounds.set_height(std::min(work_area_in_parent_.height(), |
| 134 child_bounds.height())); | 134 child_bounds.height())); |
| 135 AdjustSnappedBounds(window_state, &child_bounds); | 135 AdjustSnappedBounds(window_state, &child_bounds); |
| 136 SetChildBoundsDirect(child, child_bounds); | 136 SetChildBoundsDirect(child, child_bounds); |
| 137 } | 137 } |
| 138 UpdateShelfVisibility(); | 138 UpdateShelfVisibility(); |
| 139 } | 139 } |
| 140 | 140 |
| 141 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() { | 141 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() { |
| 142 const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent( | 142 const gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent( |
| 143 window_->parent())); | 143 window_->parent())); |
| 144 if (work_area != work_area_in_parent_) { | 144 if (work_area != work_area_in_parent_) { |
| 145 AdjustAllWindowsBoundsForWorkAreaChange( | 145 AdjustAllWindowsBoundsForWorkAreaChange( |
| 146 ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED); | 146 ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED); |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 | 149 |
| 150 void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window, | 150 void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window, |
| 151 const void* key, | 151 const void* key, |
| 152 intptr_t old) { | 152 intptr_t old) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 // Notify observers that fullscreen state may be changing. | 198 // Notify observers that fullscreen state may be changing. |
| 199 if (window_state->IsFullscreen() || old_type == wm::SHOW_TYPE_FULLSCREEN) | 199 if (window_state->IsFullscreen() || old_type == wm::SHOW_TYPE_FULLSCREEN) |
| 200 UpdateFullscreenState(); | 200 UpdateFullscreenState(); |
| 201 | 201 |
| 202 UpdateShelfVisibility(); | 202 UpdateShelfVisibility(); |
| 203 } | 203 } |
| 204 | 204 |
| 205 void WorkspaceLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange( | 205 void WorkspaceLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange( |
| 206 AdjustWindowReason reason) { | 206 AdjustWindowReason reason) { |
| 207 work_area_in_parent_ = | 207 work_area_in_parent_ = |
| 208 ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_->parent()); | 208 ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_->parent()); |
| 209 BaseLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(reason); | 209 BaseLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(reason); |
| 210 } | 210 } |
| 211 | 211 |
| 212 void WorkspaceLayoutManager::AdjustWindowBoundsForWorkAreaChange( | 212 void WorkspaceLayoutManager::AdjustWindowBoundsForWorkAreaChange( |
| 213 wm::WindowState* window_state, | 213 wm::WindowState* window_state, |
| 214 AdjustWindowReason reason) { | 214 AdjustWindowReason reason) { |
| 215 if (window_state->is_dragged()) | 215 if (window_state->is_dragged()) |
| 216 return; | 216 return; |
| 217 | 217 |
| 218 // Do not cross fade here: the window's layer hierarchy may be messed up for | 218 // Do not cross fade here: the window's layer hierarchy may be messed up for |
| 219 // the transition between mirroring and extended. See also: crbug.com/267698 | 219 // the transition between mirroring and extended. See also: crbug.com/267698 |
| 220 // TODO(oshima): Differentiate display change and shelf visibility change, and | 220 // TODO(oshima): Differentiate display change and shelf visibility change, and |
| 221 // bring back CrossFade animation. | 221 // bring back CrossFade animation. |
| 222 if (window_state->IsMaximized() && | 222 if (window_state->IsMaximized() && |
| 223 reason == ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED) { | 223 reason == ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED) { |
| 224 SetChildBoundsDirect(window_state->window(), | 224 SetChildBoundsDirect(window_state->window(), |
| 225 ScreenAsh::GetMaximizedWindowBoundsInParent( | 225 ScreenUtil::GetMaximizedWindowBoundsInParent( |
| 226 window_state->window()->parent()->parent())); | 226 window_state->window()->parent()->parent())); |
| 227 return; | 227 return; |
| 228 } | 228 } |
| 229 | 229 |
| 230 if (SetMaximizedOrFullscreenBounds(window_state)) | 230 if (SetMaximizedOrFullscreenBounds(window_state)) |
| 231 return; | 231 return; |
| 232 | 232 |
| 233 gfx::Rect bounds = window_state->window()->bounds(); | 233 gfx::Rect bounds = window_state->window()->bounds(); |
| 234 switch (reason) { | 234 switch (reason) { |
| 235 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED: | 235 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED: |
| (...skipping 24 matching lines...) Expand all Loading... |
| 260 return; | 260 return; |
| 261 } | 261 } |
| 262 | 262 |
| 263 Window* window = window_state->window(); | 263 Window* window = window_state->window(); |
| 264 gfx::Rect bounds = window->bounds(); | 264 gfx::Rect bounds = window->bounds(); |
| 265 | 265 |
| 266 // Use entire display instead of workarea because the workarea can | 266 // Use entire display instead of workarea because the workarea can |
| 267 // be further shrunk by the docked area. The logic ensures 30% | 267 // be further shrunk by the docked area. The logic ensures 30% |
| 268 // visibility which should be enough to see where the window gets | 268 // visibility which should be enough to see where the window gets |
| 269 // moved. | 269 // moved. |
| 270 gfx::Rect display_area = ScreenAsh::GetDisplayBoundsInParent(window); | 270 gfx::Rect display_area = ScreenUtil::GetDisplayBoundsInParent(window); |
| 271 | 271 |
| 272 int min_width = bounds.width() * kMinimumPercentOnScreenArea; | 272 int min_width = bounds.width() * kMinimumPercentOnScreenArea; |
| 273 int min_height = bounds.height() * kMinimumPercentOnScreenArea; | 273 int min_height = bounds.height() * kMinimumPercentOnScreenArea; |
| 274 ash::wm::AdjustBoundsToEnsureWindowVisibility( | 274 ash::wm::AdjustBoundsToEnsureWindowVisibility( |
| 275 display_area, min_width, min_height, &bounds); | 275 display_area, min_width, min_height, &bounds); |
| 276 AdjustSnappedBounds(window_state, &bounds); | 276 AdjustSnappedBounds(window_state, &bounds); |
| 277 if (window->bounds() != bounds) | 277 if (window->bounds() != bounds) |
| 278 window->SetBounds(bounds); | 278 window->SetBounds(bounds); |
| 279 } | 279 } |
| 280 | 280 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 show_type == wm::SHOW_TYPE_RIGHT_SNAPPED) { | 321 show_type == wm::SHOW_TYPE_RIGHT_SNAPPED) { |
| 322 AdjustSnappedBounds(window_state, &bounds_in_parent); | 322 AdjustSnappedBounds(window_state, &bounds_in_parent); |
| 323 } else { | 323 } else { |
| 324 bounds_in_parent = BaseLayoutManager::BoundsWithScreenEdgeVisible( | 324 bounds_in_parent = BaseLayoutManager::BoundsWithScreenEdgeVisible( |
| 325 window->parent()->parent(), | 325 window->parent()->parent(), |
| 326 bounds_in_parent); | 326 bounds_in_parent); |
| 327 } | 327 } |
| 328 break; | 328 break; |
| 329 | 329 |
| 330 case wm::SHOW_TYPE_MAXIMIZED: | 330 case wm::SHOW_TYPE_MAXIMIZED: |
| 331 bounds_in_parent = ScreenAsh::GetMaximizedWindowBoundsInParent( | 331 bounds_in_parent = ScreenUtil::GetMaximizedWindowBoundsInParent( |
| 332 window->parent()->parent()); | 332 window->parent()->parent()); |
| 333 break; | 333 break; |
| 334 | 334 |
| 335 case wm::SHOW_TYPE_FULLSCREEN: | 335 case wm::SHOW_TYPE_FULLSCREEN: |
| 336 bounds_in_parent = ScreenAsh::GetDisplayBoundsInParent( | 336 bounds_in_parent = ScreenUtil::GetDisplayBoundsInParent( |
| 337 window->parent()->parent()); | 337 window->parent()->parent()); |
| 338 break; | 338 break; |
| 339 | 339 |
| 340 case wm::SHOW_TYPE_MINIMIZED: | 340 case wm::SHOW_TYPE_MINIMIZED: |
| 341 case wm::SHOW_TYPE_INACTIVE: | 341 case wm::SHOW_TYPE_INACTIVE: |
| 342 case wm::SHOW_TYPE_DETACHED: | 342 case wm::SHOW_TYPE_DETACHED: |
| 343 case wm::SHOW_TYPE_END: | 343 case wm::SHOW_TYPE_END: |
| 344 case wm::SHOW_TYPE_AUTO_POSITIONED: | 344 case wm::SHOW_TYPE_AUTO_POSITIONED: |
| 345 return; | 345 return; |
| 346 } | 346 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 359 | 359 |
| 360 bool WorkspaceLayoutManager::SetMaximizedOrFullscreenBounds( | 360 bool WorkspaceLayoutManager::SetMaximizedOrFullscreenBounds( |
| 361 wm::WindowState* window_state) { | 361 wm::WindowState* window_state) { |
| 362 DCHECK(!window_state->is_dragged()); | 362 DCHECK(!window_state->is_dragged()); |
| 363 | 363 |
| 364 // During animations there is a transform installed on the workspace | 364 // During animations there is a transform installed on the workspace |
| 365 // windows. For this reason this code uses the parent so that the transform is | 365 // windows. For this reason this code uses the parent so that the transform is |
| 366 // ignored. | 366 // ignored. |
| 367 if (window_state->IsMaximized()) { | 367 if (window_state->IsMaximized()) { |
| 368 SetChildBoundsDirect( | 368 SetChildBoundsDirect( |
| 369 window_state->window(), ScreenAsh::GetMaximizedWindowBoundsInParent( | 369 window_state->window(), ScreenUtil::GetMaximizedWindowBoundsInParent( |
| 370 window_state->window()->parent()->parent())); | 370 window_state->window()->parent()->parent())); |
| 371 return true; | 371 return true; |
| 372 } | 372 } |
| 373 if (window_state->IsFullscreen()) { | 373 if (window_state->IsFullscreen()) { |
| 374 SetChildBoundsDirect( | 374 SetChildBoundsDirect( |
| 375 window_state->window(), | 375 window_state->window(), |
| 376 ScreenAsh::GetDisplayBoundsInParent( | 376 ScreenUtil::GetDisplayBoundsInParent( |
| 377 window_state->window()->parent()->parent())); | 377 window_state->window()->parent()->parent())); |
| 378 return true; | 378 return true; |
| 379 } | 379 } |
| 380 return false; | 380 return false; |
| 381 } | 381 } |
| 382 | 382 |
| 383 void WorkspaceLayoutManager::AdjustSnappedBounds(wm::WindowState* window_state, | 383 void WorkspaceLayoutManager::AdjustSnappedBounds(wm::WindowState* window_state, |
| 384 gfx::Rect* bounds) { | 384 gfx::Rect* bounds) { |
| 385 if (window_state->is_dragged() || !window_state->IsSnapped()) | 385 if (window_state->is_dragged() || !window_state->IsSnapped()) |
| 386 return; | 386 return; |
| 387 gfx::Rect maximized_bounds = ScreenAsh::GetMaximizedWindowBoundsInParent( | 387 gfx::Rect maximized_bounds = ScreenUtil::GetMaximizedWindowBoundsInParent( |
| 388 window_state->window()->parent()->parent()); | 388 window_state->window()->parent()->parent()); |
| 389 if (window_state->window_show_type() == wm::SHOW_TYPE_LEFT_SNAPPED) | 389 if (window_state->window_show_type() == wm::SHOW_TYPE_LEFT_SNAPPED) |
| 390 bounds->set_x(maximized_bounds.x()); | 390 bounds->set_x(maximized_bounds.x()); |
| 391 else if (window_state->window_show_type() == wm::SHOW_TYPE_RIGHT_SNAPPED) | 391 else if (window_state->window_show_type() == wm::SHOW_TYPE_RIGHT_SNAPPED) |
| 392 bounds->set_x(maximized_bounds.right() - bounds->width()); | 392 bounds->set_x(maximized_bounds.right() - bounds->width()); |
| 393 bounds->set_y(maximized_bounds.y()); | 393 bounds->set_y(maximized_bounds.y()); |
| 394 // TODO(varkha): Set width to 50% here for snapped windows. | 394 // TODO(varkha): Set width to 50% here for snapped windows. |
| 395 bounds->set_height(maximized_bounds.height()); | 395 bounds->set_height(maximized_bounds.height()); |
| 396 } | 396 } |
| 397 | 397 |
| 398 void WorkspaceLayoutManager::SetChildBoundsAnimated(Window* child, | 398 void WorkspaceLayoutManager::SetChildBoundsAnimated(Window* child, |
| 399 const gfx::Rect& bounds) { | 399 const gfx::Rect& bounds) { |
| 400 const int kBoundsChangeSlideDurationMs = 120; | 400 const int kBoundsChangeSlideDurationMs = 120; |
| 401 | 401 |
| 402 ui::Layer* layer = child->layer(); | 402 ui::Layer* layer = child->layer(); |
| 403 ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator()); | 403 ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator()); |
| 404 slide_settings.SetPreemptionStrategy( | 404 slide_settings.SetPreemptionStrategy( |
| 405 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 405 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 406 slide_settings.SetTransitionDuration( | 406 slide_settings.SetTransitionDuration( |
| 407 base::TimeDelta::FromMilliseconds(kBoundsChangeSlideDurationMs)); | 407 base::TimeDelta::FromMilliseconds(kBoundsChangeSlideDurationMs)); |
| 408 SetChildBoundsDirect(child, bounds); | 408 SetChildBoundsDirect(child, bounds); |
| 409 } | 409 } |
| 410 | 410 |
| 411 } // namespace internal | 411 } // namespace internal |
| 412 } // namespace ash | 412 } // namespace ash |
| OLD | NEW |