| 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/wm/workspace/workspace_window_resizer.h" | 5 #include "ash/wm/workspace/workspace_window_resizer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "ash/ash_switches.h" | 12 #include "ash/ash_switches.h" |
| 13 #include "ash/root_window_controller.h" | 13 #include "ash/root_window_controller.h" |
| 14 #include "ash/screen_ash.h" | 14 #include "ash/screen_ash.h" |
| 15 #include "ash/shell.h" | 15 #include "ash/shell.h" |
| 16 #include "ash/shell_window_ids.h" | 16 #include "ash/shell_window_ids.h" |
| 17 #include "ash/wm/coordinate_conversion.h" | 17 #include "ash/wm/coordinate_conversion.h" |
| 18 #include "ash/wm/default_window_resizer.h" | 18 #include "ash/wm/default_window_resizer.h" |
| 19 #include "ash/wm/dock/docked_window_resizer.h" | 19 #include "ash/wm/dock/docked_window_resizer.h" |
| 20 #include "ash/wm/drag_window_resizer.h" | 20 #include "ash/wm/drag_window_resizer.h" |
| 21 #include "ash/wm/panels/panel_window_resizer.h" | 21 #include "ash/wm/panels/panel_window_resizer.h" |
| 22 #include "ash/wm/property_util.h" | 22 #include "ash/wm/property_util.h" |
| 23 #include "ash/wm/window_properties.h" | 23 #include "ash/wm/window_properties.h" |
| 24 #include "ash/wm/window_util.h" | 24 #include "ash/wm/window_util.h" |
| 25 #include "ash/wm/workspace/phantom_window_controller.h" | 25 #include "ash/wm/workspace/phantom_window_controller.h" |
| 26 #include "ash/wm/workspace/snap_sizer.h" | |
| 27 #include "base/command_line.h" | 26 #include "base/command_line.h" |
| 28 #include "ui/aura/client/aura_constants.h" | 27 #include "ui/aura/client/aura_constants.h" |
| 29 #include "ui/aura/client/screen_position_client.h" | 28 #include "ui/aura/client/screen_position_client.h" |
| 30 #include "ui/aura/client/window_types.h" | 29 #include "ui/aura/client/window_types.h" |
| 31 #include "ui/aura/root_window.h" | 30 #include "ui/aura/root_window.h" |
| 32 #include "ui/aura/window.h" | 31 #include "ui/aura/window.h" |
| 33 #include "ui/aura/window_delegate.h" | 32 #include "ui/aura/window_delegate.h" |
| 34 #include "ui/base/hit_test.h" | 33 #include "ui/base/hit_test.h" |
| 35 #include "ui/compositor/layer.h" | 34 #include "ui/compositor/layer.h" |
| 36 #include "ui/gfx/screen.h" | 35 #include "ui/gfx/screen.h" |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 return; | 406 return; |
| 408 | 407 |
| 409 // When the window is not in the normal show state, we do not snap the window. | 408 // When the window is not in the normal show state, we do not snap the window. |
| 410 // This happens when the user minimizes or maximizes the window by keyboard | 409 // This happens when the user minimizes or maximizes the window by keyboard |
| 411 // shortcut while dragging it. If the window is the result of dragging a tab | 410 // shortcut while dragging it. If the window is the result of dragging a tab |
| 412 // out of a maximized window, it's already in the normal show state when this | 411 // out of a maximized window, it's already in the normal show state when this |
| 413 // is called, so it does not matter. | 412 // is called, so it does not matter. |
| 414 if (wm::IsWindowNormal(window()) && | 413 if (wm::IsWindowNormal(window()) && |
| 415 (window()->type() != aura::client::WINDOW_TYPE_PANEL || | 414 (window()->type() != aura::client::WINDOW_TYPE_PANEL || |
| 416 !window()->GetProperty(kPanelAttachedKey)) && | 415 !window()->GetProperty(kPanelAttachedKey)) && |
| 417 (snap_type_ == SNAP_LEFT_EDGE || snap_type_ == SNAP_RIGHT_EDGE)) { | 416 (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) { |
| 418 if (!GetRestoreBoundsInScreen(window())) { | 417 if (!GetRestoreBoundsInScreen(window())) { |
| 419 gfx::Rect initial_bounds = ScreenAsh::ConvertRectToScreen( | 418 gfx::Rect initial_bounds = ScreenAsh::ConvertRectToScreen( |
| 420 window()->parent(), details_.initial_bounds_in_parent); | 419 window()->parent(), details_.initial_bounds_in_parent); |
| 421 SetRestoreBoundsInScreen(window(), details_.restore_bounds.IsEmpty() ? | 420 SetRestoreBoundsInScreen(window(), details_.restore_bounds.IsEmpty() ? |
| 422 initial_bounds : | 421 initial_bounds : |
| 423 details_.restore_bounds); | 422 details_.restore_bounds); |
| 424 } | 423 } |
| 425 window()->SetBounds(snap_sizer_->target_bounds()); | 424 if (snap_type_ == SNAP_LEFT) |
| 426 return; | 425 wm::SnapWindowToEdge(window(), wm::SNAP_LEFT_EDGE); |
| 426 else if (snap_type_ == SNAP_RIGHT) |
| 427 wm::SnapWindowToEdge(window(), wm::SNAP_RIGHT_EDGE); |
| 427 } | 428 } |
| 428 } | 429 } |
| 429 | 430 |
| 430 void WorkspaceWindowResizer::RevertDrag() { | 431 void WorkspaceWindowResizer::RevertDrag() { |
| 431 snap_phantom_window_controller_.reset(); | 432 snap_phantom_window_controller_.reset(); |
| 432 | 433 |
| 433 if (!did_move_or_resize_) | 434 if (!did_move_or_resize_) |
| 434 return; | 435 return; |
| 435 | 436 |
| 436 window()->SetBounds(details_.initial_bounds_in_parent); | 437 window()->SetBounds(details_.initial_bounds_in_parent); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 shell->cursor_manager()->LockCursor(); | 484 shell->cursor_manager()->LockCursor(); |
| 484 | 485 |
| 485 // Only support attaching to the right/bottom. | 486 // Only support attaching to the right/bottom. |
| 486 DCHECK(attached_windows_.empty() || | 487 DCHECK(attached_windows_.empty() || |
| 487 (details.window_component == HTRIGHT || | 488 (details.window_component == HTRIGHT || |
| 488 details.window_component == HTBOTTOM)); | 489 details.window_component == HTBOTTOM)); |
| 489 | 490 |
| 490 // TODO: figure out how to deal with window going off the edge. | 491 // TODO: figure out how to deal with window going off the edge. |
| 491 | 492 |
| 492 // Calculate sizes so that we can maintain the ratios if we need to resize. | 493 // Calculate sizes so that we can maintain the ratios if we need to resize. |
| 493 int total_available = 0; | |
| 494 for (size_t i = 0; i < attached_windows_.size(); ++i) { | 494 for (size_t i = 0; i < attached_windows_.size(); ++i) { |
| 495 gfx::Size min(attached_windows_[i]->delegate()->GetMinimumSize()); | 495 gfx::Size min(attached_windows_[i]->delegate()->GetMinimumSize()); |
| 496 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size()); | 496 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size()); |
| 497 initial_size_.push_back(initial_size); | 497 initial_size_.push_back(initial_size); |
| 498 // If current size is smaller than the min, use the current size as the min. | 498 // If current size is smaller than the min, use the current size as the min. |
| 499 // This way we don't snap on resize. | 499 // This way we don't snap on resize. |
| 500 int min_size = std::min(initial_size, | 500 int min_size = std::min(initial_size, |
| 501 std::max(PrimaryAxisSize(min), kMinOnscreenSize)); | 501 std::max(PrimaryAxisSize(min), kMinOnscreenSize)); |
| 502 total_min_ += min_size; | 502 total_min_ += min_size; |
| 503 total_initial_size_ += initial_size; | 503 total_initial_size_ += initial_size; |
| 504 total_available += std::max(min_size, initial_size) - min_size; | |
| 505 } | 504 } |
| 506 } | 505 } |
| 507 | 506 |
| 508 gfx::Rect WorkspaceWindowResizer::GetFinalBounds( | |
| 509 const gfx::Rect& bounds) const { | |
| 510 if (snap_phantom_window_controller_.get() && | |
| 511 snap_phantom_window_controller_->IsShowing()) { | |
| 512 return snap_phantom_window_controller_->bounds_in_screen(); | |
| 513 } | |
| 514 return bounds; | |
| 515 } | |
| 516 | |
| 517 void WorkspaceWindowResizer::LayoutAttachedWindows( | 507 void WorkspaceWindowResizer::LayoutAttachedWindows( |
| 518 gfx::Rect* bounds) { | 508 gfx::Rect* bounds) { |
| 519 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); | 509 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); |
| 520 int initial_size = PrimaryAxisSize(details_.initial_bounds_in_parent.size()); | 510 int initial_size = PrimaryAxisSize(details_.initial_bounds_in_parent.size()); |
| 521 int current_size = PrimaryAxisSize(bounds->size()); | 511 int current_size = PrimaryAxisSize(bounds->size()); |
| 522 int start = PrimaryAxisCoordinate(bounds->right(), bounds->bottom()); | 512 int start = PrimaryAxisCoordinate(bounds->right(), bounds->bottom()); |
| 523 int end = PrimaryAxisCoordinate(work_area.right(), work_area.bottom()); | 513 int end = PrimaryAxisCoordinate(work_area.right(), work_area.bottom()); |
| 524 | 514 |
| 525 int delta = current_size - initial_size; | 515 int delta = current_size - initial_size; |
| 526 int available_size = end - start; | 516 int available_size = end - start; |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 | 850 |
| 861 if (window()->type() == aura::client::WINDOW_TYPE_PANEL && | 851 if (window()->type() == aura::client::WINDOW_TYPE_PANEL && |
| 862 window()->GetProperty(kPanelAttachedKey)) { | 852 window()->GetProperty(kPanelAttachedKey)) { |
| 863 return; | 853 return; |
| 864 } | 854 } |
| 865 | 855 |
| 866 SnapType last_type = snap_type_; | 856 SnapType last_type = snap_type_; |
| 867 snap_type_ = GetSnapType(location); | 857 snap_type_ = GetSnapType(location); |
| 868 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) { | 858 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) { |
| 869 snap_phantom_window_controller_.reset(); | 859 snap_phantom_window_controller_.reset(); |
| 870 snap_sizer_.reset(); | |
| 871 if (snap_type_ == SNAP_NONE) | 860 if (snap_type_ == SNAP_NONE) |
| 872 return; | 861 return; |
| 873 } | 862 } |
| 874 if (!snap_sizer_) { | |
| 875 SnapSizer::Edge edge = (snap_type_ == SNAP_LEFT_EDGE) ? | |
| 876 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE; | |
| 877 snap_sizer_.reset(new SnapSizer(window(), | |
| 878 location, | |
| 879 edge, | |
| 880 internal::SnapSizer::OTHER_INPUT)); | |
| 881 } else { | |
| 882 snap_sizer_->Update(location); | |
| 883 } | |
| 884 if (!snap_phantom_window_controller_) { | 863 if (!snap_phantom_window_controller_) { |
| 885 snap_phantom_window_controller_.reset( | 864 snap_phantom_window_controller_.reset( |
| 886 new PhantomWindowController(window())); | 865 new PhantomWindowController(window())); |
| 887 } | 866 } |
| 867 |
| 868 wm::SnapEdge edge = (snap_type_ == SNAP_LEFT) ? |
| 869 wm::SNAP_LEFT_EDGE : wm::SNAP_RIGHT_EDGE; |
| 870 gfx::Rect target_bounds = wm::GetSnappedWindowBoundsInParent(window(), edge); |
| 888 snap_phantom_window_controller_->Show(ScreenAsh::ConvertRectToScreen( | 871 snap_phantom_window_controller_->Show(ScreenAsh::ConvertRectToScreen( |
| 889 window()->parent(), snap_sizer_->target_bounds())); | 872 window()->parent(), target_bounds)); |
| 890 } | 873 } |
| 891 | 874 |
| 892 void WorkspaceWindowResizer::RestackWindows() { | 875 void WorkspaceWindowResizer::RestackWindows() { |
| 893 if (attached_windows_.empty()) | 876 if (attached_windows_.empty()) |
| 894 return; | 877 return; |
| 895 // Build a map from index in children to window, returning if there is a | 878 // Build a map from index in children to window, returning if there is a |
| 896 // window with a different parent. | 879 // window with a different parent. |
| 897 typedef std::map<size_t, aura::Window*> IndexToWindowMap; | 880 typedef std::map<size_t, aura::Window*> IndexToWindowMap; |
| 898 IndexToWindowMap map; | 881 IndexToWindowMap map; |
| 899 aura::Window* parent = window()->parent(); | 882 aura::Window* parent = window()->parent(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 919 parent->StackChildBelow(i->second, window); | 902 parent->StackChildBelow(i->second, window); |
| 920 } | 903 } |
| 921 } | 904 } |
| 922 | 905 |
| 923 WorkspaceWindowResizer::SnapType WorkspaceWindowResizer::GetSnapType( | 906 WorkspaceWindowResizer::SnapType WorkspaceWindowResizer::GetSnapType( |
| 924 const gfx::Point& location) const { | 907 const gfx::Point& location) const { |
| 925 // TODO: this likely only wants total display area, not the area of a single | 908 // TODO: this likely only wants total display area, not the area of a single |
| 926 // display. | 909 // display. |
| 927 gfx::Rect area(ScreenAsh::GetDisplayBoundsInParent(window())); | 910 gfx::Rect area(ScreenAsh::GetDisplayBoundsInParent(window())); |
| 928 if (location.x() <= area.x()) | 911 if (location.x() <= area.x()) |
| 929 return SNAP_LEFT_EDGE; | 912 return SNAP_LEFT; |
| 930 if (location.x() >= area.right() - 1) | 913 if (location.x() >= area.right() - 1) |
| 931 return SNAP_RIGHT_EDGE; | 914 return SNAP_RIGHT; |
| 932 return SNAP_NONE; | 915 return SNAP_NONE; |
| 933 } | 916 } |
| 934 | 917 |
| 935 } // namespace internal | 918 } // namespace internal |
| 936 } // namespace ash | 919 } // namespace ash |
| OLD | NEW |