diff options
author | skuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-07 22:36:42 +0000 |
---|---|---|
committer | skuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-07 22:36:42 +0000 |
commit | 2b2273f385daa81166c938ba5c1cde76caeaf629 (patch) | |
tree | ec8f857ec61aeed106b6931e7a7f423021142bbe /ash/wm | |
parent | baefae90f294a981c973bffbdd3eccabfe796b6a (diff) | |
download | chromium_src-2b2273f385daa81166c938ba5c1cde76caeaf629.zip chromium_src-2b2273f385daa81166c938ba5c1cde76caeaf629.tar.gz chromium_src-2b2273f385daa81166c938ba5c1cde76caeaf629.tar.bz2 |
Snap resize windows on touch to 50% when the maximize button is close to the border
BUG=151101
TEST=visual & unit test
Review URL: https://chromiumcodereview.appspot.com/11366099
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@166535 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/wm')
-rw-r--r-- | ash/wm/custom_frame_view_ash_unittest.cc | 70 | ||||
-rw-r--r-- | ash/wm/gestures/system_pinch_handler.cc | 3 | ||||
-rw-r--r-- | ash/wm/gestures/two_finger_drag_handler.cc | 3 | ||||
-rw-r--r-- | ash/wm/toplevel_window_event_handler.cc | 3 | ||||
-rw-r--r-- | ash/wm/toplevel_window_event_handler_unittest.cc | 6 | ||||
-rw-r--r-- | ash/wm/workspace/frame_maximize_button.cc | 19 | ||||
-rw-r--r-- | ash/wm/workspace/frame_maximize_button.h | 8 | ||||
-rw-r--r-- | ash/wm/workspace/snap_sizer.cc | 21 | ||||
-rw-r--r-- | ash/wm/workspace/snap_sizer.h | 21 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_window_resizer.cc | 5 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_window_resizer_unittest.cc | 5 |
11 files changed, 142 insertions, 22 deletions
diff --git a/ash/wm/custom_frame_view_ash_unittest.cc b/ash/wm/custom_frame_view_ash_unittest.cc index 7686743..035e85b 100644 --- a/ash/wm/custom_frame_view_ash_unittest.cc +++ b/ash/wm/custom_frame_view_ash_unittest.cc @@ -172,7 +172,8 @@ TEST_F(CustomFrameViewAshTest, ResizeButtonDrag) { EXPECT_FALSE(ash::wm::IsWindowMaximized(window)); EXPECT_FALSE(ash::wm::IsWindowMinimized(window)); internal::SnapSizer sizer(window, center, - internal::SnapSizer::RIGHT_EDGE); + internal::SnapSizer::RIGHT_EDGE, + internal::SnapSizer::OTHER_INPUT); EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString()); } @@ -188,7 +189,8 @@ TEST_F(CustomFrameViewAshTest, ResizeButtonDrag) { EXPECT_FALSE(ash::wm::IsWindowMaximized(window)); EXPECT_FALSE(ash::wm::IsWindowMinimized(window)); internal::SnapSizer sizer(window, center, - internal::SnapSizer::LEFT_EDGE); + internal::SnapSizer::LEFT_EDGE, + internal::SnapSizer::OTHER_INPUT); EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString()); } @@ -221,7 +223,8 @@ TEST_F(CustomFrameViewAshTest, ResizeButtonDrag) { EXPECT_FALSE(ash::wm::IsWindowMaximized(window)); EXPECT_FALSE(ash::wm::IsWindowMinimized(window)); internal::SnapSizer sizer(window, center, - internal::SnapSizer::RIGHT_EDGE); + internal::SnapSizer::RIGHT_EDGE, + internal::SnapSizer::OTHER_INPUT); EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString()); } @@ -238,7 +241,8 @@ TEST_F(CustomFrameViewAshTest, ResizeButtonDrag) { EXPECT_FALSE(ash::wm::IsWindowMaximized(window)); EXPECT_FALSE(ash::wm::IsWindowMinimized(window)); internal::SnapSizer sizer(window, center, - internal::SnapSizer::LEFT_EDGE); + internal::SnapSizer::LEFT_EDGE, + internal::SnapSizer::OTHER_INPUT); EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString()); } @@ -260,6 +264,61 @@ TEST_F(CustomFrameViewAshTest, ResizeButtonDrag) { widget->Close(); } +// Tests Left/Right snapping with resize button touch dragging - which should +// trigger dependent on the available drag distance. +TEST_F(CustomFrameViewAshTest, TouchDragResizeCloseToCornerDiffersFromMouse) { + views::Widget* widget = CreateWidget(); + aura::Window* window = widget->GetNativeWindow(); + CustomFrameViewAsh* frame = custom_frame_view_ash(widget); + CustomFrameViewAsh::TestApi test(frame); + views::View* view = test.maximize_button(); + + gfx::Rect work_area = widget->GetWorkAreaBoundsInScreen(); + gfx::Rect bounds = window->bounds(); + bounds.set_x(work_area.width() - bounds.width()); + widget->SetBounds(bounds); + + gfx::Point start_point = view->GetBoundsInScreen().CenterPoint(); + // We want to move all the way to the right (the few pixels we have). + gfx::Point end_point = gfx::Point(work_area.width(), start_point.y()); + + aura::test::EventGenerator generator(window->GetRootWindow(), start_point); + + EXPECT_TRUE(ash::wm::IsWindowNormal(window)); + + // Snap right with a touch drag. + generator.GestureScrollSequence(start_point, + end_point, + base::TimeDelta::FromMilliseconds(100), + 10); + RunAllPendingInMessageLoop(); + + EXPECT_FALSE(ash::wm::IsWindowMaximized(window)); + EXPECT_FALSE(ash::wm::IsWindowMinimized(window)); + gfx::Rect touch_result = window->bounds(); + EXPECT_NE(bounds.ToString(), touch_result.ToString()); + + // Set the position back to where it was before and re-try with a mouse. + widget->SetBounds(bounds); + + generator.MoveMouseTo(start_point); + generator.PressLeftButton(); + generator.MoveMouseTo(end_point, 10); + generator.ReleaseLeftButton(); + RunAllPendingInMessageLoop(); + + EXPECT_FALSE(ash::wm::IsWindowMaximized(window)); + EXPECT_FALSE(ash::wm::IsWindowMinimized(window)); + gfx::Rect mouse_result = window->bounds(); + + // The difference between the two operations should be that the mouse + // operation should have just started to resize and the touch operation is + // already all the way down to the smallest possible size. + EXPECT_NE(mouse_result.ToString(), touch_result.ToString()); + EXPECT_GT(mouse_result.width(), touch_result.width()); +} + + // Test that closing the (browser) window with an opened balloon does not // crash the system. In other words: Make sure that shutting down the frame // destroys the opened balloon in an orderly fashion. @@ -369,7 +428,8 @@ TEST_F(CustomFrameViewAshTest, MaximizeLeftByButton) { EXPECT_FALSE(ash::wm::IsWindowMaximized(window)); EXPECT_FALSE(ash::wm::IsWindowMinimized(window)); internal::SnapSizer sizer(window, button_pos, - internal::SnapSizer::LEFT_EDGE); + internal::SnapSizer::LEFT_EDGE, + internal::SnapSizer::OTHER_INPUT); sizer.SelectDefaultSizeAndDisableResize(); EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString()); } diff --git a/ash/wm/gestures/system_pinch_handler.cc b/ash/wm/gestures/system_pinch_handler.cc index 2f519b0..f34836c 100644 --- a/ash/wm/gestures/system_pinch_handler.cc +++ b/ash/wm/gestures/system_pinch_handler.cc @@ -95,7 +95,8 @@ SystemGestureStatus SystemPinchHandler::ProcessGestureEvent( SnapSizer sizer(target_, gfx::Point(), event.details().swipe_left() ? internal::SnapSizer::LEFT_EDGE : - internal::SnapSizer::RIGHT_EDGE); + internal::SnapSizer::RIGHT_EDGE, + internal::SnapSizer::OTHER_INPUT); target_->SetBounds(sizer.GetSnapBounds(target_->bounds())); } else if (event.details().swipe_up()) { if (!wm::IsWindowMaximized(target_) && diff --git a/ash/wm/gestures/two_finger_drag_handler.cc b/ash/wm/gestures/two_finger_drag_handler.cc index 7ed214a..a450a27 100644 --- a/ash/wm/gestures/two_finger_drag_handler.cc +++ b/ash/wm/gestures/two_finger_drag_handler.cc @@ -136,7 +136,8 @@ bool TwoFingerDragHandler::ProcessGestureEvent(aura::Window* target, internal::SnapSizer sizer(target, gfx::Point(), event.details().swipe_left() ? internal::SnapSizer::LEFT_EDGE : - internal::SnapSizer::RIGHT_EDGE); + internal::SnapSizer::RIGHT_EDGE, + internal::SnapSizer::OTHER_INPUT); ui::ScopedLayerAnimationSettings scoped_setter( target->layer()->GetAnimator()); diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc index 1f39054..c8d5769 100644 --- a/ash/wm/toplevel_window_event_handler.cc +++ b/ash/wm/toplevel_window_event_handler.cc @@ -225,7 +225,8 @@ ui::EventResult ToplevelWindowEventHandler::OnGestureEvent( internal::SnapSizer sizer(target, gfx::Point(), event->details().velocity_x() < 0 ? internal::SnapSizer::LEFT_EDGE : - internal::SnapSizer::RIGHT_EDGE); + internal::SnapSizer::RIGHT_EDGE, + internal::SnapSizer::OTHER_INPUT); ui::ScopedLayerAnimationSettings scoped_setter( target->layer()->GetAnimator()); diff --git a/ash/wm/toplevel_window_event_handler_unittest.cc b/ash/wm/toplevel_window_event_handler_unittest.cc index ddee670..e29df87 100644 --- a/ash/wm/toplevel_window_event_handler_unittest.cc +++ b/ash/wm/toplevel_window_event_handler_unittest.cc @@ -414,7 +414,8 @@ TEST_F(ToplevelWindowEventHandlerTest, GestureDrag) { EXPECT_NE(old_bounds.ToString(), target->bounds().ToString()); { internal::SnapSizer sizer(target.get(), location, - internal::SnapSizer::RIGHT_EDGE); + internal::SnapSizer::RIGHT_EDGE, + internal::SnapSizer::OTHER_INPUT); EXPECT_EQ(sizer.target_bounds().ToString(), target->bounds().ToString()); } @@ -431,7 +432,8 @@ TEST_F(ToplevelWindowEventHandlerTest, GestureDrag) { EXPECT_NE(old_bounds.ToString(), target->bounds().ToString()); { internal::SnapSizer sizer(target.get(), location, - internal::SnapSizer::LEFT_EDGE); + internal::SnapSizer::LEFT_EDGE, + internal::SnapSizer::OTHER_INPUT); EXPECT_EQ(sizer.target_bounds().ToString(), target->bounds().ToString()); } diff --git a/ash/wm/workspace/frame_maximize_button.cc b/ash/wm/workspace/frame_maximize_button.cc index 876c82c..29a9e45 100644 --- a/ash/wm/workspace/frame_maximize_button.cc +++ b/ash/wm/workspace/frame_maximize_button.cc @@ -111,6 +111,7 @@ FrameMaximizeButton::FrameMaximizeButton(views::ButtonListener* listener, is_snap_enabled_(false), exceeded_drag_threshold_(false), window_(NULL), + press_is_gesture_(false), snap_type_(SNAP_NONE), bubble_appearance_delay_ms_(kBubbleAppearanceDelayMS) { // TODO(sky): nuke this. It's temporary while we don't have good images. @@ -160,7 +161,9 @@ void FrameMaximizeButton::SnapButtonHovered(SnapType type) { // We should not come here. NOTREACHED(); } - UpdateSnap(location, true); + // Note: There is no hover with touch - we can therefore pass false for touch + // operations. + UpdateSnap(location, true, false); } void FrameMaximizeButton::ExecuteSnapAndCloseMenu(SnapType snap_type) { @@ -326,6 +329,7 @@ void FrameMaximizeButton::ProcessStartEvent(const ui::LocatedEvent& event) { InstallEventFilter(); snap_type_ = SNAP_NONE; press_location_ = event.location(); + press_is_gesture_ = event.IsGestureEvent(); exceeded_drag_threshold_ = false; update_timer_.Start( FROM_HERE, @@ -341,7 +345,7 @@ void FrameMaximizeButton::ProcessUpdateEvent(const ui::LocatedEvent& event) { event.location() - press_location_); } if (exceeded_drag_threshold_) - UpdateSnap(event.location(), false); + UpdateSnap(event.location(), false, event.IsGestureEvent()); } bool FrameMaximizeButton::ProcessEndEvent(const ui::LocatedEvent& event) { @@ -397,11 +401,12 @@ void FrameMaximizeButton::UpdateSnapFromEventLocation() { if (exceeded_drag_threshold_) return; exceeded_drag_threshold_ = true; - UpdateSnap(press_location_, false); + UpdateSnap(press_location_, false, press_is_gesture_); } void FrameMaximizeButton::UpdateSnap(const gfx::Point& location, - bool select_default) { + bool select_default, + bool is_touch) { SnapType type = SnapTypeForLocation(location); if (type == snap_type_) { if (snap_sizer_.get()) { @@ -425,9 +430,13 @@ void FrameMaximizeButton::UpdateSnap(const gfx::Point& location, if (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT) { SnapSizer::Edge snap_edge = snap_type_ == SNAP_LEFT ? SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE; + SnapSizer::InputType input_type = + is_touch ? SnapSizer::TOUCH_MAXIMIZE_BUTTON_INPUT : + SnapSizer::OTHER_INPUT; snap_sizer_.reset(new SnapSizer(frame_->GetWidget()->GetNativeWindow(), LocationForSnapSizer(location), - snap_edge)); + snap_edge, + input_type)); if (select_default) snap_sizer_->SelectDefaultSizeAndDisableResize(); } diff --git a/ash/wm/workspace/frame_maximize_button.h b/ash/wm/workspace/frame_maximize_button.h index 45c1b32..6179deb 100644 --- a/ash/wm/workspace/frame_maximize_button.h +++ b/ash/wm/workspace/frame_maximize_button.h @@ -107,7 +107,10 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton, // Updates |snap_type_| based on a mouse drag. If |select_default| is set, // the single button click default setting of the snap sizer should be used. - void UpdateSnap(const gfx::Point& location, bool select_default); + // Set |is_touch| to true to make touch snapping at the corners possible. + void UpdateSnap(const gfx::Point& location, + bool select_default, + bool is_touch); // Returns the type of snap based on the specified location. SnapType SnapTypeForLocation(const gfx::Point& location) const; @@ -145,6 +148,9 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton, // Location of the press. gfx::Point press_location_; + // True if the press was triggered by a gesture/touch. + bool press_is_gesture_; + // Current snap type. SnapType snap_type_; diff --git a/ash/wm/workspace/snap_sizer.cc b/ash/wm/workspace/snap_sizer.cc index f357d23..d7436da 100644 --- a/ash/wm/workspace/snap_sizer.cc +++ b/ash/wm/workspace/snap_sizer.cc @@ -38,7 +38,8 @@ const int kMinimumScreenPercent = 90; SnapSizer::SnapSizer(aura::Window* window, const gfx::Point& start, - Edge edge) + Edge edge, + InputType input_type) : window_(window), edge_(edge), time_last_update_(base::TimeTicks::Now()), @@ -46,7 +47,9 @@ SnapSizer::SnapSizer(aura::Window* window, resize_disabled_(false), num_moves_since_adjust_(0), last_adjust_x_(start.x()), - last_update_x_(start.x()) { + last_update_x_(start.x()), + start_x_(start.x()), + input_type_(input_type) { target_bounds_ = GetTargetBounds(); } @@ -59,7 +62,19 @@ void SnapSizer::Update(const gfx::Point& location) { CalculateIncrement(location.x(), last_update_x_)); } else { bool along_edge = AlongEdge(location.x()); - if (std::abs(location.x() - last_adjust_x_) >= kPixelsBeforeAdjust || + 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 || (along_edge && num_moves_since_adjust_ >= kMovesBeforeAdjust)) { ChangeBounds(location.x(), CalculateIncrement(location.x(), last_adjust_x_)); diff --git a/ash/wm/workspace/snap_sizer.h b/ash/wm/workspace/snap_sizer.h index 9d64a63..8590386 100644 --- a/ash/wm/workspace/snap_sizer.h +++ b/ash/wm/workspace/snap_sizer.h @@ -27,7 +27,18 @@ class ASH_EXPORT SnapSizer { RIGHT_EDGE }; - SnapSizer(aura::Window* window, const gfx::Point& start, Edge edge); + enum InputType { + TOUCH_MAXIMIZE_BUTTON_INPUT, + OTHER_INPUT + }; + + // Set |input_type| to |TOUCH_MAXIMIZE_BUTTON_INPUT| when called by a touch + // operation by the maximize button. This will allow the user to snap resize + // the window beginning close to the border. + SnapSizer(aura::Window* window, + const gfx::Point& start, + Edge edge, + InputType input_type); // Updates the target bounds based on a mouse move. void Update(const gfx::Point& location); @@ -92,6 +103,14 @@ class ASH_EXPORT SnapSizer { // X-coordinate last supplied to Update(). int last_update_x_; + // Initial x-coordinate. + const int start_x_; + + // |TOUCH_MAXIMIZE_BUTTON_INPUT| if the snap sizer was created through a + // touch & drag operation of the maximizer button. It changes the behavior of + // the drag / resize behavior when the dragging starts close to the border. + const InputType input_type_; + DISALLOW_COPY_AND_ASSIGN(SnapSizer); }; diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index f17c3f7..ab5782a 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc @@ -761,7 +761,10 @@ void WorkspaceWindowResizer::UpdateSnapPhantomWindow(const gfx::Point& location, if (!snap_sizer_.get()) { SnapSizer::Edge edge = (snap_type_ == SNAP_LEFT_EDGE) ? SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE; - snap_sizer_.reset(new SnapSizer(window(), location, edge)); + snap_sizer_.reset(new SnapSizer(window(), + location, + edge, + internal::SnapSizer::OTHER_INPUT)); } else { snap_sizer_->Update(location); } diff --git a/ash/wm/workspace/workspace_window_resizer_unittest.cc b/ash/wm/workspace/workspace_window_resizer_unittest.cc index 3419c6c..e31b4f1 100644 --- a/ash/wm/workspace/workspace_window_resizer_unittest.cc +++ b/ash/wm/workspace/workspace_window_resizer_unittest.cc @@ -1119,7 +1119,10 @@ TEST_F(WorkspaceWindowResizerTest, CtrlCompleteDragMoveToExactPosition) { TEST_F(WorkspaceWindowResizerTest, TestProperSizerResolutions) { window_->SetBounds(gfx::Rect(96, 112, 320, 160)); scoped_ptr<SnapSizer> resizer(new SnapSizer( - window_.get(), gfx::Point(), SnapSizer::LEFT_EDGE)); + window_.get(), + gfx::Point(), + SnapSizer::LEFT_EDGE, + SnapSizer::OTHER_INPUT)); ASSERT_TRUE(resizer.get()); shelf_layout_manager()->SetAutoHideBehavior( SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); |