Commit a29f1853 authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Improvements for home to overview gesture

*   Updates the target drag distance at which the home screen stops
    scaling - instead of extending for a fixed point from the threshold
    at which transition is allowed, that target is set to the center of
    the screen
*   Significantly shortens the timeout to trigger transition
*   Allows transition if pointer is moving, provided that the velocity
    is below certain threshold (instead of requiring pointer to stay
    still)

BUG=1005366, 1025283

Change-Id: Ic322932a3ae519a1989ef343f6f2e960dca29709
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1912993
Commit-Queue: Toni Baržić <tbarzic@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#715844}
parent 80a8584a
...@@ -29,16 +29,16 @@ namespace { ...@@ -29,16 +29,16 @@ namespace {
constexpr float kTargetHomeScale = 0.92f; constexpr float kTargetHomeScale = 0.92f;
// The home UI will be scaled down towards center of the screen as drag location // The home UI will be scaled down towards center of the screen as drag location
// approaches the threshold for the transition to overview. The target threshold // moves upwards. The target threshold for scaling is extended above the actual
// for scaling is extended above the actual threshold to make the UI change more // threshold for transition so the UI keeps changing even when the gesture goes
// noticeable to the user as drag approaches the threshold - this is the ratio // over the threshold. This is the target home screen scaling threshold in terms
// by which the projected threshold is extended. // of ratio of the display height.
constexpr float kExtendedVerticalThresholdForOverviewTransitionRatio = 0.5f; constexpr float kHomeScalingThresholdDisplayHeightRatio = 0.5f;
// The amount of time the drag has to remain still before the transition to the // The amount of time the drag has to remain bellow velocity threshold before
// overview starts. // the transition to the overview starts.
constexpr base::TimeDelta kOverviewTransitionDelay = constexpr base::TimeDelta kOverviewTransitionDelay =
base::TimeDelta::FromMilliseconds(350); base::TimeDelta::FromMilliseconds(150);
// The duration of transition from the home screen current scaled state to the // The duration of transition from the home screen current scaled state to the
// initial (unscaled) state when the gesture is canceled. // initial (unscaled) state when the gesture is canceled.
...@@ -90,27 +90,19 @@ void SwipeHomeToOverviewController::Drag(const gfx::PointF& location_in_screen, ...@@ -90,27 +90,19 @@ void SwipeHomeToOverviewController::Drag(const gfx::PointF& location_in_screen,
overview_transition_threshold_y_ = overview_transition_threshold_y_ =
shelf_top - kVerticalThresholdForOverviewTransition; shelf_top - kVerticalThresholdForOverviewTransition;
scaling_threshold_y_ =
display.bounds().y() +
display.bounds().height() * kHomeScalingThresholdDisplayHeightRatio;
state_ = State::kTrackingDrag; state_ = State::kTrackingDrag;
} else { } else {
const bool over_overview_transition_threshold = if (location_in_screen.y() <= overview_transition_threshold_y_ &&
location_in_screen.y() <= overview_transition_threshold_y_; std::abs(scroll_x) + std::abs(scroll_y) <= kMovementVelocityThreshold) {
// Ignore small drag updates, unless they move the drag above the overview
// transition threshold.
if (std::abs(location_in_screen.y() - last_location_in_screen_.y()) <
kMovementThreshold &&
(!over_overview_transition_threshold ||
overview_transition_timer_.IsRunning())) {
return;
}
if (over_overview_transition_threshold)
ScheduleFinalizeDragAndShowOverview(); ScheduleFinalizeDragAndShowOverview();
else } else {
overview_transition_timer_.Stop(); overview_transition_timer_.Stop();
}
} }
last_location_in_screen_ = location_in_screen;
// Update the home screen scale to match progress during the drag. // Update the home screen scale to match progress during the drag.
// Use extended threshold as the projected final transition position - UI // Use extended threshold as the projected final transition position - UI
...@@ -118,15 +110,10 @@ void SwipeHomeToOverviewController::Drag(const gfx::PointF& location_in_screen, ...@@ -118,15 +110,10 @@ void SwipeHomeToOverviewController::Drag(const gfx::PointF& location_in_screen,
// more likely to keep dragging up when they get really close to the threshold // more likely to keep dragging up when they get really close to the threshold
// for transition to overview (and reduce false negatives for detecting // for transition to overview (and reduce false negatives for detecting
// transition to overview). // transition to overview).
const float extended_threshold = const float distance = location_in_screen.y() - scaling_threshold_y_;
overview_transition_threshold_y_ - const float target_distance = overview_transition_threshold_y_ -
kVerticalThresholdForOverviewTransition * scaling_threshold_y_ +
kExtendedVerticalThresholdForOverviewTransitionRatio; kVerticalThresholdForOverviewTransition;
const float distance = location_in_screen.y() - extended_threshold;
const float target_distance =
kVerticalThresholdForOverviewTransition *
(1.f + kExtendedVerticalThresholdForOverviewTransitionRatio);
const float progress = gfx::Tween::CalculateValue( const float progress = gfx::Tween::CalculateValue(
gfx::Tween::FAST_OUT_SLOW_IN, gfx::Tween::FAST_OUT_SLOW_IN,
...@@ -156,7 +143,6 @@ void SwipeHomeToOverviewController::CancelDrag() { ...@@ -156,7 +143,6 @@ void SwipeHomeToOverviewController::CancelDrag() {
} }
overview_transition_timer_.Stop(); overview_transition_timer_.Stop();
last_location_in_screen_ = gfx::PointF();
overview_transition_threshold_y_ = 0; overview_transition_threshold_y_ = 0;
state_ = State::kFinished; state_ = State::kFinished;
...@@ -171,6 +157,9 @@ void SwipeHomeToOverviewController::CancelDrag() { ...@@ -171,6 +157,9 @@ void SwipeHomeToOverviewController::CancelDrag() {
} }
void SwipeHomeToOverviewController::ScheduleFinalizeDragAndShowOverview() { void SwipeHomeToOverviewController::ScheduleFinalizeDragAndShowOverview() {
if (overview_transition_timer_.IsRunning())
return;
overview_transition_timer_.Start( overview_transition_timer_.Start(
FROM_HERE, kOverviewTransitionDelay, FROM_HERE, kOverviewTransitionDelay,
base::BindOnce( base::BindOnce(
...@@ -179,7 +168,6 @@ void SwipeHomeToOverviewController::ScheduleFinalizeDragAndShowOverview() { ...@@ -179,7 +168,6 @@ void SwipeHomeToOverviewController::ScheduleFinalizeDragAndShowOverview() {
} }
void SwipeHomeToOverviewController::FinalizeDragAndShowOverview() { void SwipeHomeToOverviewController::FinalizeDragAndShowOverview() {
last_location_in_screen_ = gfx::PointF();
state_ = State::kFinished; state_ = State::kFinished;
overview_transition_threshold_y_ = 0; overview_transition_threshold_y_ = 0;
......
...@@ -25,9 +25,8 @@ class ASH_EXPORT SwipeHomeToOverviewController { ...@@ -25,9 +25,8 @@ class ASH_EXPORT SwipeHomeToOverviewController {
// work area for the gesture to trigger transition to overview. // work area for the gesture to trigger transition to overview.
static constexpr int kVerticalThresholdForOverviewTransition = 56; static constexpr int kVerticalThresholdForOverviewTransition = 56;
// The min location change distance required for a drag update to be // The max pointer velocity at which home transitions to overview.
// registered. static constexpr int kMovementVelocityThreshold = 10;
static constexpr int kMovementThreshold = 3;
// The constructor that uses default tick clock for // The constructor that uses default tick clock for
// |overview_transition_timer_|. Should be preferred outside of test // |overview_transition_timer_|. Should be preferred outside of test
...@@ -56,7 +55,7 @@ class ASH_EXPORT SwipeHomeToOverviewController { ...@@ -56,7 +55,7 @@ class ASH_EXPORT SwipeHomeToOverviewController {
private: private:
enum class State { kInitial, kTrackingDrag, kFinished }; enum class State { kInitial, kTrackingDrag, kFinished };
// (Re)starts |overview_transition_timer_|. // Starts |overview_transition_timer_|. No-op if the timer is already running.
void ScheduleFinalizeDragAndShowOverview(); void ScheduleFinalizeDragAndShowOverview();
// Finalizes the drag sequence, and starts overview session. // Finalizes the drag sequence, and starts overview session.
...@@ -68,15 +67,17 @@ class ASH_EXPORT SwipeHomeToOverviewController { ...@@ -68,15 +67,17 @@ class ASH_EXPORT SwipeHomeToOverviewController {
State state_ = State::kInitial; State state_ = State::kInitial;
// The last detected drag location.
gfx::PointF last_location_in_screen_;
// The y in-screen coordinate at which drag, when stopped, will cause // The y in-screen coordinate at which drag, when stopped, will cause
// transition to overview. Overview session will be started iff the drag stops // transition to overview. Overview session will be started iff the drag stops
// above this line. // above this line.
// The value is set when the controller transitions to kStarted state. // The value is set when the controller transitions to kStarted state.
int overview_transition_threshold_y_ = 0; int overview_transition_threshold_y_ = 0;
// Home screen is scaled down depending on gesture vertical distance from the
// shelf - this is the target gesture vertical location at which home screen
// should be scaled by the target scale factor.
int scaling_threshold_y_ = 0;
// The timer to run FinalizeDragAndShowOverview(). // The timer to run FinalizeDragAndShowOverview().
base::OneShotTimer overview_transition_timer_; base::OneShotTimer overview_transition_timer_;
......
...@@ -296,12 +296,24 @@ TEST_F(SwipeHomeToOverviewControllerTest, DragMovementRestartsTimeout) { ...@@ -296,12 +296,24 @@ TEST_F(SwipeHomeToOverviewControllerTest, DragMovementRestartsTimeout) {
GetTimerDesiredRunTime() - tick_clock_.NowTicks(); GetTimerDesiredRunTime() - tick_clock_.NowTicks();
EXPECT_GT(delay, base::TimeDelta()); EXPECT_GT(delay, base::TimeDelta());
// Advance clock, and simulate another drag. const float max_allowed_velocity =
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); SwipeHomeToOverviewController::kMovementVelocityThreshold;
// Advance clock, and simulate another drag whose speed is above the max
// allowed.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1));
Drag(shelf_bounds.top_center() - gfx::Vector2d(0, 2 * transition_threshold), Drag(shelf_bounds.top_center() - gfx::Vector2d(0, 2 * transition_threshold),
0.f, 1.f); 0.f, max_allowed_velocity + 10);
// Verify the timer was stopped.
EXPECT_FALSE(OverviewTransitionTimerRunning());
EXPECT_FALSE(OverviewStarted());
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1));
// Another slow drag should restart the timer.
Drag(shelf_bounds.top_center() - gfx::Vector2d(0, 2 * transition_threshold),
0.f, max_allowed_velocity / 2);
// Verify the expected timer run time was updated.
EXPECT_TRUE(OverviewTransitionTimerRunning()); EXPECT_TRUE(OverviewTransitionTimerRunning());
EXPECT_FALSE(OverviewStarted()); EXPECT_FALSE(OverviewStarted());
...@@ -337,33 +349,30 @@ TEST_F(SwipeHomeToOverviewControllerTest, ...@@ -337,33 +349,30 @@ TEST_F(SwipeHomeToOverviewControllerTest,
GetTimerDesiredRunTime() - tick_clock_.NowTicks(); GetTimerDesiredRunTime() - tick_clock_.NowTicks();
EXPECT_GT(delay, base::TimeDelta()); EXPECT_GT(delay, base::TimeDelta());
const int movement_threshold = const float movement_threshold =
SwipeHomeToOverviewController::kMovementThreshold; SwipeHomeToOverviewController::kMovementVelocityThreshold;
// Advance clock, and simulate another drag, but for small amount.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); // Advance clock, and simulate another drag, for an amount below the movement
// threshold.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1));
Drag(shelf_bounds.top_center() - Drag(shelf_bounds.top_center() -
gfx::Vector2d(0, transition_threshold + movement_threshold - 1), gfx::Vector2d(0, transition_threshold + movement_threshold - 1),
0.f, 1.f); 0.f, movement_threshold / 2);
// Verify the expected timer run time was not updated. // Verify the expected timer run time was not updated.
EXPECT_TRUE(OverviewTransitionTimerRunning()); EXPECT_TRUE(OverviewTransitionTimerRunning());
EXPECT_FALSE(OverviewStarted()); EXPECT_FALSE(OverviewStarted());
EXPECT_EQ(delay - base::TimeDelta::FromMilliseconds(10), EXPECT_EQ(delay - base::TimeDelta::FromMilliseconds(1),
GetTimerDesiredRunTime() - tick_clock_.NowTicks()); GetTimerDesiredRunTime() - tick_clock_.NowTicks());
// Advance clock, and simulate another small drag (the total distance from the // Movement with velocity above the allowed threshold restarts the timer.
// last position being over the movement detection threshold) - verify the
// timer is updated.
tick_clock_.Advance(base::TimeDelta::FromMilliseconds(10));
Drag(shelf_bounds.top_center() - Drag(shelf_bounds.top_center() -
gfx::Vector2d(0, transition_threshold + movement_threshold), gfx::Vector2d(0, transition_threshold + movement_threshold - 1),
0.f, 1.f); 0.f, movement_threshold + 1);
EXPECT_TRUE(OverviewTransitionTimerRunning()); EXPECT_FALSE(OverviewTransitionTimerRunning());
EXPECT_FALSE(OverviewStarted()); EXPECT_FALSE(OverviewStarted());
EXPECT_EQ(delay, GetTimerDesiredRunTime() - tick_clock_.NowTicks());
} }
TEST_F(SwipeHomeToOverviewControllerTest, DragBellowThresholdStopsTimer) { TEST_F(SwipeHomeToOverviewControllerTest, DragBellowThresholdStopsTimer) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment