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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 }; | 203 }; |
204 | 204 |
205 namespace { | 205 namespace { |
206 | 206 |
207 // Returns true if a window is a popup or a transient child. | 207 // Returns true if a window is a popup or a transient child. |
208 bool IsPopupOrTransient(const aura::Window* window) { | 208 bool IsPopupOrTransient(const aura::Window* window) { |
209 return (window->type() == ui::wm::WINDOW_TYPE_POPUP || | 209 return (window->type() == ui::wm::WINDOW_TYPE_POPUP || |
210 ::wm::GetTransientParent(window)); | 210 ::wm::GetTransientParent(window)); |
211 } | 211 } |
212 | 212 |
213 // Certain windows (minimized, hidden or popups) do not matter to docking. | 213 // Certain windows (minimized, hidden or popups) are not docked and are ignored |
214 bool IsUsedByLayout(const aura::Window* window) { | 214 // by layout logic even when they are children of a docked container. |
| 215 bool IsWindowDocked(const aura::Window* window) { |
215 return (window->IsVisible() && | 216 return (window->IsVisible() && |
216 !wm::GetWindowState(window)->IsMinimized() && | 217 !wm::GetWindowState(window)->IsMinimized() && |
217 !IsPopupOrTransient(window)); | 218 !IsPopupOrTransient(window)); |
218 } | 219 } |
219 | 220 |
220 void UndockWindow(aura::Window* window) { | 221 void UndockWindow(aura::Window* window) { |
221 gfx::Rect previous_bounds = window->bounds(); | 222 gfx::Rect previous_bounds = window->bounds(); |
222 aura::Window* old_parent = window->parent(); | 223 aura::Window* old_parent = window->parent(); |
223 aura::client::ParentWindowWithContext(window, window, gfx::Rect()); | 224 aura::client::ParentWindowWithContext(window, window, gfx::Rect()); |
224 if (window->parent() != old_parent) | 225 if (window->parent() != old_parent) |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 | 473 |
473 // Resize all windows that are flush with the dock edge together if one of | 474 // Resize all windows that are flush with the dock edge together if one of |
474 // them gets resized. | 475 // them gets resized. |
475 if (dragged_window_->bounds().width() == docked_width_ && | 476 if (dragged_window_->bounds().width() == docked_width_ && |
476 (dragged_state->drag_details()->bounds_change & | 477 (dragged_state->drag_details()->bounds_change & |
477 WindowResizer::kBoundsChange_Resizes) && | 478 WindowResizer::kBoundsChange_Resizes) && |
478 (dragged_state->drag_details()->size_change_direction & | 479 (dragged_state->drag_details()->size_change_direction & |
479 WindowResizer::kBoundsChangeDirection_Horizontal)) { | 480 WindowResizer::kBoundsChangeDirection_Horizontal)) { |
480 for (size_t i = 0; i < dock_container_->children().size(); ++i) { | 481 for (size_t i = 0; i < dock_container_->children().size(); ++i) { |
481 aura::Window* window1(dock_container_->children()[i]); | 482 aura::Window* window1(dock_container_->children()[i]); |
482 if (IsUsedByLayout(window1) && | 483 if (IsWindowDocked(window1) && window1 != dragged_window_ && |
483 window1 != dragged_window_ && | |
484 window1->bounds().width() == docked_width_) { | 484 window1->bounds().width() == docked_width_) { |
485 wm::GetWindowState(window1)->set_bounds_changed_by_user(false); | 485 wm::GetWindowState(window1)->set_bounds_changed_by_user(false); |
486 } | 486 } |
487 } | 487 } |
488 } | 488 } |
489 } | 489 } |
490 | 490 |
491 void DockedWindowLayoutManager::DockDraggedWindow(aura::Window* window) { | 491 void DockedWindowLayoutManager::DockDraggedWindow(aura::Window* window) { |
492 DCHECK(!IsPopupOrTransient(window)); | 492 DCHECK(!IsPopupOrTransient(window)); |
493 OnDraggedWindowDocked(window); | 493 OnDraggedWindowDocked(window); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 const gfx::Rect& requested_bounds) { | 738 const gfx::Rect& requested_bounds) { |
739 // The minimum constraints have to be applied first by the layout manager. | 739 // The minimum constraints have to be applied first by the layout manager. |
740 gfx::Rect actual_new_bounds(requested_bounds); | 740 gfx::Rect actual_new_bounds(requested_bounds); |
741 if (child->delegate()) { | 741 if (child->delegate()) { |
742 const gfx::Size& min_size = child->delegate()->GetMinimumSize(); | 742 const gfx::Size& min_size = child->delegate()->GetMinimumSize(); |
743 actual_new_bounds.set_width( | 743 actual_new_bounds.set_width( |
744 std::max(min_size.width(), actual_new_bounds.width())); | 744 std::max(min_size.width(), actual_new_bounds.width())); |
745 actual_new_bounds.set_height( | 745 actual_new_bounds.set_height( |
746 std::max(min_size.height(), actual_new_bounds.height())); | 746 std::max(min_size.height(), actual_new_bounds.height())); |
747 } | 747 } |
| 748 if (IsWindowDocked(child) && child != dragged_window_) |
| 749 return; |
748 SnapToPixelLayoutManager::SetChildBounds(child, actual_new_bounds); | 750 SnapToPixelLayoutManager::SetChildBounds(child, actual_new_bounds); |
749 if (IsPopupOrTransient(child)) | 751 if (IsPopupOrTransient(child)) |
750 return; | 752 return; |
751 // Whenever one of our windows is moved or resized enforce layout. | 753 // Whenever one of our windows is moved or resized enforce layout. |
752 ShelfLayoutManager* shelf_layout = | 754 ShelfLayoutManager* shelf_layout = |
753 ShelfLayoutManager::ForShelf(dock_container_); | 755 ShelfLayoutManager::ForShelf(dock_container_); |
754 if (shelf_layout) | 756 if (shelf_layout) |
755 shelf_layout->UpdateVisibilityState(); | 757 shelf_layout->UpdateVisibilityState(); |
756 } | 758 } |
757 | 759 |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); | 933 Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); |
932 int available_room = work_area.height(); | 934 int available_room = work_area.height(); |
933 bool gap_needed = !!child; | 935 bool gap_needed = !!child; |
934 if (child) | 936 if (child) |
935 available_room -= GetWindowHeightCloseTo(child, 0); | 937 available_room -= GetWindowHeightCloseTo(child, 0); |
936 // Use a copy of children array because a call to Minimize can change order. | 938 // Use a copy of children array because a call to Minimize can change order. |
937 aura::Window::Windows children(dock_container_->children()); | 939 aura::Window::Windows children(dock_container_->children()); |
938 aura::Window::Windows::const_reverse_iterator iter = children.rbegin(); | 940 aura::Window::Windows::const_reverse_iterator iter = children.rbegin(); |
939 while (iter != children.rend()) { | 941 while (iter != children.rend()) { |
940 aura::Window* window(*iter++); | 942 aura::Window* window(*iter++); |
941 if (window == child || !IsUsedByLayout(window)) | 943 if (window == child || !IsWindowDocked(window)) |
942 continue; | 944 continue; |
943 int room_needed = GetWindowHeightCloseTo(window, 0) + | 945 int room_needed = GetWindowHeightCloseTo(window, 0) + |
944 (gap_needed ? kMinDockGap : 0); | 946 (gap_needed ? kMinDockGap : 0); |
945 gap_needed = true; | 947 gap_needed = true; |
946 if (available_room > room_needed) { | 948 if (available_room > room_needed) { |
947 available_room -= room_needed; | 949 available_room -= room_needed; |
948 } else { | 950 } else { |
949 // Slow down minimizing animations. Lock duration so that it is not | 951 // Slow down minimizing animations. Lock duration so that it is not |
950 // overridden by other ScopedLayerAnimationSettings down the stack. | 952 // overridden by other ScopedLayerAnimationSettings down the stack. |
951 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); | 953 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 last_action_time_ = time_now; | 1010 last_action_time_ = time_now; |
1009 int docked_all_count = 0; | 1011 int docked_all_count = 0; |
1010 int docked_visible_count = 0; | 1012 int docked_visible_count = 0; |
1011 int docked_panels_count = 0; | 1013 int docked_panels_count = 0; |
1012 int large_windows_count = 0; | 1014 int large_windows_count = 0; |
1013 for (size_t i = 0; i < dock_container_->children().size(); ++i) { | 1015 for (size_t i = 0; i < dock_container_->children().size(); ++i) { |
1014 const aura::Window* window(dock_container_->children()[i]); | 1016 const aura::Window* window(dock_container_->children()[i]); |
1015 if (IsPopupOrTransient(window)) | 1017 if (IsPopupOrTransient(window)) |
1016 continue; | 1018 continue; |
1017 docked_all_count++; | 1019 docked_all_count++; |
1018 if (!IsUsedByLayout(window)) | 1020 if (!IsWindowDocked(window)) |
1019 continue; | 1021 continue; |
1020 docked_visible_count++; | 1022 docked_visible_count++; |
1021 if (window->type() == ui::wm::WINDOW_TYPE_PANEL) | 1023 if (window->type() == ui::wm::WINDOW_TYPE_PANEL) |
1022 docked_panels_count++; | 1024 docked_panels_count++; |
1023 const wm::WindowState* window_state = wm::GetWindowState(window); | 1025 const wm::WindowState* window_state = wm::GetWindowState(window); |
1024 if (window_state->HasRestoreBounds()) { | 1026 if (window_state->HasRestoreBounds()) { |
1025 const gfx::Rect restore_bounds = window_state->GetRestoreBoundsInScreen(); | 1027 const gfx::Rect restore_bounds = window_state->GetRestoreBoundsInScreen(); |
1026 if (restore_bounds.width() > kMaxDockWidth) | 1028 if (restore_bounds.width() > kMaxDockWidth) |
1027 large_windows_count++; | 1029 large_windows_count++; |
1028 } | 1030 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1069 if (alignment_ == DOCKED_ALIGNMENT_NONE && !is_dragged_window_docked_) | 1071 if (alignment_ == DOCKED_ALIGNMENT_NONE && !is_dragged_window_docked_) |
1070 return; | 1072 return; |
1071 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); | 1073 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); |
1072 | 1074 |
1073 gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen(); | 1075 gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen(); |
1074 aura::Window* active_window = NULL; | 1076 aura::Window* active_window = NULL; |
1075 std::vector<WindowWithHeight> visible_windows; | 1077 std::vector<WindowWithHeight> visible_windows; |
1076 for (size_t i = 0; i < dock_container_->children().size(); ++i) { | 1078 for (size_t i = 0; i < dock_container_->children().size(); ++i) { |
1077 aura::Window* window(dock_container_->children()[i]); | 1079 aura::Window* window(dock_container_->children()[i]); |
1078 | 1080 |
1079 if (!IsUsedByLayout(window) || window == dragged_window_) | 1081 if (!IsWindowDocked(window) || window == dragged_window_) |
1080 continue; | 1082 continue; |
1081 | 1083 |
1082 // If the shelf is currently hidden (full-screen mode), hide window until | 1084 // If the shelf is currently hidden (full-screen mode), hide window until |
1083 // full-screen mode is exited. | 1085 // full-screen mode is exited. |
1084 if (in_fullscreen_) { | 1086 if (in_fullscreen_) { |
1085 // The call to Hide does not set the minimize property, so the window will | 1087 // The call to Hide does not set the minimize property, so the window will |
1086 // be restored when the shelf becomes visible again. | 1088 // be restored when the shelf becomes visible again. |
1087 window->Hide(); | 1089 window->Hide(); |
1088 continue; | 1090 continue; |
1089 } | 1091 } |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 // |`------'| | 1311 // |`------'| |
1310 // |`------'| | 1312 // |`------'| |
1311 // `------' | 1313 // `------' |
1312 // Use the middle of each window to figure out how to stack the window. | 1314 // Use the middle of each window to figure out how to stack the window. |
1313 // This allows us to update the stacking when a window is being dragged around | 1315 // This allows us to update the stacking when a window is being dragged around |
1314 // by the titlebar. | 1316 // by the titlebar. |
1315 std::map<int, aura::Window*> window_ordering; | 1317 std::map<int, aura::Window*> window_ordering; |
1316 for (aura::Window::Windows::const_iterator it = | 1318 for (aura::Window::Windows::const_iterator it = |
1317 dock_container_->children().begin(); | 1319 dock_container_->children().begin(); |
1318 it != dock_container_->children().end(); ++it) { | 1320 it != dock_container_->children().end(); ++it) { |
1319 if (!IsUsedByLayout(*it) || | 1321 if (!IsWindowDocked(*it) || |
1320 ((*it) == dragged_window_ && !is_dragged_window_docked_)) { | 1322 ((*it) == dragged_window_ && !is_dragged_window_docked_)) { |
1321 continue; | 1323 continue; |
1322 } | 1324 } |
1323 gfx::Rect bounds = (*it)->bounds(); | 1325 gfx::Rect bounds = (*it)->bounds(); |
1324 window_ordering.insert(std::make_pair(bounds.y() + bounds.height() / 2, | 1326 window_ordering.insert(std::make_pair(bounds.y() + bounds.height() / 2, |
1325 *it)); | 1327 *it)); |
1326 } | 1328 } |
1327 int active_center_y = active_window->bounds().CenterPoint().y(); | 1329 int active_center_y = active_window->bounds().CenterPoint().y(); |
1328 | 1330 |
1329 aura::Window* previous_window = NULL; | 1331 aura::Window* previous_window = NULL; |
(...skipping 23 matching lines...) Expand all Loading... |
1353 | 1355 |
1354 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( | 1356 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( |
1355 const gfx::Rect& keyboard_bounds) { | 1357 const gfx::Rect& keyboard_bounds) { |
1356 // This bounds change will have caused a change to the Shelf which does not | 1358 // This bounds change will have caused a change to the Shelf which does not |
1357 // propagate automatically to this class, so manually recalculate bounds. | 1359 // propagate automatically to this class, so manually recalculate bounds. |
1358 Relayout(); | 1360 Relayout(); |
1359 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); | 1361 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); |
1360 } | 1362 } |
1361 | 1363 |
1362 } // namespace ash | 1364 } // namespace ash |
OLD | NEW |