Adding proper dragging behavior for L/R maximized windows.
BUG=141750 TEST=unit tests & visual Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=155840 Review URL: https://chromiumcodereview.appspot.com/10918077 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@156058 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
#include "ash/shell.h"
|
#include "ash/shell.h"
|
||||||
#include "ash/wm/coordinate_conversion.h"
|
#include "ash/wm/coordinate_conversion.h"
|
||||||
#include "ash/wm/cursor_manager.h"
|
#include "ash/wm/cursor_manager.h"
|
||||||
|
#include "ash/wm/property_util.h"
|
||||||
#include "ui/aura/client/aura_constants.h"
|
#include "ui/aura/client/aura_constants.h"
|
||||||
#include "ui/aura/env.h"
|
#include "ui/aura/env.h"
|
||||||
#include "ui/aura/root_window.h"
|
#include "ui/aura/root_window.h"
|
||||||
@@ -42,6 +43,8 @@ void DefaultWindowResizer::Drag(const gfx::Point& location, int event_flags) {
|
|||||||
|
|
||||||
gfx::Rect bounds(CalculateBoundsForDrag(details_, location));
|
gfx::Rect bounds(CalculateBoundsForDrag(details_, location));
|
||||||
if (bounds != details_.window->bounds()) {
|
if (bounds != details_.window->bounds()) {
|
||||||
|
if (!did_move_or_resize_ && !details_.restore_bounds.IsEmpty())
|
||||||
|
ClearRestoreBounds(details_.window);
|
||||||
did_move_or_resize_ = true;
|
did_move_or_resize_ = true;
|
||||||
details_.window->SetBounds(bounds);
|
details_.window->SetBounds(bounds);
|
||||||
}
|
}
|
||||||
@@ -55,6 +58,9 @@ void DefaultWindowResizer::RevertDrag() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
details_.window->SetBounds(details_.initial_bounds);
|
details_.window->SetBounds(details_.initial_bounds);
|
||||||
|
|
||||||
|
if (!details_.restore_bounds.IsEmpty())
|
||||||
|
SetRestoreBoundsInScreen(details_.window, details_.restore_bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
aura::Window* DefaultWindowResizer::GetTarget() {
|
aura::Window* DefaultWindowResizer::GetTarget() {
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
#include "ash/ash_constants.h"
|
#include "ash/ash_constants.h"
|
||||||
#include "ash/shell.h"
|
#include "ash/shell.h"
|
||||||
#include "ash/shell_window_ids.h"
|
#include "ash/shell_window_ids.h"
|
||||||
|
#include "ash/wm/property_util.h"
|
||||||
#include "ash/wm/window_util.h"
|
#include "ash/wm/window_util.h"
|
||||||
#include "ash/wm/workspace_controller.h"
|
#include "ash/wm/workspace_controller.h"
|
||||||
#include "base/logging.h" // DCHECK
|
#include "base/logging.h" // DCHECK
|
||||||
@@ -26,6 +27,7 @@
|
|||||||
#include "ui/gfx/canvas.h"
|
#include "ui/gfx/canvas.h"
|
||||||
#include "ui/gfx/font.h"
|
#include "ui/gfx/font.h"
|
||||||
#include "ui/gfx/image/image.h"
|
#include "ui/gfx/image/image.h"
|
||||||
|
#include "ui/gfx/screen.h"
|
||||||
#include "ui/views/controls/button/image_button.h"
|
#include "ui/views/controls/button/image_button.h"
|
||||||
#include "ui/views/widget/widget.h"
|
#include "ui/views/widget/widget.h"
|
||||||
#include "ui/views/widget/widget_delegate.h"
|
#include "ui/views/widget/widget_delegate.h"
|
||||||
@@ -246,6 +248,7 @@ int FramePainter::NonClientHitTest(views::NonClientFrameView* view,
|
|||||||
kResizeAreaCornerSize,
|
kResizeAreaCornerSize,
|
||||||
kResizeAreaCornerSize,
|
kResizeAreaCornerSize,
|
||||||
can_ever_resize);
|
can_ever_resize);
|
||||||
|
frame_component = AdjustFrameHitCodeForMaximizedModes(frame_component);
|
||||||
if (frame_component != HTNOWHERE)
|
if (frame_component != HTNOWHERE)
|
||||||
return frame_component;
|
return frame_component;
|
||||||
|
|
||||||
@@ -610,6 +613,43 @@ int FramePainter::GetHeaderOpacity(HeaderMode header_mode,
|
|||||||
return kInactiveWindowOpacity;
|
return kInactiveWindowOpacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FramePainter::AdjustFrameHitCodeForMaximizedModes(int hit_code) {
|
||||||
|
if (hit_code != HTNOWHERE && wm::IsWindowNormal(window_) &&
|
||||||
|
GetRestoreBoundsInScreen(window_)) {
|
||||||
|
// When there is a restore rectangle, a left/right maximized window might
|
||||||
|
// be active.
|
||||||
|
const gfx::Rect& bounds = frame_->GetWindowBoundsInScreen();
|
||||||
|
const gfx::Rect& screen =
|
||||||
|
gfx::Screen::GetDisplayMatching(bounds).work_area();
|
||||||
|
if (bounds.y() == screen.y() && bounds.bottom() == screen.bottom()) {
|
||||||
|
// The window is probably either left or right maximized.
|
||||||
|
if (bounds.x() == screen.x()) {
|
||||||
|
// It is left maximized and we can only allow a right resize.
|
||||||
|
return (hit_code == HTBOTTOMRIGHT ||
|
||||||
|
hit_code == HTTOPRIGHT ||
|
||||||
|
hit_code == HTRIGHT) ? HTRIGHT : HTNOWHERE;
|
||||||
|
} else if (bounds.right() == screen.right()) {
|
||||||
|
// It is right maximized and we can only allow a left resize.
|
||||||
|
return (hit_code == HTBOTTOMLEFT ||
|
||||||
|
hit_code == HTTOPLEFT ||
|
||||||
|
hit_code == HTLEFT) ? HTLEFT : HTNOWHERE;
|
||||||
|
}
|
||||||
|
} else if (bounds.x() == screen.x() &&
|
||||||
|
bounds.right() == screen.right()) {
|
||||||
|
// If horizontal fill mode is activated we don't allow a left/right
|
||||||
|
// resizing.
|
||||||
|
if (hit_code == HTTOPRIGHT ||
|
||||||
|
hit_code == HTTOP ||
|
||||||
|
hit_code == HTTOPLEFT)
|
||||||
|
return HTTOP;
|
||||||
|
return (hit_code == HTBOTTOMRIGHT ||
|
||||||
|
hit_code == HTBOTTOM ||
|
||||||
|
hit_code == HTBOTTOMLEFT) ? HTBOTTOM : HTNOWHERE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hit_code;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool FramePainter::UseSoloWindowHeader() {
|
bool FramePainter::UseSoloWindowHeader() {
|
||||||
if (!instances_)
|
if (!instances_)
|
||||||
|
@@ -141,6 +141,9 @@ class ASH_EXPORT FramePainter : public aura::WindowObserver,
|
|||||||
int theme_frame_id,
|
int theme_frame_id,
|
||||||
const gfx::ImageSkia* theme_frame_overlay);
|
const gfx::ImageSkia* theme_frame_overlay);
|
||||||
|
|
||||||
|
// Adjust frame operations for left / right maximized modes.
|
||||||
|
int AdjustFrameHitCodeForMaximizedModes(int hit_code);
|
||||||
|
|
||||||
// Returns true if there is exactly one visible, normal-type window using
|
// Returns true if there is exactly one visible, normal-type window using
|
||||||
// a header painted by this class, in which case we should paint a transparent
|
// a header painted by this class, in which case we should paint a transparent
|
||||||
// window header.
|
// window header.
|
||||||
|
@@ -7,18 +7,40 @@
|
|||||||
#include "ash/shell.h"
|
#include "ash/shell.h"
|
||||||
#include "ash/shell_window_ids.h"
|
#include "ash/shell_window_ids.h"
|
||||||
#include "ash/test/ash_test_base.h"
|
#include "ash/test/ash_test_base.h"
|
||||||
|
#include "ash/wm/property_util.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
#include "grit/ui_resources.h"
|
#include "grit/ui_resources.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
#include "ui/aura/root_window.h"
|
#include "ui/aura/root_window.h"
|
||||||
|
#include "ui/base/hit_test.h"
|
||||||
|
#include "ui/gfx/screen.h"
|
||||||
#include "ui/views/controls/button/image_button.h"
|
#include "ui/views/controls/button/image_button.h"
|
||||||
#include "ui/views/widget/widget.h"
|
#include "ui/views/widget/widget.h"
|
||||||
|
#include "ui/views/widget/widget_delegate.h"
|
||||||
|
#include "ui/views/window/non_client_view.h"
|
||||||
|
|
||||||
using views::Widget;
|
using views::Widget;
|
||||||
using views::ImageButton;
|
using views::ImageButton;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
class ResizableWidgetDelegate : public views::WidgetDelegate {
|
||||||
|
public:
|
||||||
|
ResizableWidgetDelegate(views::Widget* widget) {
|
||||||
|
widget_ = widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool CanResize() const OVERRIDE { return true; }
|
||||||
|
// Implementations of the widget class.
|
||||||
|
virtual views::Widget* GetWidget() OVERRIDE { return widget_; }
|
||||||
|
virtual const views::Widget* GetWidget() const OVERRIDE { return widget_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
views::Widget* widget_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ResizableWidgetDelegate);
|
||||||
|
};
|
||||||
|
|
||||||
// Creates a test widget that owns its native widget.
|
// Creates a test widget that owns its native widget.
|
||||||
Widget* CreateTestWidget() {
|
Widget* CreateTestWidget() {
|
||||||
Widget* widget = new Widget;
|
Widget* widget = new Widget;
|
||||||
@@ -37,6 +59,17 @@ Widget* CreateAlwaysOnTopWidget() {
|
|||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget* CreateResizableWidget() {
|
||||||
|
Widget* widget = new Widget;
|
||||||
|
Widget::InitParams params;
|
||||||
|
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
||||||
|
params.keep_on_top = true;
|
||||||
|
params.delegate = new ResizableWidgetDelegate(widget);
|
||||||
|
params.type = Widget::InitParams::TYPE_WINDOW;
|
||||||
|
widget->Init(params);
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace ash {
|
namespace ash {
|
||||||
@@ -161,4 +194,38 @@ TEST_F(FramePainterTest, GetHeaderOpacity) {
|
|||||||
&custom_overlay));
|
&custom_overlay));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test the hit test function with windows which are "partially maximized".
|
||||||
|
TEST_F(FramePainterTest, HitTestSpecialMaximizedModes) {
|
||||||
|
// Create a widget and a painter for it.
|
||||||
|
scoped_ptr<Widget> w1(CreateResizableWidget());
|
||||||
|
FramePainter p1;
|
||||||
|
ImageButton size1(NULL);
|
||||||
|
ImageButton close1(NULL);
|
||||||
|
p1.Init(w1.get(), NULL, &size1, &close1, FramePainter::SIZE_BUTTON_MAXIMIZES);
|
||||||
|
views::NonClientFrameView* frame = w1->non_client_view()->frame_view();
|
||||||
|
w1->Show();
|
||||||
|
gfx::Rect any_rect = gfx::Rect(0, 0, 100, 100);
|
||||||
|
gfx::Rect screen = gfx::Screen::GetDisplayMatching(any_rect).work_area();
|
||||||
|
w1->SetBounds(any_rect);
|
||||||
|
EXPECT_EQ(HTTOPLEFT, p1.NonClientHitTest(frame, gfx::Point(0, 15)));
|
||||||
|
w1->SetBounds(gfx::Rect(
|
||||||
|
screen.x(), screen.y(), screen.width() / 2, screen.height()));
|
||||||
|
// A hit without a set restore rect should produce a top left hit.
|
||||||
|
EXPECT_EQ(HTTOPLEFT, p1.NonClientHitTest(frame, gfx::Point(0, 15)));
|
||||||
|
ash::SetRestoreBoundsInScreen(w1->GetNativeWindow(), any_rect);
|
||||||
|
// A hit into the corner should produce nowhere - not left.
|
||||||
|
EXPECT_EQ(HTCAPTION, p1.NonClientHitTest(frame, gfx::Point(0, 15)));
|
||||||
|
// A hit into the middle upper area should generate right - not top&right.
|
||||||
|
EXPECT_EQ(HTRIGHT,
|
||||||
|
p1.NonClientHitTest(frame, gfx::Point(screen.width() / 2, 15)));
|
||||||
|
// A hit into the middle should generate right.
|
||||||
|
EXPECT_EQ(HTRIGHT,
|
||||||
|
p1.NonClientHitTest(frame, gfx::Point(screen.width() / 2,
|
||||||
|
screen.height() / 2)));
|
||||||
|
// A hit into the middle lower area should generate right - not bottom&right.
|
||||||
|
EXPECT_EQ(HTRIGHT,
|
||||||
|
p1.NonClientHitTest(frame, gfx::Point(screen.width() / 2,
|
||||||
|
screen.height() - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ash
|
} // namespace ash
|
||||||
|
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include "ash/screen_ash.h"
|
#include "ash/screen_ash.h"
|
||||||
#include "ash/shell.h"
|
#include "ash/shell.h"
|
||||||
|
#include "ash/wm/property_util.h"
|
||||||
|
#include "ash/wm/window_util.h"
|
||||||
#include "ui/aura/client/aura_constants.h"
|
#include "ui/aura/client/aura_constants.h"
|
||||||
#include "ui/aura/root_window.h"
|
#include "ui/aura/root_window.h"
|
||||||
#include "ui/aura/window.h"
|
#include "ui/aura/window.h"
|
||||||
@@ -112,6 +114,7 @@ WindowResizer::Details::Details(aura::Window* window,
|
|||||||
int window_component)
|
int window_component)
|
||||||
: window(window),
|
: window(window),
|
||||||
initial_bounds(window->bounds()),
|
initial_bounds(window->bounds()),
|
||||||
|
restore_bounds(gfx::Rect()),
|
||||||
initial_location_in_parent(location),
|
initial_location_in_parent(location),
|
||||||
initial_opacity(window->layer()->opacity()),
|
initial_opacity(window->layer()->opacity()),
|
||||||
window_component(window_component),
|
window_component(window_component),
|
||||||
@@ -121,6 +124,10 @@ WindowResizer::Details::Details(aura::Window* window,
|
|||||||
size_change_direction(
|
size_change_direction(
|
||||||
GetSizeChangeDirectionForWindowComponent(window_component)),
|
GetSizeChangeDirectionForWindowComponent(window_component)),
|
||||||
is_resizable(bounds_change != kBoundsChangeDirection_None) {
|
is_resizable(bounds_change != kBoundsChangeDirection_None) {
|
||||||
|
if (wm::IsWindowNormal(window) &&
|
||||||
|
GetRestoreBoundsInScreen(window) &&
|
||||||
|
window_component == HTCAPTION)
|
||||||
|
restore_bounds = *GetRestoreBoundsInScreen(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowResizer::Details::~Details() {
|
WindowResizer::Details::~Details() {
|
||||||
@@ -175,6 +182,17 @@ gfx::Rect WindowResizer::CalculateBoundsForDrag(
|
|||||||
gfx::Size size = GetSizeForDrag(details, &delta_x, &delta_y);
|
gfx::Size size = GetSizeForDrag(details, &delta_x, &delta_y);
|
||||||
gfx::Point origin = GetOriginForDrag(details, delta_x, delta_y);
|
gfx::Point origin = GetOriginForDrag(details, delta_x, delta_y);
|
||||||
|
|
||||||
|
// When we might want to reposition a window which is also restored to its
|
||||||
|
// previous size, to keep the cursor within the dragged window.
|
||||||
|
if (!details.restore_bounds.IsEmpty() &&
|
||||||
|
details.bounds_change & kBoundsChange_Repositions) {
|
||||||
|
// However - it is not desirable to change the origin if the window would
|
||||||
|
// be still hit by the cursor.
|
||||||
|
if (details.initial_location_in_parent.x() >
|
||||||
|
details.initial_bounds.x() + details.restore_bounds.width())
|
||||||
|
origin.set_x(location.x() - details.restore_bounds.width() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
gfx::Rect new_bounds(origin, size);
|
gfx::Rect new_bounds(origin, size);
|
||||||
// Update bottom edge to stay in the work area when we are resizing
|
// Update bottom edge to stay in the work area when we are resizing
|
||||||
// by dragging the bottome edge or corners.
|
// by dragging the bottome edge or corners.
|
||||||
@@ -229,6 +247,8 @@ gfx::Size WindowResizer::GetSizeForDrag(const Details& details,
|
|||||||
gfx::Size min_size = details.window->delegate()->GetMinimumSize();
|
gfx::Size min_size = details.window->delegate()->GetMinimumSize();
|
||||||
size.SetSize(GetWidthForDrag(details, min_size.width(), delta_x),
|
size.SetSize(GetWidthForDrag(details, min_size.width(), delta_x),
|
||||||
GetHeightForDrag(details, min_size.height(), delta_y));
|
GetHeightForDrag(details, min_size.height(), delta_y));
|
||||||
|
} else if (!details.restore_bounds.IsEmpty()) {
|
||||||
|
size = details.restore_bounds.size();
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@@ -64,6 +64,10 @@ class ASH_EXPORT WindowResizer {
|
|||||||
// Initial bounds of the window.
|
// Initial bounds of the window.
|
||||||
gfx::Rect initial_bounds;
|
gfx::Rect initial_bounds;
|
||||||
|
|
||||||
|
// Restore bounds (in screen coordinates) of the window before the drag
|
||||||
|
// started. Only set if the window is normal and is being dragged.
|
||||||
|
gfx::Rect restore_bounds;
|
||||||
|
|
||||||
// Location passed to the constructor, in |window->parent()|'s coordinates.
|
// Location passed to the constructor, in |window->parent()|'s coordinates.
|
||||||
gfx::Point initial_location_in_parent;
|
gfx::Point initial_location_in_parent;
|
||||||
|
|
||||||
|
@@ -553,9 +553,12 @@ MaximizeBubbleFrameState
|
|||||||
gfx::Rect screen = gfx::Screen::GetDisplayMatching(bounds).work_area();
|
gfx::Rect screen = gfx::Screen::GetDisplayMatching(bounds).work_area();
|
||||||
if (bounds.width() < (screen.width() * kMinSnapSizePercent) / 100)
|
if (bounds.width() < (screen.width() * kMinSnapSizePercent) / 100)
|
||||||
return FRAME_STATE_NONE;
|
return FRAME_STATE_NONE;
|
||||||
|
// We might still have a horizontally filled window at this point which we
|
||||||
|
// treat as no special state.
|
||||||
|
if (bounds.y() != screen.y() || bounds.height() != screen.height())
|
||||||
|
return FRAME_STATE_NONE;
|
||||||
|
|
||||||
// We have to be in a maximize mode at this point.
|
// We have to be in a maximize mode at this point.
|
||||||
DCHECK(bounds.y() == screen.y());
|
|
||||||
DCHECK(bounds.height() >= screen.height());
|
|
||||||
if (bounds.x() == screen.x())
|
if (bounds.x() == screen.x())
|
||||||
return FRAME_STATE_SNAP_LEFT;
|
return FRAME_STATE_SNAP_LEFT;
|
||||||
if (bounds.right() == screen.right())
|
if (bounds.right() == screen.right())
|
||||||
|
@@ -125,8 +125,11 @@ void WorkspaceWindowResizer::Drag(const gfx::Point& location, int event_flags) {
|
|||||||
if (wm::IsWindowNormal(window()))
|
if (wm::IsWindowNormal(window()))
|
||||||
AdjustBoundsForMainWindow(&bounds, grid_size);
|
AdjustBoundsForMainWindow(&bounds, grid_size);
|
||||||
if (bounds != window()->bounds()) {
|
if (bounds != window()->bounds()) {
|
||||||
if (!did_move_or_resize_)
|
if (!did_move_or_resize_) {
|
||||||
|
if (!details_.restore_bounds.IsEmpty())
|
||||||
|
ClearRestoreBounds(window());
|
||||||
RestackWindows();
|
RestackWindows();
|
||||||
|
}
|
||||||
did_move_or_resize_ = true;
|
did_move_or_resize_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +167,9 @@ void WorkspaceWindowResizer::CompleteDrag(int event_flags) {
|
|||||||
|
|
||||||
if (snap_type_ == SNAP_LEFT_EDGE || snap_type_ == SNAP_RIGHT_EDGE) {
|
if (snap_type_ == SNAP_LEFT_EDGE || snap_type_ == SNAP_RIGHT_EDGE) {
|
||||||
if (!GetRestoreBoundsInScreen(window()))
|
if (!GetRestoreBoundsInScreen(window()))
|
||||||
SetRestoreBoundsInParent(window(), details_.initial_bounds);
|
SetRestoreBoundsInParent(window(), details_.restore_bounds.IsEmpty() ?
|
||||||
|
details_.initial_bounds :
|
||||||
|
details_.restore_bounds);
|
||||||
window()->SetBounds(snap_sizer_->target_bounds());
|
window()->SetBounds(snap_sizer_->target_bounds());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -196,6 +201,9 @@ void WorkspaceWindowResizer::RevertDrag() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
window()->SetBounds(details_.initial_bounds);
|
window()->SetBounds(details_.initial_bounds);
|
||||||
|
if (!details_.restore_bounds.IsEmpty())
|
||||||
|
SetRestoreBoundsInScreen(details_.window, details_.restore_bounds);
|
||||||
|
|
||||||
if (details_.window_component == HTRIGHT) {
|
if (details_.window_component == HTRIGHT) {
|
||||||
int last_x = details_.initial_bounds.right();
|
int last_x = details_.initial_bounds.right();
|
||||||
for (size_t i = 0; i < attached_windows_.size(); ++i) {
|
for (size_t i = 0; i < attached_windows_.size(); ++i) {
|
||||||
|
@@ -458,7 +458,6 @@ TEST_F(WorkspaceWindowResizerTest, Edge) {
|
|||||||
EXPECT_EQ("20,30 50x60",
|
EXPECT_EQ("20,30 50x60",
|
||||||
GetRestoreBoundsInScreen(window_.get())->ToString());
|
GetRestoreBoundsInScreen(window_.get())->ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try the same with the right side.
|
// Try the same with the right side.
|
||||||
scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
|
scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
|
||||||
window_.get(), gfx::Point(), HTCAPTION, empty_windows()));
|
window_.get(), gfx::Point(), HTCAPTION, empty_windows()));
|
||||||
@@ -869,5 +868,37 @@ TEST_F(WorkspaceWindowResizerTest, TestProperSizerResolutions) {
|
|||||||
EXPECT_EQ("0,0 640x552", rect.ToString());
|
EXPECT_EQ("0,0 640x552", rect.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verifies that a dragged window will restore to its pre-maximized size.
|
||||||
|
TEST_F(WorkspaceWindowResizerTest, RestoreToPreMaximizeCoordinates) {
|
||||||
|
window_->SetBounds(gfx::Rect(0, 0, 1000, 1000));
|
||||||
|
SetRestoreBoundsInScreen(window_.get(), gfx::Rect(96, 112, 320, 160));
|
||||||
|
scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
|
||||||
|
window_.get(), gfx::Point(), HTCAPTION, empty_windows()));
|
||||||
|
ASSERT_TRUE(resizer.get());
|
||||||
|
// Drag the window to new position by adding (10, 10) to original point,
|
||||||
|
// the window should get restored.
|
||||||
|
resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0);
|
||||||
|
resizer->CompleteDrag(0);
|
||||||
|
EXPECT_EQ("10,10 320x160", window_->bounds().ToString());
|
||||||
|
// The restore rectangle should get cleared as well.
|
||||||
|
EXPECT_EQ(NULL, GetRestoreBoundsInScreen(window_.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies that a dragged window will restore to its pre-maximized size.
|
||||||
|
TEST_F(WorkspaceWindowResizerTest, RevertResizeOperation) {
|
||||||
|
window_->SetBounds(gfx::Rect(0, 0, 1000, 1000));
|
||||||
|
SetRestoreBoundsInScreen(window_.get(), gfx::Rect(96, 112, 320, 160));
|
||||||
|
scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
|
||||||
|
window_.get(), gfx::Point(), HTCAPTION, empty_windows()));
|
||||||
|
ASSERT_TRUE(resizer.get());
|
||||||
|
// Drag the window to new poistion by adding (180, 16) to original point,
|
||||||
|
// the window should get restored.
|
||||||
|
resizer->Drag(CalculateDragPoint(*resizer, 180, 16), 0);
|
||||||
|
resizer->RevertDrag();
|
||||||
|
EXPECT_EQ("0,0 1000x1000", window_->bounds().ToString());
|
||||||
|
EXPECT_EQ("96,112 320x160",
|
||||||
|
GetRestoreBoundsInScreen(window_.get())->ToString());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace ash
|
} // namespace ash
|
||||||
|
@@ -1258,7 +1258,7 @@ void Widget::SetInitialBounds(const gfx::Rect& bounds) {
|
|||||||
if (GetSavedWindowPlacement(&saved_bounds, &saved_show_state_)) {
|
if (GetSavedWindowPlacement(&saved_bounds, &saved_show_state_)) {
|
||||||
if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED) {
|
if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED) {
|
||||||
// If we're going to maximize, wait until Show is invoked to set the
|
// If we're going to maximize, wait until Show is invoked to set the
|
||||||
// bounds. That way we avoid a noticable resize.
|
// bounds. That way we avoid a noticeable resize.
|
||||||
initial_restored_bounds_ = saved_bounds;
|
initial_restored_bounds_ = saved_bounds;
|
||||||
} else {
|
} else {
|
||||||
SetBounds(saved_bounds);
|
SetBounds(saved_bounds);
|
||||||
|
Reference in New Issue
Block a user