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/ash_switches.h" | 7 #include "ash/ash_switches.h" |
8 #include "ash/launcher/launcher.h" | 8 #include "ash/launcher/launcher.h" |
9 #include "ash/screen_ash.h" | 9 #include "ash/screen_ash.h" |
10 #include "ash/shelf/shelf_layout_manager.h" | 10 #include "ash/shelf/shelf_layout_manager.h" |
11 #include "ash/shelf/shelf_types.h" | 11 #include "ash/shelf/shelf_types.h" |
12 #include "ash/shelf/shelf_widget.h" | 12 #include "ash/shelf/shelf_widget.h" |
13 #include "ash/shell.h" | 13 #include "ash/shell.h" |
14 #include "ash/shell_window_ids.h" | 14 #include "ash/shell_window_ids.h" |
15 #include "ash/wm/coordinate_conversion.h" | 15 #include "ash/wm/coordinate_conversion.h" |
16 #include "ash/wm/window_animations.h" | 16 #include "ash/wm/window_animations.h" |
17 #include "ash/wm/window_properties.h" | 17 #include "ash/wm/window_properties.h" |
18 #include "ash/wm/window_state.h" | 18 #include "ash/wm/window_state.h" |
19 #include "ash/wm/window_util.h" | 19 #include "ash/wm/window_util.h" |
20 #include "ash/wm/workspace_controller.h" | 20 #include "ash/wm/workspace_controller.h" |
21 #include "base/auto_reset.h" | 21 #include "base/auto_reset.h" |
22 #include "base/command_line.h" | 22 #include "base/command_line.h" |
23 #include "base/metrics/histogram.h" | |
23 #include "third_party/skia/include/core/SkColor.h" | 24 #include "third_party/skia/include/core/SkColor.h" |
24 #include "ui/aura/client/activation_client.h" | 25 #include "ui/aura/client/activation_client.h" |
25 #include "ui/aura/client/focus_client.h" | 26 #include "ui/aura/client/focus_client.h" |
26 #include "ui/aura/client/window_tree_client.h" | 27 #include "ui/aura/client/window_tree_client.h" |
27 #include "ui/aura/root_window.h" | 28 #include "ui/aura/root_window.h" |
28 #include "ui/aura/window.h" | 29 #include "ui/aura/window.h" |
29 #include "ui/aura/window_delegate.h" | 30 #include "ui/aura/window_delegate.h" |
30 #include "ui/compositor/scoped_layer_animation_settings.h" | 31 #include "ui/compositor/scoped_layer_animation_settings.h" |
31 #include "ui/gfx/rect.h" | 32 #include "ui/gfx/rect.h" |
32 | 33 |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
241 dragged_window_(NULL), | 242 dragged_window_(NULL), |
242 is_dragged_window_docked_(false), | 243 is_dragged_window_docked_(false), |
243 is_dragged_from_dock_(false), | 244 is_dragged_from_dock_(false), |
244 launcher_(NULL), | 245 launcher_(NULL), |
245 workspace_controller_(workspace_controller), | 246 workspace_controller_(workspace_controller), |
246 in_fullscreen_(workspace_controller_->GetWindowState() == | 247 in_fullscreen_(workspace_controller_->GetWindowState() == |
247 WORKSPACE_WINDOW_STATE_FULL_SCREEN), | 248 WORKSPACE_WINDOW_STATE_FULL_SCREEN), |
248 docked_width_(0), | 249 docked_width_(0), |
249 alignment_(DOCKED_ALIGNMENT_NONE), | 250 alignment_(DOCKED_ALIGNMENT_NONE), |
250 last_active_window_(NULL), | 251 last_active_window_(NULL), |
252 previous_docked_windows_(0), | |
251 background_widget_(new DockedBackgroundWidget(dock_container_)) { | 253 background_widget_(new DockedBackgroundWidget(dock_container_)) { |
252 DCHECK(dock_container); | 254 DCHECK(dock_container); |
253 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> | 255 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> |
254 AddObserver(this); | 256 AddObserver(this); |
255 Shell::GetInstance()->AddShellObserver(this); | 257 Shell::GetInstance()->AddShellObserver(this); |
256 } | 258 } |
257 | 259 |
258 DockedWindowLayoutManager::~DockedWindowLayoutManager() { | 260 DockedWindowLayoutManager::~DockedWindowLayoutManager() { |
259 Shutdown(); | 261 Shutdown(); |
260 } | 262 } |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
457 if (IsPopupOrTransient(child)) | 459 if (IsPopupOrTransient(child)) |
458 return; | 460 return; |
459 // Dragged windows are stopped being observed by FinishDragging and do not | 461 // Dragged windows are stopped being observed by FinishDragging and do not |
460 // change alignment during the drag. They also cannot be set to be the | 462 // change alignment during the drag. They also cannot be set to be the |
461 // |last_active_window_|. | 463 // |last_active_window_|. |
462 if (child == dragged_window_) | 464 if (child == dragged_window_) |
463 return; | 465 return; |
464 // If this is the last window, set alignment and maximize the workspace. | 466 // If this is the last window, set alignment and maximize the workspace. |
465 if (!IsAnyWindowDocked()) { | 467 if (!IsAnyWindowDocked()) { |
466 alignment_ = DOCKED_ALIGNMENT_NONE; | 468 alignment_ = DOCKED_ALIGNMENT_NONE; |
469 int previous_docked_width = docked_width_; | |
467 docked_width_ = 0; | 470 docked_width_ = 0; |
471 if (docked_width_ != previous_docked_width) | |
472 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.Dock.Width", docked_width_, 0, 360, 72); | |
flackr
2013/10/29 21:33:49
Create a common method for updating and/or trackin
varkha
2013/10/30 19:21:00
Done.
| |
468 } | 473 } |
469 if (last_active_window_ == child) | 474 if (last_active_window_ == child) |
470 last_active_window_ = NULL; | 475 last_active_window_ = NULL; |
471 child->RemoveObserver(this); | 476 child->RemoveObserver(this); |
472 wm::GetWindowState(child)->RemoveObserver(this); | 477 wm::GetWindowState(child)->RemoveObserver(this); |
473 Relayout(); | 478 Relayout(); |
474 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 479 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
475 } | 480 } |
476 | 481 |
477 void DockedWindowLayoutManager::OnChildWindowVisibilityChanged( | 482 void DockedWindowLayoutManager::OnChildWindowVisibilityChanged( |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
570 // The window property will still be set, but no actual change will occur | 575 // The window property will still be set, but no actual change will occur |
571 // until OnFullscreenStateChange is called when exiting fullscreen. | 576 // until OnFullscreenStateChange is called when exiting fullscreen. |
572 if (in_fullscreen_) | 577 if (in_fullscreen_) |
573 return; | 578 return; |
574 if (window_state->IsMinimized()) { | 579 if (window_state->IsMinimized()) { |
575 MinimizeDockedWindow(window_state); | 580 MinimizeDockedWindow(window_state); |
576 } else if (window_state->IsMaximizedOrFullscreen()) { | 581 } else if (window_state->IsMaximizedOrFullscreen()) { |
577 // Reparenting changes the source bounds for the animation if a window is | 582 // Reparenting changes the source bounds for the animation if a window is |
578 // visible so hide it here and show later when it is already in the desktop. | 583 // visible so hide it here and show later when it is already in the desktop. |
579 UndockWindow(window); | 584 UndockWindow(window); |
585 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.Actions", | |
586 DOCKED_ACTION_MAXIMIZE, DOCKED_ACTION_COUNT); | |
580 } else { | 587 } else { |
581 RestoreDockedWindow(window_state); | 588 RestoreDockedWindow(window_state); |
582 } | 589 } |
583 } | 590 } |
584 | 591 |
585 ///////////////////////////////////////////////////////////////////////////// | 592 ///////////////////////////////////////////////////////////////////////////// |
586 // DockLayoutManager, WindowObserver implementation: | 593 // DockLayoutManager, WindowObserver implementation: |
587 | 594 |
588 void DockedWindowLayoutManager::OnWindowBoundsChanged( | 595 void DockedWindowLayoutManager::OnWindowBoundsChanged( |
589 aura::Window* window, | 596 aura::Window* window, |
(...skipping 18 matching lines...) Expand all Loading... | |
608 } | 615 } |
609 | 616 |
610 void DockedWindowLayoutManager::OnWindowDestroying(aura::Window* window) { | 617 void DockedWindowLayoutManager::OnWindowDestroying(aura::Window* window) { |
611 if (dragged_window_ == window) { | 618 if (dragged_window_ == window) { |
612 FinishDragging(); | 619 FinishDragging(); |
613 DCHECK(!dragged_window_); | 620 DCHECK(!dragged_window_); |
614 DCHECK (!is_dragged_window_docked_); | 621 DCHECK (!is_dragged_window_docked_); |
615 } | 622 } |
616 if (window == last_active_window_) | 623 if (window == last_active_window_) |
617 last_active_window_ = NULL; | 624 last_active_window_ = NULL; |
625 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.Actions", | |
626 DOCKED_ACTION_CLOSE, DOCKED_ACTION_COUNT); | |
618 } | 627 } |
619 | 628 |
620 | 629 |
621 //////////////////////////////////////////////////////////////////////////////// | 630 //////////////////////////////////////////////////////////////////////////////// |
622 // DockLayoutManager, aura::client::ActivationChangeObserver implementation: | 631 // DockLayoutManager, aura::client::ActivationChangeObserver implementation: |
623 | 632 |
624 void DockedWindowLayoutManager::OnWindowActivated(aura::Window* gained_active, | 633 void DockedWindowLayoutManager::OnWindowActivated(aura::Window* gained_active, |
625 aura::Window* lost_active) { | 634 aura::Window* lost_active) { |
626 if (gained_active && IsPopupOrTransient(gained_active)) | 635 if (gained_active && IsPopupOrTransient(gained_active)) |
627 return; | 636 return; |
(...skipping 17 matching lines...) Expand all Loading... | |
645 aura::Window* child) { | 654 aura::Window* child) { |
646 // Minimize any windows that don't fit without overlap. | 655 // Minimize any windows that don't fit without overlap. |
647 const gfx::Rect work_area = | 656 const gfx::Rect work_area = |
648 Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); | 657 Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); |
649 int available_room = work_area.height() - kMinDockGap; | 658 int available_room = work_area.height() - kMinDockGap; |
650 if (child) | 659 if (child) |
651 available_room -= (GetWindowHeightCloseTo(child, 0) + kMinDockGap); | 660 available_room -= (GetWindowHeightCloseTo(child, 0) + kMinDockGap); |
652 // Use a copy of children array because a call to Minimize can change order. | 661 // Use a copy of children array because a call to Minimize can change order. |
653 aura::Window::Windows children(dock_container_->children()); | 662 aura::Window::Windows children(dock_container_->children()); |
654 aura::Window::Windows::const_reverse_iterator iter = children.rbegin(); | 663 aura::Window::Windows::const_reverse_iterator iter = children.rbegin(); |
664 int docked_windows = child ? 1 : 0; | |
655 while (iter != children.rend()) { | 665 while (iter != children.rend()) { |
656 aura::Window* window(*iter++); | 666 aura::Window* window(*iter++); |
657 if (window == child || !IsUsedByLayout(window)) | 667 if (window == child || !IsUsedByLayout(window)) |
658 continue; | 668 continue; |
659 int room_needed = GetWindowHeightCloseTo(window, 0) + kMinDockGap; | 669 int room_needed = GetWindowHeightCloseTo(window, 0) + kMinDockGap; |
660 if (available_room > room_needed) | 670 if (available_room > room_needed) { |
661 available_room -= room_needed; | 671 available_room -= room_needed; |
662 else | 672 docked_windows++; |
663 wm::GetWindowState(window)->Minimize(); | 673 continue; |
674 } | |
675 wm::GetWindowState(window)->Minimize(); | |
664 } | 676 } |
677 if (docked_windows != previous_docked_windows_) | |
678 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.Items", docked_windows); | |
flackr
2013/10/29 21:33:49
MaybeMinimizeChildrenExcept is only called from Re
varkha
2013/10/30 19:21:00
MaybeMinimizeChildrenExcept is called from FinishD
| |
679 previous_docked_windows_ = docked_windows; | |
665 } | 680 } |
666 | 681 |
667 void DockedWindowLayoutManager::MinimizeDockedWindow( | 682 void DockedWindowLayoutManager::MinimizeDockedWindow( |
668 wm::WindowState* window_state) { | 683 wm::WindowState* window_state) { |
669 DCHECK(!IsPopupOrTransient(window_state->window())); | 684 DCHECK(!IsPopupOrTransient(window_state->window())); |
670 window_state->window()->Hide(); | 685 window_state->window()->Hide(); |
671 if (window_state->IsActive()) | 686 if (window_state->IsActive()) |
672 window_state->Deactivate(); | 687 window_state->Deactivate(); |
688 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.Actions", | |
689 DOCKED_ACTION_MINIMIZE, DOCKED_ACTION_COUNT); | |
673 } | 690 } |
674 | 691 |
675 void DockedWindowLayoutManager::RestoreDockedWindow( | 692 void DockedWindowLayoutManager::RestoreDockedWindow( |
676 wm::WindowState* window_state) { | 693 wm::WindowState* window_state) { |
677 aura::Window* window = window_state->window(); | 694 aura::Window* window = window_state->window(); |
678 DCHECK(!IsPopupOrTransient(window)); | 695 DCHECK(!IsPopupOrTransient(window)); |
679 // Always place restored window at the top shuffling the other windows down. | 696 // Always place restored window at the top shuffling the other windows down. |
680 // TODO(varkha): add a separate container for docked windows to keep track | 697 // TODO(varkha): add a separate container for docked windows to keep track |
681 // of ordering. | 698 // of ordering. |
682 gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow( | 699 gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow( |
683 dock_container_); | 700 dock_container_); |
684 const gfx::Rect work_area = display.work_area(); | 701 const gfx::Rect work_area = display.work_area(); |
685 | 702 |
686 // Evict the window if it can no longer be docked because of its height. | 703 // Evict the window if it can no longer be docked because of its height. |
687 if (!CanDockWindow(window, SNAP_NONE)) { | 704 if (!CanDockWindow(window, SNAP_NONE)) { |
688 UndockWindow(window); | 705 UndockWindow(window); |
706 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.Actions", | |
707 DOCKED_ACTION_EVICT, DOCKED_ACTION_COUNT); | |
689 return; | 708 return; |
690 } | 709 } |
691 gfx::Rect bounds(window->bounds()); | 710 gfx::Rect bounds(window->bounds()); |
692 bounds.set_y(work_area.y() - bounds.height()); | 711 bounds.set_y(work_area.y() - bounds.height()); |
693 window->SetBounds(bounds); | 712 window->SetBounds(bounds); |
694 window->Show(); | 713 window->Show(); |
695 MaybeMinimizeChildrenExcept(window); | 714 MaybeMinimizeChildrenExcept(window); |
715 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.Actions", | |
716 DOCKED_ACTION_RESTORE, DOCKED_ACTION_COUNT); | |
696 } | 717 } |
697 | 718 |
698 void DockedWindowLayoutManager::OnDraggedWindowDocked(aura::Window* window) { | 719 void DockedWindowLayoutManager::OnDraggedWindowDocked(aura::Window* window) { |
699 DCHECK(!is_dragged_window_docked_); | 720 DCHECK(!is_dragged_window_docked_); |
700 is_dragged_window_docked_ = true; | 721 is_dragged_window_docked_ = true; |
701 | 722 |
702 // If there are no other docked windows update alignment. | 723 // If there are no other docked windows update alignment. |
703 if (!IsAnyWindowDocked()) | 724 if (!IsAnyWindowDocked()) |
704 alignment_ = DOCKED_ALIGNMENT_NONE; | 725 alignment_ = DOCKED_ALIGNMENT_NONE; |
705 } | 726 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
842 | 863 |
843 // Calculate initial vertical offset and the gap or overlap between windows. | 864 // Calculate initial vertical offset and the gap or overlap between windows. |
844 const int num_windows = visible_windows->size(); | 865 const int num_windows = visible_windows->size(); |
845 const float delta = kMinDockGap + (float)available_room / | 866 const float delta = kMinDockGap + (float)available_room / |
846 ((available_room > 0 || num_windows <= 1) ? | 867 ((available_room > 0 || num_windows <= 1) ? |
847 num_windows + 1 : num_windows - 1); | 868 num_windows + 1 : num_windows - 1); |
848 float y_pos = work_area.y() + ((delta > 0) ? delta : kMinDockGap); | 869 float y_pos = work_area.y() + ((delta > 0) ? delta : kMinDockGap); |
849 | 870 |
850 // Docked area is shown only if there is at least one non-dragged visible | 871 // Docked area is shown only if there is at least one non-dragged visible |
851 // docked window. | 872 // docked window. |
873 int previous_docked_width = docked_width_; | |
852 docked_width_ = ideal_docked_width; | 874 docked_width_ = ideal_docked_width; |
853 if (visible_windows->empty() || | 875 if (visible_windows->empty() || |
854 (visible_windows->size() == 1 && | 876 (visible_windows->size() == 1 && |
855 (*visible_windows)[0].window() == dragged_window_)) { | 877 (*visible_windows)[0].window() == dragged_window_)) { |
856 docked_width_ = 0; | 878 docked_width_ = 0; |
857 } | 879 } |
858 | 880 if (docked_width_ != previous_docked_width) |
881 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.Dock.Width", docked_width_, 0, 360, 72); | |
flackr
2013/10/29 21:33:49
It might be worth setting a higher max in case we
varkha
2013/10/30 19:21:00
Done.
| |
859 // Sort windows by their center positions and fan out overlapping | 882 // Sort windows by their center positions and fan out overlapping |
860 // windows. | 883 // windows. |
861 std::sort(visible_windows->begin(), visible_windows->end(), | 884 std::sort(visible_windows->begin(), visible_windows->end(), |
862 CompareWindowPos(is_dragged_from_dock_ ? dragged_window_ : NULL, | 885 CompareWindowPos(is_dragged_from_dock_ ? dragged_window_ : NULL, |
863 delta)); | 886 delta)); |
864 for (std::vector<WindowWithHeight>::iterator iter = visible_windows->begin(); | 887 for (std::vector<WindowWithHeight>::iterator iter = visible_windows->begin(); |
865 iter != visible_windows->end(); ++iter) { | 888 iter != visible_windows->end(); ++iter) { |
866 aura::Window* window = iter->window(); | 889 aura::Window* window = iter->window(); |
867 gfx::Rect bounds = ScreenAsh::ConvertRectToScreen( | 890 gfx::Rect bounds = ScreenAsh::ConvertRectToScreen( |
868 window->parent(), window->GetTargetBounds()); | 891 window->parent(), window->GetTargetBounds()); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1014 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( | 1037 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( |
1015 const gfx::Rect& keyboard_bounds) { | 1038 const gfx::Rect& keyboard_bounds) { |
1016 // This bounds change will have caused a change to the Shelf which does not | 1039 // This bounds change will have caused a change to the Shelf which does not |
1017 // propagate automatically to this class, so manually recalculate bounds. | 1040 // propagate automatically to this class, so manually recalculate bounds. |
1018 Relayout(); | 1041 Relayout(); |
1019 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); | 1042 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); |
1020 } | 1043 } |
1021 | 1044 |
1022 } // namespace internal | 1045 } // namespace internal |
1023 } // namespace ash | 1046 } // namespace ash |
OLD | NEW |