| 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..309b9ca80e79696a763a9e62fd6a8d62ae1953a1 100644
|
| --- a/ash/wm/workspace/snap_sizer.cc
|
| +++ b/ash/wm/workspace/snap_sizer.cc
|
| @@ -6,10 +6,17 @@
|
|
|
| #include <cmath>
|
|
|
| +#include "ash/ash_switches.h"
|
| +#include "ash/launcher/launcher.h"
|
| #include "ash/screen_ash.h"
|
| +#include "ash/shell.h"
|
| +#include "ash/shell_window_ids.h"
|
| +#include "ash/wm/dock/docked_window_layout_manager.h"
|
| #include "ash/wm/property_util.h"
|
| +#include "ash/wm/window_properties.h"
|
| #include "ash/wm/window_resizer.h"
|
| #include "ash/wm/window_util.h"
|
| +#include "base/command_line.h"
|
| #include "ui/aura/window.h"
|
| #include "ui/gfx/screen.h"
|
|
|
| @@ -38,28 +45,37 @@ const int kPixelsBeforeAdjust = 100;
|
| 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) {
|
| +// Returns a list that for windows that can be snapped (|allow_snap| set)
|
| +// includes 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).
|
| +// When a window can be docked (|allow_dock| set) a zero-width is added as the
|
| +// last value to facilitate showing a docking guide.
|
| +std::vector<int> BuildIdealWidthList(aura::Window* window,
|
| + bool allow_snap,
|
| + bool allow_dock) {
|
| std::vector<int> ideal_width_list;
|
| - 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 (allow_snap) {
|
| + 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);
|
| }
|
| - if (half_size)
|
| - ideal_width_list.push_back(half_size);
|
| + if (allow_dock)
|
| + ideal_width_list.push_back(0);
|
|
|
| return ideal_width_list;
|
| }
|
| @@ -79,13 +95,30 @@ SnapSizer::SnapSizer(aura::Window* window,
|
| last_adjust_x_(start.x()),
|
| last_update_x_(start.x()),
|
| start_x_(start.x()),
|
| - input_type_(input_type),
|
| - usable_width_(BuildIdealWidthList(window)) {
|
| + input_type_(input_type) {
|
| + aura::Window* dock_container = Shell::GetContainer(
|
| + window_->GetRootWindow(), kShellWindowId_DockedContainer);
|
| + dock_layout_ = static_cast<DockedWindowLayoutManager*>(
|
| + dock_container->layout_manager());
|
| + bool allow_dock =
|
| + input_type_ == internal::SnapSizer::WORKSPACE_DRAG_INPUT &&
|
| + CanDockWindow(window_, edge_);
|
| + bool allow_snap = !allow_dock ||
|
| + (wm::CanSnapWindow(window_) &&
|
| + !dock_layout_->is_dragged_window_docked() &&
|
| + window->bounds().width() > DockedWindowLayoutManager::kMaxDockWidth);
|
| + usable_width_ = BuildIdealWidthList(window, allow_snap, allow_dock);
|
| DCHECK(!usable_width_.empty());
|
| + UpdateDockedState();
|
| target_bounds_ = GetTargetBounds();
|
| }
|
|
|
| SnapSizer::~SnapSizer() {
|
| + // Normally when a drag is completed CompleteDrag will be called making
|
| + // the following a no-op. updating state is necessary when a window gets
|
| + // snapped in and out during the drag.
|
| + if (dock_layout_->is_dragged_window_docked())
|
| + dock_layout_->UndockDraggedWindow();
|
| }
|
|
|
| void SnapSizer::SnapWindow(aura::Window* window, SnapSizer::Edge edge) {
|
| @@ -136,6 +169,7 @@ void SnapSizer::Update(const gfx::Point& location) {
|
| CalculateIncrement(location.x(), last_adjust_x_));
|
| }
|
| }
|
| + UpdateDockedState();
|
| last_update_x_ = location.x();
|
| time_last_update_ = base::TimeTicks::Now();
|
| }
|
| @@ -157,6 +191,7 @@ gfx::Rect SnapSizer::GetSnapBounds(const gfx::Rect& bounds) {
|
| void SnapSizer::SelectDefaultSizeAndDisableResize() {
|
| resize_disabled_ = true;
|
| size_index_ = 0;
|
| + UpdateDockedState();
|
| target_bounds_ = GetTargetBounds();
|
| }
|
|
|
| @@ -177,6 +212,11 @@ gfx::Rect SnapSizer::GetTargetBoundsForSize(size_t size_index) const {
|
| width = usable_width_[size_index];
|
| }
|
|
|
| + if (width == 0) {
|
| + return ScreenAsh::ConvertRectFromScreen(window_->parent(),
|
| + dock_layout_->dragged_bounds());
|
| + }
|
| +
|
| if (edge_ == LEFT_EDGE) {
|
| int x = work_area.x();
|
| int mid_x = x + width;
|
| @@ -187,6 +227,38 @@ gfx::Rect SnapSizer::GetTargetBoundsForSize(size_t size_index) const {
|
| return gfx::Rect(x , y, max_x - x, max_y - y);
|
| }
|
|
|
| +bool SnapSizer::ShouldDockWindow() const {
|
| + // TODO(varkha): use dedicated state.
|
| + return (usable_width_[size_index_] == 0);
|
| +}
|
| +
|
| +// static
|
| +bool SnapSizer::CanDockWindow(aura::Window* window, SnapSizer::Edge edge) {
|
| + if (!CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kAshEnableDockedWindows)) {
|
| + return false;
|
| + }
|
| + // Cannot dock on the other size from an existing dock.
|
| + aura::Window* dock_container = Shell::GetContainer(
|
| + window->GetRootWindow(), kShellWindowId_DockedContainer);
|
| + DockedWindowLayoutManager* dock_layout =
|
| + static_cast<DockedWindowLayoutManager*>(dock_container->layout_manager());
|
| + const DockedAlignment alignment = dock_layout->CalculateAlignment();
|
| + if ((edge == LEFT_EDGE && alignment == DOCKED_ALIGNMENT_RIGHT) ||
|
| + (edge == RIGHT_EDGE && alignment == DOCKED_ALIGNMENT_LEFT)) {
|
| + return false;
|
| + }
|
| +
|
| + // Do not allow docking on the same side as launcher shelf.
|
| + Launcher* shelf = Launcher::ForWindow(window);
|
| + if (shelf &&
|
| + ((edge == LEFT_EDGE && shelf->alignment() == SHELF_ALIGNMENT_LEFT) ||
|
| + (edge == RIGHT_EDGE && shelf->alignment() == SHELF_ALIGNMENT_RIGHT))) {
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| int SnapSizer::CalculateIncrement(int x, int reference_x) const {
|
| if (AlongEdge(x))
|
| return 1;
|
| @@ -219,9 +291,21 @@ gfx::Rect SnapSizer::GetTargetBounds() const {
|
| }
|
|
|
| bool SnapSizer::AlongEdge(int x) const {
|
| - gfx::Rect area(ScreenAsh::GetDisplayBoundsInParent(window_));
|
| + gfx::Rect area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_));
|
| return (x <= area.x()) || (x >= area.right() - 1);
|
| }
|
|
|
| +void SnapSizer::UpdateDockedState() {
|
| + if (ShouldDockWindow() &&
|
| + dock_layout_->GetAlignmentOfWindow(window_) != DOCKED_ALIGNMENT_NONE) {
|
| + if (!dock_layout_->is_dragged_window_docked())
|
| + dock_layout_->DockDraggedWindow(window_);
|
| + target_bounds_ = GetTargetBounds();
|
| + } else {
|
| + if (dock_layout_->is_dragged_window_docked())
|
| + dock_layout_->UndockDraggedWindow();
|
| + }
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace ash
|
|
|