| 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/common/wm/panels/panel_layout_manager.h" | 5 #include "ash/common/wm/panels/panel_layout_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "ash/common/keyboard/keyboard_observer_register.h" | 11 #include "ash/common/keyboard/keyboard_observer_register.h" |
| 12 #include "ash/common/shelf/wm_shelf.h" | 12 #include "ash/common/shelf/wm_shelf.h" |
| 13 #include "ash/common/shelf/wm_shelf_util.h" | 13 #include "ash/common/shelf/wm_shelf_util.h" |
| 14 #include "ash/common/wm/overview/window_selector_controller.h" | 14 #include "ash/common/wm/overview/window_selector_controller.h" |
| 15 #include "ash/common/wm/window_animation_types.h" | 15 #include "ash/common/wm/window_animation_types.h" |
| 16 #include "ash/common/wm/window_parenting_utils.h" | 16 #include "ash/common/wm/window_parenting_utils.h" |
| 17 #include "ash/common/wm/window_state.h" | 17 #include "ash/common/wm/window_state.h" |
| 18 #include "ash/common/wm_shell.h" | 18 #include "ash/common/wm_shell.h" |
| 19 #include "ash/common/wm_window.h" | 19 #include "ash/common/wm_window.h" |
| 20 #include "ash/public/cpp/shell_window_ids.h" | 20 #include "ash/public/cpp/shell_window_ids.h" |
| 21 #include "ash/public/cpp/window_properties.h" | 21 #include "ash/public/cpp/window_properties.h" |
| 22 #include "ash/root_window_controller.h" | 22 #include "ash/root_window_controller.h" |
| 23 #include "ash/shell.h" | 23 #include "ash/shell.h" |
| 24 #include "ash/wm/window_properties.h" | 24 #include "ash/wm/window_properties.h" |
| 25 #include "ash/wm/window_state_aura.h" |
| 26 #include "ash/wm/window_util.h" |
| 25 #include "base/auto_reset.h" | 27 #include "base/auto_reset.h" |
| 26 #include "third_party/skia/include/core/SkColor.h" | 28 #include "third_party/skia/include/core/SkColor.h" |
| 27 #include "third_party/skia/include/core/SkPath.h" | 29 #include "third_party/skia/include/core/SkPath.h" |
| 30 #include "ui/aura/client/window_parenting_client.h" |
| 31 #include "ui/aura/window_delegate.h" |
| 28 #include "ui/compositor/scoped_layer_animation_settings.h" | 32 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 29 #include "ui/gfx/canvas.h" | 33 #include "ui/gfx/canvas.h" |
| 30 #include "ui/gfx/geometry/rect.h" | 34 #include "ui/gfx/geometry/rect.h" |
| 31 #include "ui/gfx/geometry/vector2d.h" | 35 #include "ui/gfx/geometry/vector2d.h" |
| 32 #include "ui/views/background.h" | 36 #include "ui/views/background.h" |
| 33 #include "ui/views/widget/widget.h" | 37 #include "ui/views/widget/widget.h" |
| 34 #include "ui/wm/public/activation_client.h" | 38 #include "ui/wm/public/activation_client.h" |
| 35 | 39 |
| 40 using aura::Window; |
| 41 |
| 36 namespace ash { | 42 namespace ash { |
| 37 namespace { | 43 namespace { |
| 38 | 44 |
| 39 const int kPanelIdealSpacing = 4; | 45 const int kPanelIdealSpacing = 4; |
| 40 | 46 |
| 41 const float kMaxHeightFactor = .80f; | 47 const float kMaxHeightFactor = .80f; |
| 42 const float kMaxWidthFactor = .50f; | 48 const float kMaxWidthFactor = .50f; |
| 43 | 49 |
| 44 // Duration for panel animations. | 50 // Duration for panel animations. |
| 45 const int kPanelSlideDurationMilliseconds = 50; | 51 const int kPanelSlideDurationMilliseconds = 50; |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 } | 269 } |
| 264 | 270 |
| 265 // static | 271 // static |
| 266 PanelLayoutManager* PanelLayoutManager::Get(WmWindow* window) { | 272 PanelLayoutManager* PanelLayoutManager::Get(WmWindow* window) { |
| 267 if (!window) | 273 if (!window) |
| 268 return nullptr; | 274 return nullptr; |
| 269 | 275 |
| 270 return static_cast<PanelLayoutManager*>( | 276 return static_cast<PanelLayoutManager*>( |
| 271 window->GetRootWindow() | 277 window->GetRootWindow() |
| 272 ->GetChildByShellWindowId(kShellWindowId_PanelContainer) | 278 ->GetChildByShellWindowId(kShellWindowId_PanelContainer) |
| 273 ->GetLayoutManager()); | 279 ->aura_window() |
| 280 ->layout_manager()); |
| 274 } | 281 } |
| 275 | 282 |
| 276 void PanelLayoutManager::Shutdown() { | 283 void PanelLayoutManager::Shutdown() { |
| 277 if (shelf_) { | 284 if (shelf_) { |
| 278 shelf_->RemoveObserver(this); | 285 shelf_->RemoveObserver(this); |
| 279 shelf_ = nullptr; | 286 shelf_ = nullptr; |
| 280 } | 287 } |
| 281 for (PanelList::iterator iter = panel_windows_.begin(); | 288 for (PanelList::iterator iter = panel_windows_.begin(); |
| 282 iter != panel_windows_.end(); ++iter) { | 289 iter != panel_windows_.end(); ++iter) { |
| 283 delete iter->callout_widget; | 290 delete iter->callout_widget; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 DCHECK(found != panel_windows_.end()); | 337 DCHECK(found != panel_windows_.end()); |
| 331 return found->callout_widget; | 338 return found->callout_widget; |
| 332 } | 339 } |
| 333 | 340 |
| 334 //////////////////////////////////////////////////////////////////////////////// | 341 //////////////////////////////////////////////////////////////////////////////// |
| 335 // PanelLayoutManager, WmLayoutManager implementation: | 342 // PanelLayoutManager, WmLayoutManager implementation: |
| 336 void PanelLayoutManager::OnWindowResized() { | 343 void PanelLayoutManager::OnWindowResized() { |
| 337 Relayout(); | 344 Relayout(); |
| 338 } | 345 } |
| 339 | 346 |
| 340 void PanelLayoutManager::OnWindowAddedToLayout(WmWindow* child) { | 347 void PanelLayoutManager::OnWindowAddedToLayout(Window* child) { |
| 341 if (child->GetType() == ui::wm::WINDOW_TYPE_POPUP) | 348 if (child->type() == ui::wm::WINDOW_TYPE_POPUP) |
| 342 return; | 349 return; |
| 343 if (in_add_window_) | 350 if (in_add_window_) |
| 344 return; | 351 return; |
| 345 base::AutoReset<bool> auto_reset_in_add_window(&in_add_window_, true); | 352 base::AutoReset<bool> auto_reset_in_add_window(&in_add_window_, true); |
| 346 if (!child->aura_window()->GetProperty(kPanelAttachedKey)) { | 353 if (!child->GetProperty(kPanelAttachedKey)) { |
| 347 // This should only happen when a window is added to panel container as a | 354 // This should only happen when a window is added to panel container as a |
| 348 // result of bounds change from within the application during a drag. | 355 // result of bounds change from within the application during a drag. |
| 349 // If so we have already stopped the drag and should reparent the panel | 356 // If so we have already stopped the drag and should reparent the panel |
| 350 // back to appropriate container and ignore it. | 357 // back to appropriate container and ignore it. |
| 351 // TODO(varkha): Updating bounds during a drag can cause problems and a more | 358 // TODO(varkha): Updating bounds during a drag can cause problems and a more |
| 352 // general solution is needed. See http://crbug.com/251813 . | 359 // general solution is needed. See http://crbug.com/251813 . |
| 353 aura::Window* old_parent = child->aura_window()->parent(); | 360 Window* old_parent = child->parent(); |
| 354 child->SetParentUsingContext(child, | 361 aura::client::ParentWindowWithContext( |
| 355 child->GetRootWindow()->GetBoundsInScreen()); | 362 child, child, child->GetRootWindow()->GetBoundsInScreen()); |
| 356 wm::ReparentTransientChildrenOfChild(child->aura_window(), old_parent, | 363 wm::ReparentTransientChildrenOfChild(child, old_parent, child->parent()); |
| 357 child->aura_window()->parent()); | 364 DCHECK(child->parent()->id() != kShellWindowId_PanelContainer); |
| 358 DCHECK(child->GetParent()->GetShellWindowId() != | |
| 359 kShellWindowId_PanelContainer); | |
| 360 return; | 365 return; |
| 361 } | 366 } |
| 362 PanelInfo panel_info; | 367 PanelInfo panel_info; |
| 363 panel_info.window = child; | 368 panel_info.window = WmWindow::Get(child); |
| 364 panel_info.callout_widget = new PanelCalloutWidget(panel_container_); | 369 panel_info.callout_widget = new PanelCalloutWidget(panel_container_); |
| 365 panel_info.slide_in = child != dragged_panel_; | 370 panel_info.slide_in = WmWindow::Get(child) != dragged_panel_; |
| 366 panel_windows_.push_back(panel_info); | 371 panel_windows_.push_back(panel_info); |
| 367 child->aura_window()->AddObserver(this); | 372 child->AddObserver(this); |
| 368 child->GetWindowState()->AddObserver(this); | 373 wm::GetWindowState(child)->AddObserver(this); |
| 369 Relayout(); | 374 Relayout(); |
| 370 } | 375 } |
| 371 | 376 |
| 372 void PanelLayoutManager::OnWillRemoveWindowFromLayout(WmWindow* child) {} | 377 void PanelLayoutManager::OnWillRemoveWindowFromLayout(Window* child) {} |
| 373 | 378 |
| 374 void PanelLayoutManager::OnWindowRemovedFromLayout(WmWindow* child) { | 379 void PanelLayoutManager::OnWindowRemovedFromLayout(Window* child) { |
| 375 if (child->GetType() == ui::wm::WINDOW_TYPE_POPUP) | 380 if (child->type() == ui::wm::WINDOW_TYPE_POPUP) |
| 376 return; | 381 return; |
| 377 | 382 |
| 378 PanelList::iterator found = | 383 PanelList::iterator found = std::find( |
| 379 std::find(panel_windows_.begin(), panel_windows_.end(), child); | 384 panel_windows_.begin(), panel_windows_.end(), WmWindow::Get(child)); |
| 380 if (found != panel_windows_.end()) { | 385 if (found != panel_windows_.end()) { |
| 381 delete found->callout_widget; | 386 delete found->callout_widget; |
| 382 panel_windows_.erase(found); | 387 panel_windows_.erase(found); |
| 383 } | 388 } |
| 384 if (restore_windows_on_shelf_visible_) | 389 if (restore_windows_on_shelf_visible_) |
| 385 restore_windows_on_shelf_visible_->Remove(child->aura_window()); | 390 restore_windows_on_shelf_visible_->Remove(child); |
| 386 child->aura_window()->RemoveObserver(this); | 391 child->RemoveObserver(this); |
| 387 child->GetWindowState()->RemoveObserver(this); | 392 wm::GetWindowState(child)->RemoveObserver(this); |
| 388 | 393 |
| 389 if (dragged_panel_ == child) | 394 if (dragged_panel_ == WmWindow::Get(child)) |
| 390 dragged_panel_ = nullptr; | 395 dragged_panel_ = nullptr; |
| 391 | 396 |
| 392 if (last_active_panel_ == child) | 397 if (last_active_panel_ == WmWindow::Get(child)) |
| 393 last_active_panel_ = nullptr; | 398 last_active_panel_ = nullptr; |
| 394 | 399 |
| 395 Relayout(); | 400 Relayout(); |
| 396 } | 401 } |
| 397 | 402 |
| 398 void PanelLayoutManager::OnChildWindowVisibilityChanged(WmWindow* child, | 403 void PanelLayoutManager::OnChildWindowVisibilityChanged(Window* child, |
| 399 bool visible) { | 404 bool visible) { |
| 400 if (visible) | 405 if (visible) |
| 401 child->GetWindowState()->Restore(); | 406 wm::GetWindowState(child)->Restore(); |
| 402 Relayout(); | 407 Relayout(); |
| 403 } | 408 } |
| 404 | 409 |
| 405 void PanelLayoutManager::SetChildBounds(WmWindow* child, | 410 void PanelLayoutManager::SetChildBounds(Window* child, |
| 406 const gfx::Rect& requested_bounds) { | 411 const gfx::Rect& requested_bounds) { |
| 407 gfx::Rect bounds(requested_bounds); | 412 gfx::Rect bounds(requested_bounds); |
| 408 const gfx::Rect& max_bounds = panel_container_->GetRootWindow()->GetBounds(); | 413 const gfx::Rect& max_bounds = panel_container_->GetRootWindow()->GetBounds(); |
| 409 const int max_width = max_bounds.width() * kMaxWidthFactor; | 414 const int max_width = max_bounds.width() * kMaxWidthFactor; |
| 410 const int max_height = max_bounds.height() * kMaxHeightFactor; | 415 const int max_height = max_bounds.height() * kMaxHeightFactor; |
| 411 if (bounds.width() > max_width) | 416 if (bounds.width() > max_width) |
| 412 bounds.set_width(max_width); | 417 bounds.set_width(max_width); |
| 413 if (bounds.height() > max_height) | 418 if (bounds.height() > max_height) |
| 414 bounds.set_height(max_height); | 419 bounds.set_height(max_height); |
| 415 | 420 |
| 416 // Reposition dragged panel in the panel order. | 421 // Reposition dragged panel in the panel order. |
| 417 if (dragged_panel_ == child) { | 422 if (dragged_panel_ == WmWindow::Get(child)) { |
| 418 PanelList::iterator dragged_panel_iter = | 423 PanelList::iterator dragged_panel_iter = |
| 419 std::find(panel_windows_.begin(), panel_windows_.end(), dragged_panel_); | 424 std::find(panel_windows_.begin(), panel_windows_.end(), dragged_panel_); |
| 420 DCHECK(dragged_panel_iter != panel_windows_.end()); | 425 DCHECK(dragged_panel_iter != panel_windows_.end()); |
| 421 PanelList::iterator new_position; | 426 PanelList::iterator new_position; |
| 422 for (new_position = panel_windows_.begin(); | 427 for (new_position = panel_windows_.begin(); |
| 423 new_position != panel_windows_.end(); ++new_position) { | 428 new_position != panel_windows_.end(); ++new_position) { |
| 424 const gfx::Rect& bounds = (*new_position).window->GetBounds(); | 429 const gfx::Rect& bounds = (*new_position).window->GetBounds(); |
| 425 if (bounds.x() + bounds.width() / 2 <= requested_bounds.x()) | 430 if (bounds.x() + bounds.width() / 2 <= requested_bounds.x()) |
| 426 break; | 431 break; |
| 427 } | 432 } |
| 428 if (new_position != dragged_panel_iter) { | 433 if (new_position != dragged_panel_iter) { |
| 429 PanelInfo dragged_panel_info = *dragged_panel_iter; | 434 PanelInfo dragged_panel_info = *dragged_panel_iter; |
| 430 panel_windows_.erase(dragged_panel_iter); | 435 panel_windows_.erase(dragged_panel_iter); |
| 431 panel_windows_.insert(new_position, dragged_panel_info); | 436 panel_windows_.insert(new_position, dragged_panel_info); |
| 432 } | 437 } |
| 433 } | 438 } |
| 434 // Respect the minimum size of the window. | 439 // Respect the minimum size of the window. |
| 435 if (child->HasNonClientArea()) { | 440 if (child->delegate()) { |
| 436 const gfx::Size min_size = child->GetMinimumSize(); | 441 const gfx::Size min_size = child->delegate()->GetMinimumSize(); |
| 437 bounds.set_width(std::max(min_size.width(), bounds.width())); | 442 bounds.set_width(std::max(min_size.width(), bounds.width())); |
| 438 bounds.set_height(std::max(min_size.height(), bounds.height())); | 443 bounds.set_height(std::max(min_size.height(), bounds.height())); |
| 439 } | 444 } |
| 440 | 445 |
| 441 child->SetBoundsDirect(bounds); | 446 SetChildBoundsDirect(child, bounds); |
| 447 wm::SnapWindowToPixelBoundary(child); |
| 442 Relayout(); | 448 Relayout(); |
| 443 } | 449 } |
| 444 | 450 |
| 445 //////////////////////////////////////////////////////////////////////////////// | 451 //////////////////////////////////////////////////////////////////////////////// |
| 446 // PanelLayoutManager, ShellObserver implementation: | 452 // PanelLayoutManager, ShellObserver implementation: |
| 447 | 453 |
| 448 void PanelLayoutManager::OnOverviewModeEnded() { | 454 void PanelLayoutManager::OnOverviewModeEnded() { |
| 449 Relayout(); | 455 Relayout(); |
| 450 } | 456 } |
| 451 | 457 |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 937 // This bounds change will have caused a change to the Shelf which does not | 943 // This bounds change will have caused a change to the Shelf which does not |
| 938 // propogate automatically to this class, so manually recalculate bounds. | 944 // propogate automatically to this class, so manually recalculate bounds. |
| 939 OnWindowResized(); | 945 OnWindowResized(); |
| 940 } | 946 } |
| 941 | 947 |
| 942 void PanelLayoutManager::OnKeyboardClosed() { | 948 void PanelLayoutManager::OnKeyboardClosed() { |
| 943 keyboard_observer_.RemoveAll(); | 949 keyboard_observer_.RemoveAll(); |
| 944 } | 950 } |
| 945 | 951 |
| 946 } // namespace ash | 952 } // namespace ash |
| OLD | NEW |