Chromium Code Reviews| Index: ash/wm/workspace/snap_sizer.cc |
| diff --git a/ash/wm/workspace/snap_sizer.cc b/ash/wm/workspace/snap_sizer.cc |
| index 11b59470fcd87d5be27e934cc992feac57b7c90a..3156ed5ea1fad0c13fbfb593ebaae4f6fa8d9d26 100644 |
| --- a/ash/wm/workspace/snap_sizer.cc |
| +++ b/ash/wm/workspace/snap_sizer.cc |
| @@ -11,6 +11,7 @@ |
| #include "ash/wm/window_resizer.h" |
| #include "ash/wm/window_util.h" |
| #include "ui/aura/window.h" |
| +#include "ui/aura/window_delegate.h" |
| #include "ui/gfx/screen.h" |
| namespace ash { |
| @@ -18,12 +19,9 @@ namespace internal { |
| namespace { |
| -// A list of ideal window width in pixel which will be used to populate the |
| -// |usable_width_| list. |
| -const int kIdealWidth[] = { 1280, 1024, 768, 640 }; |
| - |
| -// Windows are initially snapped to the size in |usable_width_| at index 0. |
| -// The index into |usable_width_| is changed if any of the following happen: |
| +// Windows are initially snapped to the bounds for the state at index 0 in |
| +// |states_|. |
| +// The index into |states_| is changed if any of the following happen: |
| // . The user stops moving the mouse for |kDelayBeforeIncreaseMS| and then |
| // moves the mouse again. |
| // . The mouse moves |kPixelsBeforeAdjust| horizontal pixels. |
| @@ -33,35 +31,49 @@ const int kDelayBeforeIncreaseMS = 500; |
| const int kMovesBeforeAdjust = 25; |
| const int kPixelsBeforeAdjust = 100; |
| -// When the smallest resolution does not fit on the screen, we take this |
| -// fraction of the available space. |
| -const int kMinimumScreenPercent = 90; |
| - |
| -// Create the list of possible width for the current screen configuration: |
| -// Fill the |usable_width_| list with items from |kIdealWidth| which fit on |
| -// the screen and supplement it with the 'half of screen' size. Furthermore, |
| -// add an entry for 90% of the screen size if it is smaller then the biggest |
| -// value in the |kIdealWidth| list (to get a step between the values). |
| -std::vector<int> BuildIdealWidthList(aura::Window* window) { |
| - std::vector<int> ideal_width_list; |
| +// The percent of the screen's width that a side maximized window takes up. |
| +const int kSideMaximizedScreenWidthPercent = 50; |
| + |
| +bool CanSideMaximizeWindow(aura::Window* window) { |
| + if (!wm::CanResizeWindow(window)) |
| + return false; |
| + // If a window has a maximum size defined, snapping may make it too big. |
| + return window->delegate() ? |
| + window->delegate()->GetMaximumSize().IsEmpty() : true; |
| +} |
| + |
| +gfx::Rect GetSideMaximizedWindowBoundsInParent(aura::Window* window, |
| + SnapSizer::Edge edge) { |
| gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window)); |
| - int half_size = work_area.width() / 2; |
| - int maximum_width = (kMinimumScreenPercent * work_area.width()) / 100; |
| - for (size_t i = 0; i < arraysize(kIdealWidth); i++) { |
| - if (maximum_width >= kIdealWidth[i]) { |
| - if (i && !ideal_width_list.size() && maximum_width != kIdealWidth[i]) |
| - ideal_width_list.push_back(maximum_width); |
| - if (half_size > kIdealWidth[i]) |
| - ideal_width_list.push_back(half_size); |
| - if (half_size >= kIdealWidth[i]) |
| - half_size = 0; |
| - ideal_width_list.push_back(kIdealWidth[i]); |
| - } |
| - } |
| - if (half_size) |
| - ideal_width_list.push_back(half_size); |
| + int width = work_area.width() * kSideMaximizedScreenWidthPercent / 100; |
| + if (window->delegate()) |
| + width = std::max(width, window->delegate()->GetMinimumSize().width()); |
|
Mr4D (OOO till 08-26)
2013/09/06 21:57:54
Just wondering: You are looking at the minimum siz
|
| + int x = (edge == SnapSizer::LEFT_EDGE) ? |
| + work_area.x() : work_area.right() - width; |
| + return gfx::Rect(x, work_area.y(), width, work_area.height()); |
| +} |
| - return ideal_width_list; |
| +void SideMaximizeWindow(aura::Window* window, SnapSizer::Edge edge) { |
| + gfx::Rect new_bounds(GetSideMaximizedWindowBoundsInParent(window, edge)); |
| + |
| + if (wm::IsWindowFullscreen(window) || wm::IsWindowMaximized(window)) { |
| + // Before we can set the bounds we need to restore the window. |
| + // Restoring the window will set the window to its restored bounds. |
| + // To avoid an unnecessary bounds changes (which may have side effects) |
| + // we set the restore bounds to the bounds we want, restore the window, |
| + // then reset the restore bounds. This way no unnecessary bounds |
| + // changes occurs and the original restore bounds is remembered. |
| + gfx::Rect restore = *GetRestoreBoundsInScreen(window); |
| + SetRestoreBoundsInParent(window, new_bounds); |
| + wm::RestoreWindow(window); |
| + SetRestoreBoundsInScreen(window, restore); |
| + } else { |
| + // Others might have set up a restore rectangle already. If so, we should |
| + // not overwrite the restore rectangle. |
| + if (GetRestoreBoundsInScreen(window) == NULL) |
| + SetRestoreBoundsInScreen(window, window->GetBoundsInScreen()); |
| + window->SetBounds(new_bounds); |
| + } |
| } |
| } // namespace |
| @@ -69,44 +81,37 @@ std::vector<int> BuildIdealWidthList(aura::Window* window) { |
| SnapSizer::SnapSizer(aura::Window* window, |
| const gfx::Point& start, |
| Edge edge, |
| - InputType input_type) |
| + StepBehavior step_behavior) |
| : window_(window), |
| edge_(edge), |
| time_last_update_(base::TimeTicks::Now()), |
| - size_index_(0), |
| - resize_disabled_(false), |
| num_moves_since_adjust_(0), |
| last_adjust_x_(start.x()), |
| last_update_x_(start.x()), |
| start_x_(start.x()), |
| - input_type_(input_type), |
| - usable_width_(BuildIdealWidthList(window)) { |
| - DCHECK(!usable_width_.empty()); |
| + state_index_(0), |
| + states_(BuildValidStatesList(window, step_behavior)) { |
| + DCHECK(!states_.empty()); |
| target_bounds_ = GetTargetBounds(); |
| } |
| SnapSizer::~SnapSizer() { |
| } |
| -void SnapSizer::SnapWindow(aura::Window* window, SnapSizer::Edge edge) { |
| - if (!wm::CanSnapWindow(window)) |
| - return; |
| - internal::SnapSizer sizer(window, gfx::Point(), edge, |
| - internal::SnapSizer::OTHER_INPUT); |
| - if (wm::IsWindowFullscreen(window) || wm::IsWindowMaximized(window)) { |
| - // Before we can set the bounds we need to restore the window. |
| - // Restoring the window will set the window to its restored bounds. |
| - // To avoid an unnecessary bounds changes (which may have side effects) |
| - // we set the restore bounds to the bounds we want, restore the window, |
| - // then reset the restore bounds. This way no unnecessary bounds |
| - // changes occurs and the original restore bounds is remembered. |
| - gfx::Rect restore = *GetRestoreBoundsInScreen(window); |
| - SetRestoreBoundsInParent(window, sizer.GetSnapBounds(window->bounds())); |
| - wm::RestoreWindow(window); |
| - SetRestoreBoundsInScreen(window, restore); |
| - } else { |
| - window->SetBounds(sizer.GetSnapBounds(window->bounds())); |
| - } |
| +// static |
| +bool SnapSizer::CanSnapWindow(aura::Window* window) { |
| + return CanSideMaximizeWindow(window); |
| +} |
| + |
| +// static |
| +void SnapSizer::SnapWindow(aura::Window* window, |
| + Edge edge, |
| + StepBehavior step_behavior) { |
| + SnapSizer(window, gfx::Point(), edge, step_behavior).Snap(); |
| +} |
| + |
| +void SnapSizer::Snap() { |
| + SideMaximizeWindow(window_, edge_); |
| } |
| void SnapSizer::Update(const gfx::Point& location) { |
| @@ -114,77 +119,32 @@ void SnapSizer::Update(const gfx::Point& location) { |
| num_moves_since_adjust_++; |
| if ((base::TimeTicks::Now() - time_last_update_).InMilliseconds() > |
| kDelayBeforeIncreaseMS) { |
| - ChangeBounds(location.x(), |
| - CalculateIncrement(location.x(), last_update_x_)); |
| + IncrementState(CalculateIncrement(location.x(), last_update_x_)); |
| + num_moves_since_adjust_ = 0; |
| + last_adjust_x_ = location.x(); |
| } else { |
| bool along_edge = AlongEdge(location.x()); |
| - int pixels_before_adjust = kPixelsBeforeAdjust; |
| - if (input_type_ == TOUCH_MAXIMIZE_BUTTON_INPUT) { |
| - const gfx::Rect& workspace_bounds = window_->parent()->bounds(); |
| - if (start_x_ > location.x()) { |
| - pixels_before_adjust = |
| - std::min(pixels_before_adjust, start_x_ / 10); |
| - } else { |
| - pixels_before_adjust = |
| - std::min(pixels_before_adjust, |
| - (workspace_bounds.width() - start_x_) / 10); |
| - } |
| - } |
| - if (std::abs(location.x() - last_adjust_x_) >= pixels_before_adjust || |
| + if (std::abs(location.x() - last_adjust_x_) >= kPixelsBeforeAdjust || |
| (along_edge && num_moves_since_adjust_ >= kMovesBeforeAdjust)) { |
| - ChangeBounds(location.x(), |
| - CalculateIncrement(location.x(), last_adjust_x_)); |
| + IncrementState(CalculateIncrement(location.x(), last_adjust_x_)); |
| + num_moves_since_adjust_ = 0; |
| + last_adjust_x_ = location.x(); |
| } |
| } |
| last_update_x_ = location.x(); |
| time_last_update_ = base::TimeTicks::Now(); |
| } |
| -gfx::Rect SnapSizer::GetSnapBounds(const gfx::Rect& bounds) { |
| - int current = 0; |
| - if (!resize_disabled_) { |
| - for (current = usable_width_.size() - 1; current >= 0; current--) { |
| - gfx::Rect target = GetTargetBoundsForSize(current); |
| - if (target == bounds) { |
| - ++current; |
| - break; |
| - } |
| - } |
| - } |
| - return GetTargetBoundsForSize(current % usable_width_.size()); |
| -} |
| - |
| -void SnapSizer::SelectDefaultSizeAndDisableResize() { |
| - resize_disabled_ = true; |
| - size_index_ = 0; |
| - target_bounds_ = GetTargetBounds(); |
| -} |
| - |
| -gfx::Rect SnapSizer::GetTargetBoundsForSize(size_t size_index) const { |
| - gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_)); |
| - int y = work_area.y(); |
| - // We don't align to the bottom of the grid as the launcher may not |
| - // necessarily align to the grid (happens when auto-hidden). |
| - int max_y = work_area.bottom(); |
| - int width = 0; |
| - if (resize_disabled_) { |
| - // Make sure that we keep the size of the window smaller then a certain |
| - // fraction of the screen space. |
| - int minimum_size = (kMinimumScreenPercent * work_area.width()) / 100; |
| - width = std::max(std::min(minimum_size, 1024), work_area.width() / 2); |
| - } else { |
| - DCHECK(size_index < usable_width_.size()); |
| - width = usable_width_[size_index]; |
| - } |
| - |
| - if (edge_ == LEFT_EDGE) { |
| - int x = work_area.x(); |
| - int mid_x = x + width; |
| - return gfx::Rect(x, y, mid_x - x, max_y - y); |
| - } |
| - int max_x = work_area.right(); |
| - int x = max_x - width; |
| - return gfx::Rect(x , y, max_x - x, max_y - y); |
| +// static |
| +std::vector<SnapSizer::State> SnapSizer::BuildValidStatesList( |
| + aura::Window* window, |
| + StepBehavior step_behavior) { |
| + // If |step_behavior| == STEP_NO, the size of the returned list should be |
| + // capped to a size of 1. |
|
Mr4D (OOO till 08-26)
2013/09/06 21:57:54
Is this a TODO? (since I cannot see step_behavior
|
| + std::vector<SnapSizer::State> states; |
| + DCHECK(CanSideMaximizeWindow(window)); |
| + states.push_back(SIDE_MAXIMIZE); |
| + return states; |
| } |
| int SnapSizer::CalculateIncrement(int x, int reference_x) const { |
| @@ -203,19 +163,19 @@ int SnapSizer::CalculateIncrement(int x, int reference_x) const { |
| return -1; |
| } |
| -void SnapSizer::ChangeBounds(int x, int delta) { |
| - int index = std::min(static_cast<int>(usable_width_.size()) - 1, |
| - std::max(size_index_ + delta, 0)); |
| - if (index != size_index_) { |
| - size_index_ = index; |
| +void SnapSizer::IncrementState(int delta) { |
| + int index = std::min(static_cast<int>(states_.size()) - 1, |
| + std::max(state_index_ + delta, 0)); |
| + if (index != state_index_) { |
| + state_index_ = index; |
| target_bounds_ = GetTargetBounds(); |
| } |
| - num_moves_since_adjust_ = 0; |
| - last_adjust_x_ = x; |
| } |
| gfx::Rect SnapSizer::GetTargetBounds() const { |
| - return GetTargetBoundsForSize(size_index_); |
| + State state = states_[state_index_]; |
| + DCHECK_EQ(SIDE_MAXIMIZE, state); |
| + return GetSideMaximizedWindowBoundsInParent(window_, edge_); |
| } |
| bool SnapSizer::AlongEdge(int x) const { |