Commit f3dc80ce authored by sadrul@chromium.org's avatar sadrul@chromium.org

gestures: Generate only either scroll-end or fling-start events at the end of a scroll gesture.

When a fling happens at the end of a scroll, instead of generating both a scroll-end
and a fling-start event, generate only fling-start event. Unfortunately, WebKit still
requires an explicit scroll-end gesture before a fling, so continue to do that as a
special case.

BUG=141460,141309

Review URL: https://chromiumcodereview.appspot.com/10826209

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150852 0039d316-1c4b-4281-b951-d872f2087c98
parent efdbdb05
...@@ -149,17 +149,22 @@ ui::GestureStatus ToplevelWindowEventFilter::PreHandleGestureEvent( ...@@ -149,17 +149,22 @@ ui::GestureStatus ToplevelWindowEventFilter::PreHandleGestureEvent(
break; break;
} }
case ui::ET_GESTURE_SCROLL_END: case ui::ET_GESTURE_SCROLL_END:
if (!in_gesture_resize_) case ui::ET_SCROLL_FLING_START: {
return ui::GESTURE_STATUS_UNKNOWN; ui::GestureStatus status = ui::GESTURE_STATUS_UNKNOWN;
CompleteDrag(DRAG_COMPLETE, event->flags()); if (in_gesture_resize_) {
if (in_move_loop_) { // If the window was being resized, then just complete the resize.
quit_closure_.Run(); CompleteDrag(DRAG_COMPLETE, event->flags());
in_move_loop_ = false; if (in_move_loop_) {
quit_closure_.Run();
in_move_loop_ = false;
}
in_gesture_resize_ = false;
status = ui::GESTURE_STATUS_CONSUMED;
} }
in_gesture_resize_ = false;
break;
case ui::ET_SCROLL_FLING_START: { if (event->type() == ui::ET_GESTURE_SCROLL_END)
return status;
int component = int component =
target->delegate()->GetNonClientComponent(event->location()); target->delegate()->GetNonClientComponent(event->location());
if (WindowResizer::GetBoundsChangeForWindowComponent(component) == 0) if (WindowResizer::GetBoundsChangeForWindowComponent(component) == 0)
......
...@@ -204,13 +204,14 @@ ui::GestureStatus ContentsView::OnGestureEvent( ...@@ -204,13 +204,14 @@ ui::GestureStatus ContentsView::OnGestureEvent(
pagination_model_->EndScroll(); pagination_model_->EndScroll();
return ui::GESTURE_STATUS_CONSUMED; return ui::GESTURE_STATUS_CONSUMED;
case ui::ET_SCROLL_FLING_START: { case ui::ET_SCROLL_FLING_START: {
pagination_model_->EndScroll();
if (fabs(event.details().velocity_x()) > kMinHorizVelocityToSwitchPage) { if (fabs(event.details().velocity_x()) > kMinHorizVelocityToSwitchPage) {
pagination_model_->ResetTransitionAnimation();
pagination_model_->SelectPageRelative( pagination_model_->SelectPageRelative(
event.details().velocity_x() < 0 ? 1 : -1, event.details().velocity_x() < 0 ? 1 : -1,
true); true);
return ui::GESTURE_STATUS_CONSUMED;
} }
break; return ui::GESTURE_STATUS_CONSUMED;
} }
default: default:
break; break;
......
...@@ -56,7 +56,7 @@ void PaginationModel::SelectPage(int page, bool animate) { ...@@ -56,7 +56,7 @@ void PaginationModel::SelectPage(int page, bool animate) {
if (page == selected_page_) if (page == selected_page_)
return; return;
ResetTranstionAnimation(); ResetTransitionAnimation();
int old_selected = selected_page_; int old_selected = selected_page_;
selected_page_ = page; selected_page_ = page;
...@@ -86,6 +86,13 @@ void PaginationModel::SetTransitionDuration(int duration_ms) { ...@@ -86,6 +86,13 @@ void PaginationModel::SetTransitionDuration(int duration_ms) {
transition_duration_ms_ = duration_ms; transition_duration_ms_ = duration_ms;
} }
void PaginationModel::ResetTransitionAnimation() {
transition_animation_.reset();
transition_.target_page = -1;
transition_.progress = 0;
pending_selected_page_ = -1;
}
void PaginationModel::StartScroll() { void PaginationModel::StartScroll() {
// Cancels current transition animation (if any). // Cancels current transition animation (if any).
transition_animation_.reset(); transition_animation_.reset();
...@@ -185,13 +192,6 @@ void PaginationModel::CreateTransitionAnimation() { ...@@ -185,13 +192,6 @@ void PaginationModel::CreateTransitionAnimation() {
transition_animation_->SetSlideDuration(transition_duration_ms_); transition_animation_->SetSlideDuration(transition_duration_ms_);
} }
void PaginationModel::ResetTranstionAnimation() {
transition_animation_.reset();
transition_.target_page = -1;
transition_.progress = 0;
pending_selected_page_ = -1;
}
void PaginationModel::AnimationProgressed(const ui::Animation* animation) { void PaginationModel::AnimationProgressed(const ui::Animation* animation) {
transition_.progress = transition_animation_->GetCurrentValue(); transition_.progress = transition_animation_->GetCurrentValue();
NotifyTransitionChanged(); NotifyTransitionChanged();
...@@ -216,7 +216,7 @@ void PaginationModel::AnimationEnded(const ui::Animation* animation) { ...@@ -216,7 +216,7 @@ void PaginationModel::AnimationEnded(const ui::Animation* animation) {
SelectPage(transition_.target_page, false /* animate */); SelectPage(transition_.target_page, false /* animate */);
} else if (transition_animation_->GetCurrentValue() == 0) { } else if (transition_animation_->GetCurrentValue() == 0) {
// Hiding animation ends. No page change should happen. // Hiding animation ends. No page change should happen.
ResetTranstionAnimation(); ResetTransitionAnimation();
} }
if (next_target >= 0) if (next_target >= 0)
......
...@@ -60,6 +60,7 @@ class APP_LIST_EXPORT PaginationModel : public ui::AnimationDelegate { ...@@ -60,6 +60,7 @@ class APP_LIST_EXPORT PaginationModel : public ui::AnimationDelegate {
void SetTransition(const Transition& transition); void SetTransition(const Transition& transition);
void SetTransitionDuration(int duration_ms); void SetTransitionDuration(int duration_ms);
void ResetTransitionAnimation();
// Starts a scroll transition. If there is a running transition animation, // Starts a scroll transition. If there is a running transition animation,
// cancels it but keeps the transition info. // cancels it but keeps the transition info.
...@@ -107,7 +108,6 @@ class APP_LIST_EXPORT PaginationModel : public ui::AnimationDelegate { ...@@ -107,7 +108,6 @@ class APP_LIST_EXPORT PaginationModel : public ui::AnimationDelegate {
void StartTranstionAnimation(int target_page); void StartTranstionAnimation(int target_page);
void CreateTransitionAnimation(); void CreateTransitionAnimation();
void ResetTranstionAnimation();
// ui::AnimationDelegate overrides: // ui::AnimationDelegate overrides:
virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
......
...@@ -164,8 +164,10 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { ...@@ -164,8 +164,10 @@ class GestureEventConsumeDelegate : public TestWindowDelegate {
case ui::ET_SCROLL_FLING_START: case ui::ET_SCROLL_FLING_START:
EXPECT_TRUE(gesture->details().velocity_x() != 0 || EXPECT_TRUE(gesture->details().velocity_x() != 0 ||
gesture->details().velocity_y() != 0); gesture->details().velocity_y() != 0);
EXPECT_TRUE(scroll_end_); EXPECT_FALSE(scroll_end_);
fling_ = true; fling_ = true;
velocity_x_ = gesture->details().velocity_x();
velocity_y_ = gesture->details().velocity_y();
break; break;
case ui::ET_GESTURE_TWO_FINGER_TAP: case ui::ET_GESTURE_TWO_FINGER_TAP:
two_finger_tap_ = true; two_finger_tap_ = true;
...@@ -859,8 +861,9 @@ TEST_F(GestureRecognizerTest, GestureEventHorizontalRailFling) { ...@@ -859,8 +861,9 @@ TEST_F(GestureRecognizerTest, GestureEventHorizontalRailFling) {
kTouchId, GetTime()); kTouchId, GetTime());
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);
EXPECT_TRUE(delegate->scroll_end()); EXPECT_TRUE(delegate->fling());
EXPECT_EQ(0, delegate->velocity_x()); EXPECT_FALSE(delegate->scroll_end());
EXPECT_GT(delegate->velocity_x(), 0);
EXPECT_EQ(0, delegate->velocity_y()); EXPECT_EQ(0, delegate->velocity_y());
} }
...@@ -895,9 +898,10 @@ TEST_F(GestureRecognizerTest, GestureEventVerticalRailFling) { ...@@ -895,9 +898,10 @@ TEST_F(GestureRecognizerTest, GestureEventVerticalRailFling) {
kTouchId, GetTime()); kTouchId, GetTime());
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);
EXPECT_TRUE(delegate->scroll_end()); EXPECT_TRUE(delegate->fling());
EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(0, delegate->velocity_x()); EXPECT_EQ(0, delegate->velocity_x());
EXPECT_EQ(0, delegate->velocity_y()); EXPECT_GT(delegate->velocity_y(), 0);
} }
// Check Scroll End Events reports zero velocities // Check Scroll End Events reports zero velocities
...@@ -929,9 +933,10 @@ TEST_F(GestureRecognizerTest, GestureEventNonRailFling) { ...@@ -929,9 +933,10 @@ TEST_F(GestureRecognizerTest, GestureEventNonRailFling) {
kTouchId, GetTime()); kTouchId, GetTime());
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);
EXPECT_TRUE(delegate->scroll_end()); EXPECT_TRUE(delegate->fling());
EXPECT_EQ(0, delegate->velocity_x()); EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(0, delegate->velocity_y()); EXPECT_GT(delegate->velocity_x(), 0);
EXPECT_GT(delegate->velocity_y(), 0);
} }
// Check that appropriate touch events generate long press events // Check that appropriate touch events generate long press events
......
...@@ -642,15 +642,6 @@ void GestureSequence::AppendScrollGestureEnd(const GesturePoint& point, ...@@ -642,15 +642,6 @@ void GestureSequence::AppendScrollGestureEnd(const GesturePoint& point,
else if (scroll_type_ == ST_VERTICAL) else if (scroll_type_ == ST_VERTICAL)
railed_x_velocity = 0; railed_x_velocity = 0;
// TODO(rjkroege): It is conceivable that we could suppress sending the
// GestureScrollEnd if it is immediately followed by a GestureFlingStart.
gestures->push_back(CreateGestureEvent(
GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0),
location,
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
1 << point.touch_id()));
if (railed_x_velocity != 0 || railed_y_velocity != 0) { if (railed_x_velocity != 0 || railed_y_velocity != 0) {
// TODO(sad|rjkroege): fling-curve is currently configured to work well with // TODO(sad|rjkroege): fling-curve is currently configured to work well with
// touchpad scroll-events. This curve needs to be adjusted to work correctly // touchpad scroll-events. This curve needs to be adjusted to work correctly
...@@ -666,6 +657,13 @@ void GestureSequence::AppendScrollGestureEnd(const GesturePoint& point, ...@@ -666,6 +657,13 @@ void GestureSequence::AppendScrollGestureEnd(const GesturePoint& point,
flags_, flags_,
base::Time::FromDoubleT(point.last_touch_time()), base::Time::FromDoubleT(point.last_touch_time()),
1 << point.touch_id())); 1 << point.touch_id()));
} else {
gestures->push_back(CreateGestureEvent(
GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0),
location,
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
1 << point.touch_id()));
} }
} }
......
...@@ -91,6 +91,11 @@ class VIEWS_EXPORT Event { ...@@ -91,6 +91,11 @@ class VIEWS_EXPORT Event {
type_ == ui::ET_GESTURE_SCROLL_END; type_ == ui::ET_GESTURE_SCROLL_END;
} }
bool IsFlingScrollEvent() const {
return type_ == ui::ET_SCROLL_FLING_CANCEL ||
type_ == ui::ET_SCROLL_FLING_START;
}
protected: protected:
Event(ui::EventType type, int flags); Event(ui::EventType type, int flags);
Event(const NativeEvent& native_event, ui::EventType type, int flags); Event(const NativeEvent& native_event, ui::EventType type, int flags);
......
...@@ -458,8 +458,9 @@ ui::GestureStatus RootView::OnGestureEvent(const GestureEvent& event) { ...@@ -458,8 +458,9 @@ ui::GestureStatus RootView::OnGestureEvent(const GestureEvent& event) {
if (gesture_handler_) { if (gesture_handler_) {
// |gesture_handler_| (or |scroll_gesture_handler_|) can be deleted during // |gesture_handler_| (or |scroll_gesture_handler_|) can be deleted during
// processing. // processing.
View* handler = event.IsScrollGestureEvent() && scroll_gesture_handler_ ? View* handler = scroll_gesture_handler_ &&
scroll_gesture_handler_ : gesture_handler_; (event.IsScrollGestureEvent() || event.IsFlingScrollEvent()) ?
scroll_gesture_handler_ : gesture_handler_;
GestureEvent handler_event(event, this, handler); GestureEvent handler_event(event, this, handler);
ui::GestureStatus status = handler->ProcessGestureEvent(handler_event); ui::GestureStatus status = handler->ProcessGestureEvent(handler_event);
...@@ -468,7 +469,8 @@ ui::GestureStatus RootView::OnGestureEvent(const GestureEvent& event) { ...@@ -468,7 +469,8 @@ ui::GestureStatus RootView::OnGestureEvent(const GestureEvent& event) {
event.details().touch_points() <= 1) event.details().touch_points() <= 1)
gesture_handler_ = NULL; gesture_handler_ = NULL;
if (event.type() == ui::ET_GESTURE_SCROLL_END && scroll_gesture_handler_) if (scroll_gesture_handler_ && (event.type() == ui::ET_GESTURE_SCROLL_END ||
event.type() == ui::ET_SCROLL_FLING_START))
scroll_gesture_handler_ = NULL; scroll_gesture_handler_ = NULL;
if (status == ui::GESTURE_STATUS_CONSUMED) if (status == ui::GESTURE_STATUS_CONSUMED)
......
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