0

wm: Refactor WorkspaceWindowResizer.

Some things encountered while working on making workspace drag
work with maximized windows.

* remove unused members/variables
* remove base::NumberToString in tests
* combined two anon namespaces
* small miscallenous updates

Test: none
Bug: 1066159
Change-Id: I2dfd1cd7f416d9e93b034147d408227f16a39d13
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2142777
Reviewed-by: Xiaoqian Dai <xdai@chromium.org>
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#758059}
This commit is contained in:
Sammie Quon
2020-04-09 23:03:47 +00:00
committed by Commit Bot
parent 7717134952
commit 7f6b154529
5 changed files with 179 additions and 222 deletions

@ -70,7 +70,6 @@ DragDetails::DragDetails(aura::Window* window,
// When drag starts, we might be in the middle of a window opacity
// animation, on drag completion we must set the opacity to the target
// opacity rather than the current opacity (crbug.com/687003).
initial_opacity(window->layer()->GetTargetOpacity()),
window_component(window_component),
bounds_change(
WindowResizer::GetBoundsChangeForWindowComponent(window_component)),

@ -37,9 +37,6 @@ struct ASH_EXPORT DragDetails {
// Location passed to the constructor, in |window->parent()|'s coordinates.
const gfx::PointF initial_location_in_parent;
// Initial opacity of the window.
const float initial_opacity;
// The component the user pressed on.
const int window_component;

@ -53,141 +53,13 @@ namespace {
constexpr double kMinHorizVelocityForWindowSwipe = 1100;
constexpr double kMinVertVelocityForWindowMinimize = 1000;
// Returns true if |window| can be dragged from the top of the screen in tablet
// mode.
std::unique_ptr<WindowResizer> CreateWindowResizerForTabletMode(
aura::Window* window,
const gfx::PointF& point_in_parent,
int window_component,
::wm::WindowMoveSource source) {
// Window dragging from top and tab dragging are disabled if "WebUITabStrip"
// feature is enabled. "WebUITabStrip" will be enabled on 81 for Krane and on
// 82 for all other boards.
if (features::IsWebUITabStripEnabled())
return nullptr;
// Snap region when dragging close to the edges. That is, as the window gets
// this close to an edge of the screen it snaps to the edge.
constexpr int kScreenEdgeInset = 8;
WindowState* window_state = WindowState::Get(window);
// Only maximized/fullscreen/snapped window can be dragged from the top of
// the screen.
if (!window_state->IsMaximized() && !window_state->IsFullscreen() &&
!window_state->IsSnapped()) {
return nullptr;
}
AppType app_type =
static_cast<AppType>(window->GetProperty(aura::client::kAppType));
// App windows can be dragged from the client area (see
// ToplevelWindowEventHandler).
if (app_type != AppType::BROWSER && window_component == HTCLIENT) {
DCHECK_EQ(source, ::wm::WINDOW_MOVE_SOURCE_TOUCH);
window_state->CreateDragDetails(point_in_parent, HTCLIENT,
::wm::WINDOW_MOVE_SOURCE_TOUCH);
std::unique_ptr<WindowResizer> window_resizer =
std::make_unique<TabletModeWindowResizer>(
window_state, std::make_unique<TabletModeWindowDragDelegate>());
return std::make_unique<DragWindowResizer>(std::move(window_resizer),
window_state);
}
// Only allow drag that happens on caption or top area. Note: for a maxmized
// or fullscreen window, the window component here is always HTCAPTION, but
// for a snapped window, the window component here can either be HTCAPTION or
// HTTOP.
if (window_component != HTCAPTION && window_component != HTTOP)
return nullptr;
// Note: only browser windows and chrome app windows are included here.
// For browser windows, this piece of codes will be called no matter the
// drag happens on the tab(s) or on the non-tabstrip caption or top area.
// But for app window, this piece of codes will only be called if the chrome
// app window has its customized caption area and can't be hidden in tablet
// mode (and thus the drag for this type of chrome app window always happens
// on caption or top area). The case where the caption area of the chrome app
// window can be hidden is handled above.
if (app_type != AppType::BROWSER && app_type != AppType::CHROME_APP)
return nullptr;
window_state->CreateDragDetails(point_in_parent, window_component, source);
std::unique_ptr<WindowResizer> window_resizer =
std::make_unique<TabletModeWindowResizer>(
window_state,
std::make_unique<TabletModeBrowserWindowDragDelegate>());
return std::make_unique<DragWindowResizer>(std::move(window_resizer),
window_state);
}
} // namespace
std::unique_ptr<WindowResizer> CreateWindowResizer(
aura::Window* window,
const gfx::PointF& point_in_parent,
int window_component,
::wm::WindowMoveSource source) {
DCHECK(window);
WindowState* window_state = WindowState::Get(window);
// A resizer already exists; don't create a new one.
if (window_state->drag_details())
return nullptr;
// When running in single app mode, we should not create window resizer.
if (Shell::Get()->session_controller()->IsRunningInAppMode())
return nullptr;
if (window_state->IsPip()) {
window_state->CreateDragDetails(point_in_parent, window_component, source);
return std::make_unique<PipWindowResizer>(window_state);
}
if (Shell::Get()->tablet_mode_controller()->InTabletMode()) {
return CreateWindowResizerForTabletMode(window, point_in_parent,
window_component, source);
}
// No need to return a resizer when the window cannot get resized.
if (!window_state->CanResize() && window_component != HTCAPTION)
return nullptr;
if (!window_state->IsNormalOrSnapped())
return nullptr;
int bounds_change =
WindowResizer::GetBoundsChangeForWindowComponent(window_component);
if (bounds_change == WindowResizer::kBoundsChangeDirection_None)
return nullptr;
window_state->CreateDragDetails(point_in_parent, window_component, source);
// TODO(varkha): The chaining of window resizers causes some of the logic
// to be repeated and the logic flow difficult to control. With some windows
// classes using reparenting during drag operations it becomes challenging to
// implement proper transition from one resizer to another during or at the
// end of the drag. This also causes http://crbug.com/247085.
// We should have a better way of doing this, perhaps by having a way of
// observing drags or having a generic drag window wrapper which informs a
// layout manager that a drag has started or stopped. It may be possible to
// refactor and eliminate chaining.
std::unique_ptr<WindowResizer> window_resizer;
const auto* parent = window->parent();
if (parent &&
// TODO(afakhry): Maybe use switchable containers?
(desks_util::IsDeskContainer(parent) ||
parent->id() == kShellWindowId_AlwaysOnTopContainer)) {
window_resizer.reset(WorkspaceWindowResizer::Create(
window_state, std::vector<aura::Window*>()));
} else {
window_resizer.reset(DefaultWindowResizer::Create(window_state));
}
return std::make_unique<DragWindowResizer>(std::move(window_resizer),
window_state);
}
namespace {
// Snapping distance used instead of WorkspaceWindowResizer::kScreenEdgeInset
// when resizing a window using touchscreen.
const int kScreenEdgeInsetForTouchDrag = 32;
// Snapping distance used instead of kScreenEdgeInset when resizing a window
// using touchscreen.
constexpr int kScreenEdgeInsetForTouchDrag = 32;
// If an edge of the work area is at an edge of the display, then you can snap a
// window by dragging to a point within this far inward from that edge. This
@ -196,10 +68,15 @@ const int kScreenEdgeInsetForTouchDrag = 32;
// neighboring display. For touch dragging, you may be able to drag out of the
// display because the physical device has a border around the display. Either
// case makes it difficult to drag to the edge without this tolerance.
const int kScreenEdgeInsetForSnapping = 32;
constexpr int kScreenEdgeInsetForSnapping = 32;
// When dragging an attached window this is the min size we'll make sure is
// visible. In the vertical direction we take the max of this and that from
// the delegate.
constexpr int kMinOnscreenSize = 20;
// Current instance for use by the WorkspaceWindowResizerTest.
WorkspaceWindowResizer* instance = NULL;
WorkspaceWindowResizer* instance = nullptr;
// Returns true if the window should stick to the edge.
bool ShouldStickToEdge(int distance_from_edge, int sticky_size) {
@ -336,16 +213,134 @@ uint32_t WindowComponentToMagneticEdge(int window_component) {
return 0;
}
// Returns a WindowResizer if dragging |window| is allowed in tablet mode.
std::unique_ptr<WindowResizer> CreateWindowResizerForTabletMode(
aura::Window* window,
const gfx::PointF& point_in_parent,
int window_component,
::wm::WindowMoveSource source) {
// Window dragging from top and tab dragging are disabled if "WebUITabStrip"
// feature is enabled. "WebUITabStrip" will be enabled on 81 for Krane and on
// 82 for all other boards.
if (features::IsWebUITabStripEnabled())
return nullptr;
WindowState* window_state = WindowState::Get(window);
// Only maximized/fullscreen/snapped window can be dragged from the top of
// the screen.
if (!window_state->IsMaximized() && !window_state->IsFullscreen() &&
!window_state->IsSnapped()) {
return nullptr;
}
AppType app_type =
static_cast<AppType>(window->GetProperty(aura::client::kAppType));
// App windows can be dragged from the client area (see
// ToplevelWindowEventHandler).
if (app_type != AppType::BROWSER && window_component == HTCLIENT) {
DCHECK_EQ(source, ::wm::WINDOW_MOVE_SOURCE_TOUCH);
window_state->CreateDragDetails(point_in_parent, HTCLIENT,
::wm::WINDOW_MOVE_SOURCE_TOUCH);
std::unique_ptr<WindowResizer> window_resizer =
std::make_unique<TabletModeWindowResizer>(
window_state, std::make_unique<TabletModeWindowDragDelegate>());
return std::make_unique<DragWindowResizer>(std::move(window_resizer),
window_state);
}
// Only allow drag that happens on caption or top area. Note: for a maxmized
// or fullscreen window, the window component here is always HTCAPTION, but
// for a snapped window, the window component here can either be HTCAPTION or
// HTTOP.
if (window_component != HTCAPTION && window_component != HTTOP)
return nullptr;
// Note: only browser windows and chrome app windows are included here.
// For browser windows, this piece of codes will be called no matter the
// drag happens on the tab(s) or on the non-tabstrip caption or top area.
// But for app window, this piece of codes will only be called if the chrome
// app window has its customized caption area and can't be hidden in tablet
// mode (and thus the drag for this type of chrome app window always happens
// on caption or top area). The case where the caption area of the chrome app
// window can be hidden is handled above.
if (app_type != AppType::BROWSER && app_type != AppType::CHROME_APP)
return nullptr;
window_state->CreateDragDetails(point_in_parent, window_component, source);
std::unique_ptr<WindowResizer> window_resizer =
std::make_unique<TabletModeWindowResizer>(
window_state,
std::make_unique<TabletModeBrowserWindowDragDelegate>());
return std::make_unique<DragWindowResizer>(std::move(window_resizer),
window_state);
}
} // namespace
// static
const int WorkspaceWindowResizer::kMinOnscreenSize = 20;
std::unique_ptr<WindowResizer> CreateWindowResizer(
aura::Window* window,
const gfx::PointF& point_in_parent,
int window_component,
::wm::WindowMoveSource source) {
DCHECK(window);
// static
const int WorkspaceWindowResizer::kMinOnscreenHeight = 32;
WindowState* window_state = WindowState::Get(window);
// static
const int WorkspaceWindowResizer::kScreenEdgeInset = 8;
// A resizer already exists; don't create a new one.
if (window_state->drag_details())
return nullptr;
// When running in single app mode, we should not create window resizer.
if (Shell::Get()->session_controller()->IsRunningInAppMode())
return nullptr;
if (window_state->IsPip()) {
window_state->CreateDragDetails(point_in_parent, window_component, source);
return std::make_unique<PipWindowResizer>(window_state);
}
if (Shell::Get()->tablet_mode_controller()->InTabletMode()) {
return CreateWindowResizerForTabletMode(window, point_in_parent,
window_component, source);
}
// No need to return a resizer when the window cannot get resized.
if (!window_state->CanResize() && window_component != HTCAPTION)
return nullptr;
if (!window_state->IsNormalOrSnapped())
return nullptr;
int bounds_change =
WindowResizer::GetBoundsChangeForWindowComponent(window_component);
if (bounds_change == WindowResizer::kBoundsChangeDirection_None)
return nullptr;
window_state->CreateDragDetails(point_in_parent, window_component, source);
// TODO(varkha): The chaining of window resizers causes some of the logic
// to be repeated and the logic flow difficult to control. With some windows
// classes using reparenting during drag operations it becomes challenging to
// implement proper transition from one resizer to another during or at the
// end of the drag. This also causes http://crbug.com/247085.
// We should have a better way of doing this, perhaps by having a way of
// observing drags or having a generic drag window wrapper which informs a
// layout manager that a drag has started or stopped. It may be possible to
// refactor and eliminate chaining.
std::unique_ptr<WindowResizer> window_resizer;
const auto* parent = window->parent();
if (parent &&
// TODO(afakhry): Maybe use switchable containers?
(desks_util::IsDeskContainer(parent) ||
parent->id() == kShellWindowId_AlwaysOnTopContainer)) {
window_resizer.reset(WorkspaceWindowResizer::Create(
window_state, std::vector<aura::Window*>()));
} else {
window_resizer.reset(DefaultWindowResizer::Create(window_state));
}
return std::make_unique<DragWindowResizer>(std::move(window_resizer),
window_state);
}
WorkspaceWindowResizer* WorkspaceWindowResizer::GetInstanceForTest() {
return instance;
@ -405,12 +400,14 @@ class WindowSize {
int max_;
};
constexpr int WorkspaceWindowResizer::kMinOnscreenHeight;
WorkspaceWindowResizer::~WorkspaceWindowResizer() {
if (did_lock_cursor_)
Shell::Get()->cursor_manager()->UnlockCursor();
if (instance == this)
instance = NULL;
instance = nullptr;
}
// static
@ -620,14 +617,7 @@ WorkspaceWindowResizer::WorkspaceWindowResizer(
const std::vector<aura::Window*>& attached_windows)
: WindowResizer(window_state),
attached_windows_(attached_windows),
did_lock_cursor_(false),
did_move_or_resize_(false),
initial_bounds_changed_by_user_(window_state_->bounds_changed_by_user()),
total_min_(0),
total_initial_size_(0),
snap_type_(SNAP_NONE),
num_mouse_moves_since_bounds_change_(0),
magnetism_window_(nullptr) {
initial_bounds_changed_by_user_(window_state_->bounds_changed_by_user()) {
DCHECK(details().is_resizable);
// A mousemove should still show the cursor even if the window is

@ -34,22 +34,9 @@ class WindowState;
// attempt to restore the old height.
class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer {
public:
// When dragging an attached window this is the min size we'll make sure is
// visible. In the vertical direction we take the max of this and that from
// the delegate.
static const int kMinOnscreenSize;
// Min height we'll force on screen when dragging the caption.
// TODO: this should come from a property on the window.
static const int kMinOnscreenHeight;
// Snap region when dragging close to the edges. That is, as the window gets
// this close to an edge of the screen it snaps to the edge.
static const int kScreenEdgeInset;
// Distance in pixels that the cursor must move past an edge for a window
// to move or resize beyond that edge.
static const int kStickyDistancePixels;
static constexpr int kMinOnscreenHeight = 32;
~WorkspaceWindowResizer() override;
@ -179,41 +166,36 @@ class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer {
// Returns the currently used instance for test.
static WorkspaceWindowResizer* GetInstanceForTest();
bool did_lock_cursor_;
bool did_lock_cursor_ = false;
// Set to true once Drag() is invoked and the bounds of the window change.
bool did_move_or_resize_;
bool did_move_or_resize_ = false;
// True if the window initially had |bounds_changed_by_user_| set in state.
bool initial_bounds_changed_by_user_;
const bool initial_bounds_changed_by_user_;
// The initial size of each of the windows in |attached_windows_| along the
// primary axis.
std::vector<int> initial_size_;
// Sum of the minimum sizes of the attached windows.
int total_min_;
int total_min_ = 0;
// Sum of the sizes in |initial_size_|.
int total_initial_size_;
int total_initial_size_ = 0;
// Gives a previews of where the the window will end up. Only used if there
// is a grid and the caption is being dragged.
std::unique_ptr<PhantomWindowController> snap_phantom_window_controller_;
// The edge to which the window should be snapped to at the end of the drag.
SnapType snap_type_;
// Number of mouse moves since the last bounds change. Only used for phantom
// placement to track when the mouse is moved while pushed against the edge of
// the screen.
int num_mouse_moves_since_bounds_change_;
SnapType snap_type_ = SNAP_NONE;
// The mouse location passed to Drag().
gfx::PointF last_mouse_location_;
// Window the drag has magnetically attached to.
aura::Window* magnetism_window_;
aura::Window* magnetism_window_ = nullptr;
// Used to verify |magnetism_window_| is still valid.
aura::WindowTracker window_tracker_;

@ -17,7 +17,6 @@
#include "ash/wm/workspace/phantom_window_controller.h"
#include "ash/wm/workspace_controller.h"
#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/time/time.h"
@ -158,15 +157,13 @@ class WorkspaceWindowResizerTest : public AshTestBase {
// Returns a string identifying the z-order of each of the known child windows
// of |parent|. The returned string constains the id of the known windows and
// is ordered from topmost to bottomost windows.
std::string WindowOrderAsString(aura::Window* parent) const {
std::string result;
std::vector<int> WindowOrderAsIntVector(aura::Window* parent) const {
std::vector<int> result;
const aura::Window::Windows& windows = parent->children();
for (aura::Window::Windows::const_reverse_iterator i = windows.rbegin();
i != windows.rend(); ++i) {
if (*i == window_.get() || *i == window2_.get() || *i == window3_.get()) {
if (!result.empty())
result += " ";
result += base::NumberToString((*i)->id());
result.push_back((*i)->id());
}
}
return result;
@ -633,10 +630,9 @@ TEST_F(WorkspaceWindowResizerTest, Edge) {
EXPECT_EQ(root_windows[0], window_->GetRootWindow());
resizer->CompleteDrag();
EXPECT_EQ(root_windows[1], window_->GetRootWindow());
EXPECT_EQ("0,0 250x" + base::NumberToString(bottom),
window_->bounds().ToString());
EXPECT_EQ("820,30 400x60",
window_state->GetRestoreBoundsInScreen().ToString());
EXPECT_EQ(gfx::Rect(250, bottom), window_->bounds());
EXPECT_EQ(gfx::Rect(820, 30, 400, 60),
window_state->GetRestoreBoundsInScreen());
}
// Restore the window to clear snapped state.
@ -658,10 +654,9 @@ TEST_F(WorkspaceWindowResizerTest, Edge) {
screen_util::GetDisplayWorkAreaBoundsInParent(window_.get()).bottom();
resizer->CompleteDrag();
// TODO(varkha): Insets are updated because of http://crbug.com/292238
EXPECT_EQ("250,0 250x" + base::NumberToString(bottom),
window_->bounds().ToString());
EXPECT_EQ("820,30 400x60",
window_state->GetRestoreBoundsInScreen().ToString());
EXPECT_EQ(gfx::Rect(250, 0, 250, bottom), window_->bounds());
EXPECT_EQ(gfx::Rect(820, 30, 400, 60),
window_state->GetRestoreBoundsInScreen());
}
}
@ -812,7 +807,8 @@ TEST_F(WorkspaceWindowResizerTest, RestackAttached) {
resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
// 2 should be topmost since it's initially the highest in the stack.
EXPECT_EQ("2 1 3", WindowOrderAsString(window_->parent()));
const std::vector<int> expected_order = {2, 1, 3};
EXPECT_EQ(expected_order, WindowOrderAsIntVector(window_->parent()));
}
{
@ -826,7 +822,8 @@ TEST_F(WorkspaceWindowResizerTest, RestackAttached) {
resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
// 2 should be topmost since it's initially the highest in the stack.
EXPECT_EQ("2 3 1", WindowOrderAsString(window_->parent()));
const std::vector<int> expected_order = {2, 3, 1};
EXPECT_EQ(expected_order, WindowOrderAsIntVector(window_->parent()));
}
}
@ -844,8 +841,7 @@ TEST_F(WorkspaceWindowResizerTest, DontDragOffBottom) {
resizer->Drag(CalculateDragPoint(*resizer, 0, 600), 0);
int expected_y =
kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
EXPECT_EQ("100," + base::NumberToString(expected_y) + " 300x400",
window_->bounds().ToString());
EXPECT_EQ(gfx::Rect(100, expected_y, 300, 400), window_->bounds());
}
// Makes sure we don't allow dragging on the work area with multidisplay.
@ -874,8 +870,7 @@ TEST_F(WorkspaceWindowResizerTest, DontDragOffBottomWithMultiDisplay) {
// When the mouse cursor is in the primary display, the window cannot move
// on non-work area but can get all the way towards the bottom,
// restricted only by the window height.
EXPECT_EQ("100," + base::NumberToString(expected_y) + " 300x20",
window_->bounds().ToString());
EXPECT_EQ(gfx::Rect(100, expected_y, 300, 20), window_->bounds());
// Revert the drag in order to not remember the restore bounds.
resizer->RevertDrag();
}
@ -893,8 +888,7 @@ TEST_F(WorkspaceWindowResizerTest, DontDragOffBottomWithMultiDisplay) {
kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
// When the mouse cursor is in the primary display, the window cannot move
// on non-work area with kMinOnscreenHeight margin.
EXPECT_EQ("100," + base::NumberToString(expected_y) + " 300x400",
window_->bounds().ToString());
EXPECT_EQ(gfx::Rect(100, expected_y, 300, 400), window_->bounds());
resizer->CompleteDrag();
}
@ -949,9 +943,8 @@ TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideLeftWorkArea) {
window_.get(), gfx::Point(pixels_to_left_border, 0), HTRIGHT));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, -window_width, 0), 0);
EXPECT_EQ(base::NumberToString(window_x) + ",100 " +
base::NumberToString(kMinimumOnScreenArea - window_x) + "x380",
window_->bounds().ToString());
EXPECT_EQ(gfx::Rect(window_x, 100, kMinimumOnScreenArea - window_x, 380),
window_->bounds());
}
TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideRightWorkArea) {
@ -967,11 +960,11 @@ TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideRightWorkArea) {
CreateResizerForTest(window_.get(), gfx::Point(window_x, 0), HTLEFT));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
EXPECT_EQ(base::NumberToString(right - kMinimumOnScreenArea) + ",100 " +
base::NumberToString(window_width - pixels_to_right_border +
kMinimumOnScreenArea) +
"x380",
window_->bounds().ToString());
EXPECT_EQ(
gfx::Rect(right - kMinimumOnScreenArea, 100,
window_width - pixels_to_right_border + kMinimumOnScreenArea,
380),
window_->bounds());
}
TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideBottomWorkArea) {
@ -986,11 +979,9 @@ TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideBottomWorkArea) {
window_.get(), gfx::Point(0, bottom - delta_to_bottom), HTTOP));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, 0, bottom), 0);
EXPECT_EQ("100," + base::NumberToString(bottom - kMinimumOnScreenArea) +
" 300x" +
base::NumberToString(height -
(delta_to_bottom - kMinimumOnScreenArea)),
window_->bounds().ToString());
EXPECT_EQ(gfx::Rect(100, bottom - kMinimumOnScreenArea, 300,
height - (delta_to_bottom - kMinimumOnScreenArea)),
window_->bounds());
}
// Verifies that 'outside' check of the resizer take into account the extended
@ -1010,9 +1001,8 @@ TEST_F(WorkspaceWindowResizerTest, DragWindowOutsideRightToSecondaryDisplay) {
CreateResizerForTest(window_.get(), gfx::Point(window_x, 0), HTCAPTION));
ASSERT_TRUE(resizer.get());
resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
EXPECT_EQ(base::NumberToString(right - kMinimumOnScreenArea) + ",100 " +
base::NumberToString(window_width) + "x380",
window_->bounds().ToString());
EXPECT_EQ(gfx::Rect(right - kMinimumOnScreenArea, 100, window_width, 380),
window_->bounds());
// With secondary display. Operation itself is same but doesn't change
// the position because the window is still within the secondary display.
@ -1021,9 +1011,8 @@ TEST_F(WorkspaceWindowResizerTest, DragWindowOutsideRightToSecondaryDisplay) {
gfx::Insets(0, 0, 50, 0));
window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
EXPECT_EQ(base::NumberToString(window_x + window_width) + ",100 " +
base::NumberToString(window_width) + "x380",
window_->bounds().ToString());
EXPECT_EQ(gfx::Rect(window_x + window_width, 100, window_width, 380),
window_->bounds());
}
// Verifies snapping to edges works.