Chromium Code Reviews| 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" | 7 #include "ash/screen_util.h" |
| 8 #include "ash/shelf/shelf.h" | 8 #include "ash/shelf/shelf.h" |
| 9 #include "ash/shelf/shelf_constants.h" | 9 #include "ash/shelf/shelf_constants.h" |
| 10 #include "ash/shelf/shelf_layout_manager.h" | 10 #include "ash/shelf/shelf_layout_manager.h" |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 569 bounds.right() > container_bounds.x()) { | 569 bounds.right() > container_bounds.x()) { |
| 570 return DOCKED_ALIGNMENT_LEFT; | 570 return DOCKED_ALIGNMENT_LEFT; |
| 571 } else if (bounds.x() < container_bounds.right() && | 571 } else if (bounds.x() < container_bounds.right() && |
| 572 bounds.right() >= container_bounds.right()) { | 572 bounds.right() >= container_bounds.right()) { |
| 573 return DOCKED_ALIGNMENT_RIGHT; | 573 return DOCKED_ALIGNMENT_RIGHT; |
| 574 } | 574 } |
| 575 return DOCKED_ALIGNMENT_NONE; | 575 return DOCKED_ALIGNMENT_NONE; |
| 576 } | 576 } |
| 577 | 577 |
| 578 DockedAlignment DockedWindowLayoutManager::CalculateAlignment() const { | 578 DockedAlignment DockedWindowLayoutManager::CalculateAlignment() const { |
| 579 // Find a child that is not being dragged and is not a popup. | 579 return CalculateAlignmentExcept(dragged_window_); |
| 580 } | |
| 581 | |
| 582 DockedAlignment DockedWindowLayoutManager::CalculateAlignmentExcept( | |
| 583 const aura::Window* window) const { | |
| 584 // Find a child that is not the window being queried and is not a popup. | |
| 580 // If such exists the current alignment is returned - even if some of the | 585 // If such exists the current alignment is returned - even if some of the |
| 581 // children are hidden or minimized (so they can be restored without losing | 586 // children are hidden or minimized (so they can be restored without losing |
| 582 // the docked state). | 587 // the docked state). |
| 583 for (size_t i = 0; i < dock_container_->children().size(); ++i) { | 588 for (size_t i = 0; i < dock_container_->children().size(); ++i) { |
| 584 aura::Window* window(dock_container_->children()[i]); | 589 aura::Window* child(dock_container_->children()[i]); |
| 585 if (window != dragged_window_ && !IsPopupOrTransient(window)) | 590 if (window != child && !IsPopupOrTransient(child)) |
| 586 return alignment_; | 591 return alignment_; |
| 587 } | 592 } |
| 588 // No docked windows remain other than possibly the window being dragged. | 593 // No docked windows remain other than possibly the window being queried. |
| 589 // Return |NONE| to indicate that windows may get docked on either side. | 594 // Return |NONE| to indicate that windows may get docked on either side. |
| 590 return DOCKED_ALIGNMENT_NONE; | 595 return DOCKED_ALIGNMENT_NONE; |
| 591 } | 596 } |
| 592 | 597 |
| 593 bool DockedWindowLayoutManager::CanDockWindow( | 598 bool DockedWindowLayoutManager::CanDockWindow( |
| 594 aura::Window* window, | 599 aura::Window* window, |
| 595 DockedAlignment desired_alignment) { | 600 DockedAlignment desired_alignment) { |
| 596 // Don't allow interactive docking of windows with transient parents such as | 601 // Don't allow interactive docking of windows with transient parents such as |
| 597 // modal browser dialogs. Prevent docking of panels attached to shelf during | 602 // modal browser dialogs. Prevent docking of panels attached to shelf during |
| 598 // the drag. | 603 // the drag. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 613 window->delegate()->GetMinimumSize().width() > kMaxDockWidth))) { | 618 window->delegate()->GetMinimumSize().width() > kMaxDockWidth))) { |
| 614 return false; | 619 return false; |
| 615 } | 620 } |
| 616 // If a window is tall and cannot be resized down to maximum height allowed | 621 // If a window is tall and cannot be resized down to maximum height allowed |
| 617 // then it cannot be docked. | 622 // then it cannot be docked. |
| 618 const gfx::Rect work_area = | 623 const gfx::Rect work_area = |
| 619 Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); | 624 Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); |
| 620 if (GetWindowHeightCloseTo(window, work_area.height()) > work_area.height()) | 625 if (GetWindowHeightCloseTo(window, work_area.height()) > work_area.height()) |
| 621 return false; | 626 return false; |
| 622 // Cannot dock on the other size from an existing dock. | 627 // Cannot dock on the other size from an existing dock. |
| 623 const DockedAlignment alignment = CalculateAlignment(); | 628 const DockedAlignment alignment = CalculateAlignmentExcept(window); |
| 624 if (desired_alignment != DOCKED_ALIGNMENT_NONE && | 629 if (desired_alignment != DOCKED_ALIGNMENT_NONE && |
| 625 alignment != DOCKED_ALIGNMENT_NONE && | 630 alignment != DOCKED_ALIGNMENT_NONE && |
| 626 alignment != desired_alignment) { | 631 alignment != desired_alignment) { |
| 627 return false; | 632 return false; |
| 628 } | 633 } |
| 629 // Do not allow docking on the same side as shelf. | 634 // Do not allow docking on the same side as shelf. |
| 635 return IsDockedAlignmentValid(desired_alignment); | |
| 636 } | |
| 637 | |
| 638 bool DockedWindowLayoutManager::IsDockedAlignmentValid( | |
| 639 DockedAlignment alignment) const { | |
| 630 ShelfAlignment shelf_alignment = SHELF_ALIGNMENT_BOTTOM; | 640 ShelfAlignment shelf_alignment = SHELF_ALIGNMENT_BOTTOM; |
|
oshima
2014/10/01 23:48:57
nit:
could you please change to
shelf_alignment =
dtapuska
2014/10/02 21:05:28
Done.
| |
| 631 if (shelf_) | 641 if (shelf_) |
| 632 shelf_alignment = shelf_->alignment(); | 642 shelf_alignment = shelf_->alignment(); |
| 633 if ((desired_alignment == DOCKED_ALIGNMENT_LEFT && | 643 if ((alignment == DOCKED_ALIGNMENT_LEFT && |
| 634 shelf_alignment == SHELF_ALIGNMENT_LEFT) || | 644 shelf_alignment == SHELF_ALIGNMENT_LEFT) || |
| 635 (desired_alignment == DOCKED_ALIGNMENT_RIGHT && | 645 (alignment == DOCKED_ALIGNMENT_RIGHT && |
| 636 shelf_alignment == SHELF_ALIGNMENT_RIGHT)) { | 646 shelf_alignment == SHELF_ALIGNMENT_RIGHT)) { |
| 637 return false; | 647 return false; |
| 638 } | 648 } |
| 639 return true; | 649 return true; |
| 640 } | 650 } |
| 641 | 651 |
| 652 void DockedWindowLayoutManager::MaybeSetDesiredDockedAlignment( | |
| 653 DockedAlignment alignment) { | |
| 654 // If the requested alignment is |NONE| or there are no | |
| 655 // docked windows return early as we can't change whether there is a | |
| 656 // dock or not. If the requested alignment is the same as the current | |
| 657 // alignment return early as an optimization. | |
| 658 if (alignment == DOCKED_ALIGNMENT_NONE || | |
| 659 alignment_ == DOCKED_ALIGNMENT_NONE || | |
| 660 alignment_ == alignment || | |
| 661 !IsDockedAlignmentValid(alignment)) { | |
| 662 return; | |
| 663 } | |
| 664 alignment_ = alignment; | |
| 665 | |
| 666 Relayout(); | |
| 667 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | |
| 668 } | |
| 669 | |
| 642 void DockedWindowLayoutManager::OnShelfBoundsChanged() { | 670 void DockedWindowLayoutManager::OnShelfBoundsChanged() { |
| 643 Relayout(); | 671 Relayout(); |
| 644 UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_INSETS_CHANGED); | 672 UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_INSETS_CHANGED); |
| 645 } | 673 } |
| 646 | 674 |
| 647 //////////////////////////////////////////////////////////////////////////////// | 675 //////////////////////////////////////////////////////////////////////////////// |
| 648 // DockedWindowLayoutManager, aura::LayoutManager implementation: | 676 // DockedWindowLayoutManager, aura::LayoutManager implementation: |
| 649 void DockedWindowLayoutManager::OnWindowResized() { | 677 void DockedWindowLayoutManager::OnWindowResized() { |
| 650 MaybeMinimizeChildrenExcept(dragged_window_); | 678 MaybeMinimizeChildrenExcept(dragged_window_); |
| 651 Relayout(); | 679 Relayout(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 693 wm::GetWindowState(child)->RemoveObserver(this); | 721 wm::GetWindowState(child)->RemoveObserver(this); |
| 694 Relayout(); | 722 Relayout(); |
| 695 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 723 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 696 } | 724 } |
| 697 | 725 |
| 698 void DockedWindowLayoutManager::OnChildWindowVisibilityChanged( | 726 void DockedWindowLayoutManager::OnChildWindowVisibilityChanged( |
| 699 aura::Window* child, | 727 aura::Window* child, |
| 700 bool visible) { | 728 bool visible) { |
| 701 if (IsPopupOrTransient(child)) | 729 if (IsPopupOrTransient(child)) |
| 702 return; | 730 return; |
| 703 if (visible) | 731 |
| 704 wm::GetWindowState(child)->Restore(); | 732 wm::WindowState* window_state = wm::GetWindowState(child); |
| 733 if (visible && window_state->IsMinimized()) | |
|
oshima
2014/10/01 23:48:57
in which state (other than minimized) the window c
dtapuska
2014/10/02 21:05:28
When restoring a app/panel (not a browser window);
| |
| 734 window_state->Restore(); | |
| 705 Relayout(); | 735 Relayout(); |
| 706 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 736 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 707 } | 737 } |
| 708 | 738 |
| 709 void DockedWindowLayoutManager::SetChildBounds( | 739 void DockedWindowLayoutManager::SetChildBounds( |
| 710 aura::Window* child, | 740 aura::Window* child, |
| 711 const gfx::Rect& requested_bounds) { | 741 const gfx::Rect& requested_bounds) { |
| 712 // The minimum constraints have to be applied first by the layout manager. | 742 // The minimum constraints have to be applied first by the layout manager. |
| 713 gfx::Rect actual_new_bounds(requested_bounds); | 743 gfx::Rect actual_new_bounds(requested_bounds); |
| 714 if (child->delegate()) { | 744 if (child->delegate()) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 808 void DockedWindowLayoutManager::OnPreWindowStateTypeChange( | 838 void DockedWindowLayoutManager::OnPreWindowStateTypeChange( |
| 809 wm::WindowState* window_state, | 839 wm::WindowState* window_state, |
| 810 wm::WindowStateType old_type) { | 840 wm::WindowStateType old_type) { |
| 811 aura::Window* window = window_state->window(); | 841 aura::Window* window = window_state->window(); |
| 812 if (IsPopupOrTransient(window)) | 842 if (IsPopupOrTransient(window)) |
| 813 return; | 843 return; |
| 814 // The window property will still be set, but no actual change will occur | 844 // The window property will still be set, but no actual change will occur |
| 815 // until OnFullscreenStateChange is called when exiting fullscreen. | 845 // until OnFullscreenStateChange is called when exiting fullscreen. |
| 816 if (in_fullscreen_) | 846 if (in_fullscreen_) |
| 817 return; | 847 return; |
| 818 if (window_state->IsMinimized()) { | 848 if (!window_state->IsDocked()) { |
| 819 MinimizeDockedWindow(window_state); | |
| 820 } else if (window_state->IsMaximizedOrFullscreen() || | |
| 821 window_state->IsSnapped()) { | |
| 822 if (window != dragged_window_) { | 849 if (window != dragged_window_) { |
| 823 UndockWindow(window); | 850 UndockWindow(window); |
| 824 RecordUmaAction(DOCKED_ACTION_MAXIMIZE, DOCKED_ACTION_SOURCE_UNKNOWN); | 851 if (window_state->IsMaximizedOrFullscreen()) |
| 852 RecordUmaAction(DOCKED_ACTION_MAXIMIZE, DOCKED_ACTION_SOURCE_UNKNOWN); | |
|
varkha
2014/10/01 20:33:14
Should probably record some other action in UMA (p
dtapuska
2014/10/03 15:45:17
Done.
| |
| 825 } | 853 } |
| 826 } else if (old_type == wm::WINDOW_STATE_TYPE_MINIMIZED) { | 854 } else if (window_state->IsMinimized()) { |
| 855 MinimizeDockedWindow(window_state); | |
| 856 } else if (old_type == wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED) { | |
| 827 RestoreDockedWindow(window_state); | 857 RestoreDockedWindow(window_state); |
| 828 } | 858 } |
| 829 } | 859 } |
| 830 | 860 |
| 831 ///////////////////////////////////////////////////////////////////////////// | 861 ///////////////////////////////////////////////////////////////////////////// |
| 832 // DockedWindowLayoutManager, WindowObserver implementation: | 862 // DockedWindowLayoutManager, WindowObserver implementation: |
| 833 | 863 |
| 834 void DockedWindowLayoutManager::OnWindowBoundsChanged( | 864 void DockedWindowLayoutManager::OnWindowBoundsChanged( |
| 835 aura::Window* window, | 865 aura::Window* window, |
| 836 const gfx::Rect& old_bounds, | 866 const gfx::Rect& old_bounds, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 939 DCHECK(!IsPopupOrTransient(window)); | 969 DCHECK(!IsPopupOrTransient(window)); |
| 940 // Always place restored window at the bottom shuffling the other windows up. | 970 // Always place restored window at the bottom shuffling the other windows up. |
| 941 // TODO(varkha): add a separate container for docked windows to keep track | 971 // TODO(varkha): add a separate container for docked windows to keep track |
| 942 // of ordering. | 972 // of ordering. |
| 943 gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow( | 973 gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow( |
| 944 dock_container_); | 974 dock_container_); |
| 945 const gfx::Rect work_area = display.work_area(); | 975 const gfx::Rect work_area = display.work_area(); |
| 946 | 976 |
| 947 // Evict the window if it can no longer be docked because of its height. | 977 // Evict the window if it can no longer be docked because of its height. |
| 948 if (!CanDockWindow(window, DOCKED_ALIGNMENT_NONE)) { | 978 if (!CanDockWindow(window, DOCKED_ALIGNMENT_NONE)) { |
| 949 UndockWindow(window); | 979 window_state->Restore(); |
| 950 RecordUmaAction(DOCKED_ACTION_EVICT, DOCKED_ACTION_SOURCE_UNKNOWN); | 980 RecordUmaAction(DOCKED_ACTION_EVICT, DOCKED_ACTION_SOURCE_UNKNOWN); |
| 951 return; | 981 return; |
| 952 } | 982 } |
| 953 gfx::Rect bounds(window->bounds()); | 983 gfx::Rect bounds(window->bounds()); |
| 954 bounds.set_y(work_area.bottom()); | 984 bounds.set_y(work_area.bottom()); |
| 955 window->SetBounds(bounds); | 985 window->SetBounds(bounds); |
| 956 window->Show(); | 986 window->Show(); |
| 957 MaybeMinimizeChildrenExcept(window); | 987 MaybeMinimizeChildrenExcept(window); |
| 958 RecordUmaAction(DOCKED_ACTION_RESTORE, DOCKED_ACTION_SOURCE_UNKNOWN); | 988 RecordUmaAction(DOCKED_ACTION_RESTORE, DOCKED_ACTION_SOURCE_UNKNOWN); |
| 959 } | 989 } |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1320 | 1350 |
| 1321 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( | 1351 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( |
| 1322 const gfx::Rect& keyboard_bounds) { | 1352 const gfx::Rect& keyboard_bounds) { |
| 1323 // This bounds change will have caused a change to the Shelf which does not | 1353 // This bounds change will have caused a change to the Shelf which does not |
| 1324 // propagate automatically to this class, so manually recalculate bounds. | 1354 // propagate automatically to this class, so manually recalculate bounds. |
| 1325 Relayout(); | 1355 Relayout(); |
| 1326 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); | 1356 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); |
| 1327 } | 1357 } |
| 1328 | 1358 |
| 1329 } // namespace ash | 1359 } // namespace ash |
| OLD | NEW |