| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/dock/docked_window_layout_manager.h" | 5 #include "ash/wm/dock/docked_window_layout_manager.h" |
| 6 | 6 |
| 7 #include "ash/screen_util.h" | |
| 8 #include "ash/shelf/shelf.h" | 7 #include "ash/shelf/shelf.h" |
| 9 #include "ash/shelf/shelf_constants.h" | 8 #include "ash/shelf/shelf_constants.h" |
| 10 #include "ash/shelf/shelf_layout_manager.h" | 9 #include "ash/shelf/shelf_layout_manager.h" |
| 11 #include "ash/shelf/shelf_layout_manager_observer.h" | 10 #include "ash/shelf/shelf_layout_manager_observer.h" |
| 12 #include "ash/shelf/shelf_types.h" | 11 #include "ash/shelf/shelf_types.h" |
| 13 #include "ash/shelf/shelf_widget.h" | 12 #include "ash/shelf/shelf_widget.h" |
| 14 #include "ash/shell.h" | |
| 15 #include "ash/shell_window_ids.h" | 13 #include "ash/shell_window_ids.h" |
| 16 #include "ash/wm/common/window_animation_types.h" | 14 #include "ash/wm/common/window_animation_types.h" |
| 17 #include "ash/wm/common/window_parenting_utils.h" | 15 #include "ash/wm/common/window_parenting_utils.h" |
| 18 #include "ash/wm/common/wm_globals.h" | 16 #include "ash/wm/common/wm_globals.h" |
| 19 #include "ash/wm/common/wm_root_window_controller.h" | 17 #include "ash/wm/common/wm_root_window_controller.h" |
| 20 #include "ash/wm/window_animations.h" | 18 #include "ash/wm/window_animations.h" |
| 21 #include "ash/wm/window_properties.h" | |
| 22 #include "ash/wm/window_resizer.h" | 19 #include "ash/wm/window_resizer.h" |
| 23 #include "ash/wm/window_state.h" | 20 #include "ash/wm/window_state.h" |
| 24 #include "ash/wm/window_state_aura.h" | |
| 25 #include "ash/wm/window_util.h" | |
| 26 #include "ash/wm/workspace_controller.h" | 21 #include "ash/wm/workspace_controller.h" |
| 27 #include "base/auto_reset.h" | 22 #include "base/auto_reset.h" |
| 28 #include "base/command_line.h" | |
| 29 #include "base/metrics/histogram.h" | 23 #include "base/metrics/histogram.h" |
| 30 #include "grit/ash_resources.h" | 24 #include "grit/ash_resources.h" |
| 31 #include "third_party/skia/include/core/SkColor.h" | 25 #include "third_party/skia/include/core/SkColor.h" |
| 32 #include "third_party/skia/include/core/SkPaint.h" | 26 #include "third_party/skia/include/core/SkPaint.h" |
| 33 #include "ui/aura/client/focus_client.h" | |
| 34 #include "ui/aura/client/window_tree_client.h" | |
| 35 #include "ui/aura/window.h" | |
| 36 #include "ui/aura/window_delegate.h" | |
| 37 #include "ui/aura/window_event_dispatcher.h" | |
| 38 #include "ui/base/resource/resource_bundle.h" | 27 #include "ui/base/resource/resource_bundle.h" |
| 39 #include "ui/compositor/paint_recorder.h" | 28 #include "ui/compositor/paint_recorder.h" |
| 40 #include "ui/compositor/scoped_layer_animation_settings.h" | 29 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 41 #include "ui/gfx/canvas.h" | 30 #include "ui/gfx/canvas.h" |
| 42 #include "ui/gfx/geometry/rect.h" | 31 #include "ui/gfx/display.h" |
| 43 #include "ui/gfx/image/image_skia_operations.h" | 32 #include "ui/gfx/image/image_skia_operations.h" |
| 44 #include "ui/views/background.h" | 33 #include "ui/views/background.h" |
| 45 #include "ui/wm/core/window_util.h" | |
| 46 #include "ui/wm/public/activation_client.h" | |
| 47 | 34 |
| 48 namespace ash { | 35 namespace ash { |
| 49 | 36 |
| 50 // Minimum, maximum width of the dock area and a width of the gap | 37 // Minimum, maximum width of the dock area and a width of the gap |
| 51 // static | 38 // static |
| 52 const int DockedWindowLayoutManager::kMaxDockWidth = 360; | 39 const int DockedWindowLayoutManager::kMaxDockWidth = 360; |
| 53 // static | 40 // static |
| 54 const int DockedWindowLayoutManager::kMinDockWidth = 200; | 41 const int DockedWindowLayoutManager::kMinDockWidth = 200; |
| 55 // static | 42 // static |
| 56 const int DockedWindowLayoutManager::kMinDockGap = 2; | 43 const int DockedWindowLayoutManager::kMinDockGap = 2; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 params.type = views::Widget::InitParams::TYPE_POPUP; | 131 params.type = views::Widget::InitParams::TYPE_POPUP; |
| 145 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 132 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 146 params.keep_on_top = false; | 133 params.keep_on_top = false; |
| 147 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 134 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 148 params.accept_events = false; | 135 params.accept_events = false; |
| 149 set_focus_on_creation(false); | 136 set_focus_on_creation(false); |
| 150 parent->GetRootWindowController()->ConfigureWidgetInitParamsForContainer( | 137 parent->GetRootWindowController()->ConfigureWidgetInitParamsForContainer( |
| 151 this, parent->GetShellWindowId(), ¶ms); | 138 this, parent->GetShellWindowId(), ¶ms); |
| 152 Init(params); | 139 Init(params); |
| 153 SetVisibilityChangedAnimationsEnabled(false); | 140 SetVisibilityChangedAnimationsEnabled(false); |
| 154 GetNativeWindow()->SetProperty(kStayInSameRootWindowKey, true); | 141 wm::WmWindow* wm_window = wm::WmWindow::Get(this); |
| 142 wm_window->SetLockedToRoot(true); |
| 155 opaque_background_.SetColor(SK_ColorBLACK); | 143 opaque_background_.SetColor(SK_ColorBLACK); |
| 156 opaque_background_.SetBounds(gfx::Rect(GetWindowBoundsInScreen().size())); | 144 opaque_background_.SetBounds(gfx::Rect(GetWindowBoundsInScreen().size())); |
| 157 opaque_background_.SetOpacity(0.0f); | 145 opaque_background_.SetOpacity(0.0f); |
| 158 GetNativeWindow()->layer()->Add(&opaque_background_); | 146 wm_window->GetLayer()->Add(&opaque_background_); |
| 159 | 147 |
| 160 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 148 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 161 gfx::ImageSkia shelf_background = | 149 gfx::ImageSkia shelf_background = |
| 162 *rb.GetImageSkiaNamed(IDR_ASH_SHELF_BACKGROUND); | 150 *rb.GetImageSkiaNamed(IDR_ASH_SHELF_BACKGROUND); |
| 163 shelf_background_left_ = gfx::ImageSkiaOperations::CreateRotatedImage( | 151 shelf_background_left_ = gfx::ImageSkiaOperations::CreateRotatedImage( |
| 164 shelf_background, SkBitmapOperations::ROTATION_90_CW); | 152 shelf_background, SkBitmapOperations::ROTATION_90_CW); |
| 165 shelf_background_right_ = gfx::ImageSkiaOperations::CreateRotatedImage( | 153 shelf_background_right_ = gfx::ImageSkiaOperations::CreateRotatedImage( |
| 166 shelf_background, SkBitmapOperations::ROTATION_270_CW); | 154 shelf_background, SkBitmapOperations::ROTATION_270_CW); |
| 167 | 155 |
| 168 // This background should be explicitly stacked below any windows already in | 156 // This background should be explicitly stacked below any windows already in |
| 169 // the dock, otherwise the z-order is set by the order in which windows were | 157 // the dock, otherwise the z-order is set by the order in which windows were |
| 170 // added to the container, and UpdateStacking only manages user windows, not | 158 // added to the container, and UpdateStacking only manages user windows, not |
| 171 // the background widget. | 159 // the background widget. |
| 172 parent->StackChildAtBottom(wm::WmWindow::Get(this)); | 160 parent->StackChildAtBottom(wm_window); |
| 173 } | 161 } |
| 174 | 162 |
| 175 // Transitions to |visible_background_type_| if the widget is visible and to | 163 // Transitions to |visible_background_type_| if the widget is visible and to |
| 176 // SHELF_BACKGROUND_DEFAULT if it is not. | 164 // SHELF_BACKGROUND_DEFAULT if it is not. |
| 177 void UpdateBackground() { | 165 void UpdateBackground() { |
| 178 ShelfBackgroundType background_type = IsVisible() ? | 166 ShelfBackgroundType background_type = IsVisible() ? |
| 179 visible_background_type_ : SHELF_BACKGROUND_DEFAULT; | 167 visible_background_type_ : SHELF_BACKGROUND_DEFAULT; |
| 180 BackgroundAnimatorChangeType change_type = IsVisible() ? | 168 BackgroundAnimatorChangeType change_type = IsVisible() ? |
| 181 visible_background_change_type_ : BACKGROUND_CHANGE_IMMEDIATE; | 169 visible_background_change_type_ : BACKGROUND_CHANGE_IMMEDIATE; |
| 182 | 170 |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 | 401 |
| 414 DISALLOW_COPY_AND_ASSIGN(ShelfWindowObserver); | 402 DISALLOW_COPY_AND_ASSIGN(ShelfWindowObserver); |
| 415 }; | 403 }; |
| 416 | 404 |
| 417 //////////////////////////////////////////////////////////////////////////////// | 405 //////////////////////////////////////////////////////////////////////////////// |
| 418 // DockedWindowLayoutManager public implementation: | 406 // DockedWindowLayoutManager public implementation: |
| 419 DockedWindowLayoutManager::DockedWindowLayoutManager( | 407 DockedWindowLayoutManager::DockedWindowLayoutManager( |
| 420 wm::WmWindow* dock_container, | 408 wm::WmWindow* dock_container, |
| 421 WorkspaceController* workspace_controller) | 409 WorkspaceController* workspace_controller) |
| 422 : dock_container_(dock_container), | 410 : dock_container_(dock_container), |
| 411 root_window_controller_(dock_container->GetRootWindowController()), |
| 423 in_layout_(false), | 412 in_layout_(false), |
| 424 dragged_window_(nullptr), | 413 dragged_window_(nullptr), |
| 425 is_dragged_window_docked_(false), | 414 is_dragged_window_docked_(false), |
| 426 is_dragged_from_dock_(false), | 415 is_dragged_from_dock_(false), |
| 427 shelf_(nullptr), | 416 shelf_(nullptr), |
| 428 workspace_controller_(workspace_controller), | 417 workspace_controller_(workspace_controller), |
| 429 in_fullscreen_(workspace_controller_->GetWindowState() == | 418 in_fullscreen_(workspace_controller_->GetWindowState() == |
| 430 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN), | 419 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN), |
| 431 docked_width_(0), | 420 docked_width_(0), |
| 432 alignment_(DOCKED_ALIGNMENT_NONE), | 421 alignment_(DOCKED_ALIGNMENT_NONE), |
| 433 preferred_alignment_(DOCKED_ALIGNMENT_NONE), | 422 preferred_alignment_(DOCKED_ALIGNMENT_NONE), |
| 434 event_source_(DOCKED_ACTION_SOURCE_UNKNOWN), | 423 event_source_(DOCKED_ACTION_SOURCE_UNKNOWN), |
| 435 last_active_window_(nullptr), | 424 last_active_window_(nullptr), |
| 436 last_action_time_(base::Time::Now()), | 425 last_action_time_(base::Time::Now()), |
| 437 background_widget_(nullptr) { | 426 background_widget_(nullptr) { |
| 438 DCHECK(dock_container); | 427 DCHECK(dock_container); |
| 439 dock_container->GetGlobals()->AddActivationObserver(this); | 428 dock_container->GetGlobals()->AddActivationObserver(this); |
| 440 Shell::GetInstance()->AddShellObserver(this); | 429 root_window_controller_->AddObserver(this); |
| 441 } | 430 } |
| 442 | 431 |
| 443 DockedWindowLayoutManager::~DockedWindowLayoutManager() { | 432 DockedWindowLayoutManager::~DockedWindowLayoutManager() { |
| 444 Shutdown(); | 433 Shutdown(); |
| 445 } | 434 } |
| 446 | 435 |
| 447 // static | 436 // static |
| 448 DockedWindowLayoutManager* DockedWindowLayoutManager::Get( | 437 DockedWindowLayoutManager* DockedWindowLayoutManager::Get( |
| 449 wm::WmWindow* window) { | 438 wm::WmWindow* window) { |
| 450 if (!window) | 439 if (!window) |
| 451 return nullptr; | 440 return nullptr; |
| 452 | 441 |
| 453 wm::WmWindow* root = window->GetRootWindow(); | 442 wm::WmWindow* root = window->GetRootWindow(); |
| 454 return static_cast<DockedWindowLayoutManager*>( | 443 return static_cast<DockedWindowLayoutManager*>( |
| 455 root->GetChildByShellWindowId(kShellWindowId_DockedContainer) | 444 root->GetChildByShellWindowId(kShellWindowId_DockedContainer) |
| 456 ->GetLayoutManager()); | 445 ->GetLayoutManager()); |
| 457 } | 446 } |
| 458 | 447 |
| 459 void DockedWindowLayoutManager::Shutdown() { | 448 void DockedWindowLayoutManager::Shutdown() { |
| 460 background_widget_.reset(); | 449 background_widget_.reset(); |
| 461 shelf_observer_.reset(); | 450 shelf_observer_.reset(); |
| 462 shelf_ = nullptr; | 451 shelf_ = nullptr; |
| 463 for (wm::WmWindow* child : dock_container_->GetChildren()) { | 452 for (wm::WmWindow* child : dock_container_->GetChildren()) { |
| 464 child->RemoveObserver(this); | 453 child->RemoveObserver(this); |
| 465 child->GetWindowState()->RemoveObserver(this); | 454 child->GetWindowState()->RemoveObserver(this); |
| 466 } | 455 } |
| 467 dock_container_->GetGlobals()->RemoveActivationObserver(this); | 456 dock_container_->GetGlobals()->RemoveActivationObserver(this); |
| 468 Shell::GetInstance()->RemoveShellObserver(this); | 457 root_window_controller_->RemoveObserver(this); |
| 469 } | 458 } |
| 470 | 459 |
| 471 void DockedWindowLayoutManager::AddObserver( | 460 void DockedWindowLayoutManager::AddObserver( |
| 472 DockedWindowLayoutManagerObserver* observer) { | 461 DockedWindowLayoutManagerObserver* observer) { |
| 473 observer_list_.AddObserver(observer); | 462 observer_list_.AddObserver(observer); |
| 474 } | 463 } |
| 475 | 464 |
| 476 void DockedWindowLayoutManager::RemoveObserver( | 465 void DockedWindowLayoutManager::RemoveObserver( |
| 477 DockedWindowLayoutManagerObserver* observer) { | 466 DockedWindowLayoutManagerObserver* observer) { |
| 478 observer_list_.RemoveObserver(observer); | 467 observer_list_.RemoveObserver(observer); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 return; | 762 return; |
| 774 // Whenever one of our windows is moved or resized enforce layout. | 763 // Whenever one of our windows is moved or resized enforce layout. |
| 775 ShelfLayoutManager* shelf_layout = shelf_->shelf_layout_manager(); | 764 ShelfLayoutManager* shelf_layout = shelf_->shelf_layout_manager(); |
| 776 if (shelf_layout) | 765 if (shelf_layout) |
| 777 shelf_layout->UpdateVisibilityState(); | 766 shelf_layout->UpdateVisibilityState(); |
| 778 } | 767 } |
| 779 | 768 |
| 780 //////////////////////////////////////////////////////////////////////////////// | 769 //////////////////////////////////////////////////////////////////////////////// |
| 781 // DockedWindowLayoutManager, ash::ShellObserver implementation: | 770 // DockedWindowLayoutManager, ash::ShellObserver implementation: |
| 782 | 771 |
| 783 void DockedWindowLayoutManager::OnDisplayWorkAreaInsetsChanged() { | 772 void DockedWindowLayoutManager::OnWorkAreaChanged() { |
| 784 Relayout(); | 773 Relayout(); |
| 785 UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_INSETS_CHANGED); | 774 UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_INSETS_CHANGED); |
| 786 MaybeMinimizeChildrenExcept(dragged_window_); | 775 MaybeMinimizeChildrenExcept(dragged_window_); |
| 787 } | 776 } |
| 788 | 777 |
| 789 void DockedWindowLayoutManager::OnFullscreenStateChanged( | 778 void DockedWindowLayoutManager::OnFullscreenStateChanged(bool is_fullscreen) { |
| 790 bool is_fullscreen, aura::Window* root_window) { | |
| 791 if (dock_container_->GetRootWindow() != wm::WmWindowAura::Get(root_window)) | |
| 792 return; | |
| 793 // Entering fullscreen mode (including immersive) hides docked windows. | 779 // Entering fullscreen mode (including immersive) hides docked windows. |
| 794 in_fullscreen_ = workspace_controller_->GetWindowState() == | 780 in_fullscreen_ = workspace_controller_->GetWindowState() == |
| 795 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN; | 781 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN; |
| 796 { | 782 { |
| 797 // prevent Relayout from getting called multiple times during this | 783 // prevent Relayout from getting called multiple times during this |
| 798 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); | 784 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); |
| 799 // Use a copy of children array because a call to MinimizeDockedWindow or | 785 // Use a copy of children array because a call to MinimizeDockedWindow or |
| 800 // RestoreDockedWindow can change order. | 786 // RestoreDockedWindow can change order. |
| 801 for (wm::WmWindow* window : dock_container_->GetChildren()) { | 787 for (wm::WmWindow* window : dock_container_->GetChildren()) { |
| 802 if (IsPopupOrTransient(window)) | 788 if (IsPopupOrTransient(window)) |
| 803 continue; | 789 continue; |
| 804 wm::WindowState* window_state = window->GetWindowState(); | 790 wm::WindowState* window_state = window->GetWindowState(); |
| 805 if (in_fullscreen_) { | 791 if (in_fullscreen_) { |
| 806 if (window->IsVisible()) | 792 if (window->IsVisible()) |
| 807 MinimizeDockedWindow(window_state); | 793 MinimizeDockedWindow(window_state); |
| 808 } else { | 794 } else { |
| 809 if (!window_state->IsMinimized()) | 795 if (!window_state->IsMinimized()) |
| 810 RestoreDockedWindow(window_state); | 796 RestoreDockedWindow(window_state); |
| 811 } | 797 } |
| 812 } | 798 } |
| 813 } | 799 } |
| 814 Relayout(); | 800 Relayout(); |
| 815 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 801 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 816 } | 802 } |
| 817 | 803 |
| 818 void DockedWindowLayoutManager::OnShelfAlignmentChanged( | 804 void DockedWindowLayoutManager::OnShelfAlignmentChanged() { |
| 819 aura::Window* root_window) { | |
| 820 if (dock_container_->GetRootWindow() != wm::WmWindowAura::Get(root_window)) | |
| 821 return; | |
| 822 | |
| 823 if (!shelf_ || alignment_ == DOCKED_ALIGNMENT_NONE) | 805 if (!shelf_ || alignment_ == DOCKED_ALIGNMENT_NONE) |
| 824 return; | 806 return; |
| 825 | 807 |
| 826 // Do not allow shelf and dock on the same side. Switch side that | 808 // Do not allow shelf and dock on the same side. Switch side that |
| 827 // the dock is attached to and move all dock windows to that new side. | 809 // the dock is attached to and move all dock windows to that new side. |
| 828 ShelfAlignment shelf_alignment = shelf_->alignment(); | 810 ShelfAlignment shelf_alignment = shelf_->alignment(); |
| 829 if (alignment_ == DOCKED_ALIGNMENT_LEFT && | 811 if (alignment_ == DOCKED_ALIGNMENT_LEFT && |
| 830 shelf_alignment == SHELF_ALIGNMENT_LEFT) { | 812 shelf_alignment == SHELF_ALIGNMENT_LEFT) { |
| 831 alignment_ = DOCKED_ALIGNMENT_RIGHT; | 813 alignment_ = DOCKED_ALIGNMENT_RIGHT; |
| 832 } else if (alignment_ == DOCKED_ALIGNMENT_RIGHT && | 814 } else if (alignment_ == DOCKED_ALIGNMENT_RIGHT && |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1354 | 1336 |
| 1355 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( | 1337 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( |
| 1356 const gfx::Rect& keyboard_bounds) { | 1338 const gfx::Rect& keyboard_bounds) { |
| 1357 // This bounds change will have caused a change to the Shelf which does not | 1339 // This bounds change will have caused a change to the Shelf which does not |
| 1358 // propagate automatically to this class, so manually recalculate bounds. | 1340 // propagate automatically to this class, so manually recalculate bounds. |
| 1359 Relayout(); | 1341 Relayout(); |
| 1360 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); | 1342 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); |
| 1361 } | 1343 } |
| 1362 | 1344 |
| 1363 } // namespace ash | 1345 } // namespace ash |
| OLD | NEW |