summaryrefslogtreecommitdiffstats
path: root/content/browser
diff options
context:
space:
mode:
authordominikg@chromium.org <dominikg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-03 00:42:08 +0000
committerdominikg@chromium.org <dominikg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-03 00:42:08 +0000
commitbb281f85ccce66e277ff70b1dd82e6419a95ccb3 (patch)
tree0b9524656b706f97f88f4be7daae52034ef1a893 /content/browser
parent36d836a9c44a366d637c9ee9ea2a22282e3dcf68 (diff)
downloadchromium_src-bb281f85ccce66e277ff70b1dd82e6419a95ccb3.zip
chromium_src-bb281f85ccce66e277ff70b1dd82e6419a95ccb3.tar.gz
chromium_src-bb281f85ccce66e277ff70b1dd82e6419a95ccb3.tar.bz2
Make touch-based synthetic gesture take touch slop into account.
Touchscreen devices typically have a 'touch slop', i.e. a certain distance a pointer has to move before it is considered moving. The touch slop is subtracted from the distance a pointer moves. So if the touch slop is 10 pixels and a pointer moves by 100 pixels on the screen, the resulting move is registered as having covered only 90 pixels. This patch adds the 'GetTouchSlopInDips' to SyntheticGestureTargets. This value is used by the gestures to increase the distances covered by touch pointers. For example, to scroll 100 pixels with a touch slop of 10 pixels, the pointer will cover 110 pixels. Touch-based synthetic gestures are updated to take the touch slop into account. BUG=321114 Review URL: https://codereview.chromium.org/95153002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238248 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser')
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc62
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target.h4
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_android.cc9
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_android.h2
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_aura.cc7
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_aura.h2
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_base.cc9
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_base.h4
-rw-r--r--content/browser/renderer_host/input/synthetic_pinch_gesture.cc61
-rw-r--r--content/browser/renderer_host/input/synthetic_pinch_gesture.h1
-rw-r--r--content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc6
-rw-r--r--content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h13
12 files changed, 136 insertions, 44 deletions
diff --git a/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc b/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
index baefa69..8bf1450 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
@@ -25,6 +25,7 @@ namespace {
const int kFlushInputRateInMs = 16;
const int kPointerAssumedStoppedTimeMs = 43;
+const int kTouchSlopInDips = 7;
class MockSyntheticGesture : public SyntheticGesture {
public:
@@ -100,6 +101,10 @@ class MockSyntheticGestureTarget : public SyntheticGestureTarget {
pointer_assumed_stopped_time_ms_ = time_ms;
}
+ virtual int GetTouchSlopInDips() const OVERRIDE {
+ return kTouchSlopInDips;
+ }
+
int num_success() const { return num_success_; }
int num_failure() const { return num_failure_; }
@@ -373,7 +378,7 @@ TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouch) {
EXPECT_EQ(1, target_->num_success());
EXPECT_EQ(0, target_->num_failure());
- EXPECT_FLOAT_EQ(params.distance,
+ EXPECT_FLOAT_EQ(params.distance + target_->GetTouchSlopInDips(),
static_cast<MockSyntheticSmoothScrollTouchTarget*>(target_)
->scroll_distance());
}
@@ -397,12 +402,30 @@ TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchLongStop) {
EXPECT_EQ(1, target_->num_success());
EXPECT_EQ(0, target_->num_failure());
- EXPECT_FLOAT_EQ(params.distance,
+ EXPECT_FLOAT_EQ(params.distance + target_->GetTouchSlopInDips(),
static_cast<MockSyntheticSmoothScrollTouchTarget*>(target_)
->scroll_distance());
EXPECT_GE(GetTotalTime(), target_->PointerAssumedStoppedTime());
}
+TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchZeroDistance) {
+ CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
+
+ SyntheticSmoothScrollGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params.distance = 0;
+
+ scoped_ptr<SyntheticSmoothScrollGesture> gesture(
+ new SyntheticSmoothScrollGesture(params));
+ controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
+ FlushInputUntilComplete();
+
+ EXPECT_EQ(1, target_->num_success());
+ EXPECT_EQ(0, target_->num_failure());
+ EXPECT_FLOAT_EQ(0, static_cast<MockSyntheticSmoothScrollTouchTarget*>(target_)
+ ->scroll_distance());
+}
+
TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureMouse) {
CreateControllerAndTarget<MockSyntheticSmoothScrollMouseTarget>();
@@ -439,9 +462,10 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomIn) {
EXPECT_EQ(
static_cast<MockSyntheticPinchTouchTarget*>(target_)->zoom_direction(),
MockSyntheticPinchTouchTarget::ZOOM_IN);
- EXPECT_FLOAT_EQ(params.total_num_pixels_covered,
- static_cast<MockSyntheticPinchTouchTarget*>(target_)
- ->total_num_pixels_covered());
+ EXPECT_FLOAT_EQ(
+ params.total_num_pixels_covered + 2 * target_->GetTouchSlopInDips(),
+ static_cast<MockSyntheticPinchTouchTarget*>(target_)
+ ->total_num_pixels_covered());
}
TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) {
@@ -461,9 +485,31 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) {
EXPECT_EQ(
static_cast<MockSyntheticPinchTouchTarget*>(target_)->zoom_direction(),
MockSyntheticPinchTouchTarget::ZOOM_OUT);
- EXPECT_FLOAT_EQ(params.total_num_pixels_covered,
- static_cast<MockSyntheticPinchTouchTarget*>(target_)
- ->total_num_pixels_covered());
+ EXPECT_FLOAT_EQ(
+ params.total_num_pixels_covered + 2 * target_->GetTouchSlopInDips(),
+ static_cast<MockSyntheticPinchTouchTarget*>(target_)
+ ->total_num_pixels_covered());
+}
+
+TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZeroPixelsCovered) {
+ CreateControllerAndTarget<MockSyntheticPinchTouchTarget>();
+
+ SyntheticPinchGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params.zoom_in = true;
+ params.total_num_pixels_covered = 0;
+
+ scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
+ controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
+ FlushInputUntilComplete();
+
+ EXPECT_EQ(1, target_->num_success());
+ EXPECT_EQ(0, target_->num_failure());
+ EXPECT_EQ(
+ static_cast<MockSyntheticPinchTouchTarget*>(target_)->zoom_direction(),
+ MockSyntheticPinchTouchTarget::ZOOM_DIRECTION_UNKNOWN);
+ EXPECT_FLOAT_EQ(0, static_cast<MockSyntheticPinchTouchTarget*>(target_)
+ ->total_num_pixels_covered());
}
} // namespace
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target.h b/content/browser/renderer_host/input/synthetic_gesture_target.h
index 5b31b02..01487fc 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target.h
+++ b/content/browser/renderer_host/input/synthetic_gesture_target.h
@@ -44,6 +44,10 @@ class CONTENT_EXPORT SyntheticGestureTarget {
// After how much time of inaction does the target assume that a pointer has
// stopped moving.
virtual base::TimeDelta PointerAssumedStoppedTime() const = 0;
+
+ // Returns the maximum number of DIPs a touch pointer can move without being
+ // considered moving by the platform.
+ virtual int GetTouchSlopInDips() const = 0;
};
} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_android.cc b/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
index acaee85..6590f00 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
@@ -5,8 +5,11 @@
#include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
#include "content/browser/android/content_view_core_impl.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/common/android/view_configuration.h"
#include "jni/TouchEventSynthesizer_jni.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/gfx/screen.h"
using blink::WebTouchEvent;
@@ -80,4 +83,10 @@ bool SyntheticGestureTargetAndroid::SupportsSyntheticGestureSourceType(
return gesture_source_type == SyntheticGestureParams::TOUCH_INPUT;
}
+int SyntheticGestureTargetAndroid::GetTouchSlopInDips() const {
+ float device_scale_factor =
+ gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor();
+ return ViewConfiguration::GetTouchSlopInPixels() / device_scale_factor;
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_android.h b/content/browser/renderer_host/input/synthetic_gesture_target_android.h
index d31516e..b8c5a5d 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_android.h
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_android.h
@@ -33,6 +33,8 @@ class SyntheticGestureTargetAndroid : public SyntheticGestureTargetBase {
SyntheticGestureParams::GestureSourceType gesture_source_type) const
OVERRIDE;
+ virtual int GetTouchSlopInDips() const OVERRIDE;
+
private:
// Enum values below need to be kept in sync with TouchEventSynthesizer.java
enum Action {
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
index 1d5c6a8..9e10313 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
@@ -11,6 +11,7 @@
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
+#include "ui/events/gestures/gesture_configuration.h"
using blink::WebTouchEvent;
using blink::WebMouseWheelEvent;
@@ -70,4 +71,10 @@ bool SyntheticGestureTargetAura::SupportsSyntheticGestureSourceType(
gesture_source_type == SyntheticGestureParams::MOUSE_INPUT;
}
+int SyntheticGestureTargetAura::GetTouchSlopInDips() const {
+ // - 1 because Aura considers a pointer to be moving if it has moved at least
+ // 'max_touch_move_in_pixels_for_click' pixels.
+ return ui::GestureConfiguration::max_touch_move_in_pixels_for_click() - 1;
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_aura.h b/content/browser/renderer_host/input/synthetic_gesture_target_aura.h
index 69837de..5a4ab9c 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_aura.h
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_aura.h
@@ -30,6 +30,8 @@ class SyntheticGestureTargetAura : public SyntheticGestureTargetBase {
SyntheticGestureParams::GestureSourceType gesture_source_type) const
OVERRIDE;
+ virtual int GetTouchSlopInDips() const OVERRIDE;
+
private:
DISALLOW_COPY_AND_ASSIGN(SyntheticGestureTargetAura);
};
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_base.cc b/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
index bc6dc8f..0938eeb 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
@@ -25,6 +25,11 @@ namespace {
// fling on Android.
const int kPointerAssumedStoppedTimeMs = 50;
+// SyntheticGestureTargetBase passes input events straight on to the renderer
+// without going through a gesture recognition framework. There is thus no touch
+// slop.
+const int kTouchSlopInDips = 0;
+
} // namespace
SyntheticGestureTargetBase::SyntheticGestureTargetBase(
@@ -110,4 +115,8 @@ base::TimeDelta SyntheticGestureTargetBase::PointerAssumedStoppedTime()
return base::TimeDelta::FromMilliseconds(kPointerAssumedStoppedTimeMs);
}
+int SyntheticGestureTargetBase::GetTouchSlopInDips() const {
+ return kTouchSlopInDips;
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_base.h b/content/browser/renderer_host/input/synthetic_gesture_target_base.h
index 711c0c3..efb8d76 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_base.h
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_base.h
@@ -55,8 +55,10 @@ class SyntheticGestureTargetBase : public SyntheticGestureTarget {
virtual base::TimeDelta PointerAssumedStoppedTime() const OVERRIDE;
+ virtual int GetTouchSlopInDips() const OVERRIDE;
+
protected:
- RenderWidgetHostImpl* render_widget_host() { return host_; }
+ RenderWidgetHostImpl* render_widget_host() const { return host_; }
private:
RenderWidgetHostImpl* host_;
diff --git a/content/browser/renderer_host/input/synthetic_pinch_gesture.cc b/content/browser/renderer_host/input/synthetic_pinch_gesture.cc
index d7c02a6..b8f9ea8 100644
--- a/content/browser/renderer_host/input/synthetic_pinch_gesture.cc
+++ b/content/browser/renderer_host/input/synthetic_pinch_gesture.cc
@@ -11,35 +11,16 @@
#include "ui/events/latency_info.h"
namespace content {
-namespace {
-
-// TODO(dominikg): Use touch slop to compute this value.
-const float kMinPointerDistance = 40.0f;
-
-}
SyntheticPinchGesture::SyntheticPinchGesture(
const SyntheticPinchGestureParams& params)
- : params_(params), started_(false) {
+ : params_(params),
+ current_y_0_(0.0f),
+ current_y_1_(0.0f),
+ target_y_0_(0.0f),
+ target_y_1_(0.0f),
+ started_(false) {
DCHECK_GE(params_.total_num_pixels_covered, 0);
-
- float inner_distance_to_anchor = kMinPointerDistance / 2.0f;
- float outer_distance_to_anchor =
- inner_distance_to_anchor + params_.total_num_pixels_covered / 2.0f;
-
- // Move pointers away from each other to zoom in
- // or towards each other to zoom out.
- if (params_.zoom_in) {
- current_y_0_ = params_.anchor.y() - inner_distance_to_anchor;
- current_y_1_ = params_.anchor.y() + inner_distance_to_anchor;
- target_y_0_ = params_.anchor.y() - outer_distance_to_anchor;
- target_y_1_ = params_.anchor.y() + outer_distance_to_anchor;
- } else {
- current_y_0_ = params_.anchor.y() - outer_distance_to_anchor;
- current_y_1_ = params_.anchor.y() + outer_distance_to_anchor;
- target_y_0_ = params_.anchor.y() - inner_distance_to_anchor;
- target_y_1_ = params_.anchor.y() + inner_distance_to_anchor;
- }
}
SyntheticPinchGesture::~SyntheticPinchGesture() {}
@@ -63,10 +44,12 @@ SyntheticGesture::Result SyntheticPinchGesture::ForwardInputEvents(
SyntheticGesture::Result SyntheticPinchGesture::ForwardTouchInputEvents(
const base::TimeDelta& interval, SyntheticGestureTarget* target) {
- if (HasFinished())
- return SyntheticGesture::GESTURE_FINISHED;
-
if (!started_) {
+ if (params_.total_num_pixels_covered == 0)
+ return SyntheticGesture::GESTURE_FINISHED;
+
+ SetupCoordinates(target);
+
touch_event_.PressPoint(params_.anchor.x(), current_y_0_);
touch_event_.PressPoint(params_.anchor.x(), current_y_1_);
ForwardTouchEvent(target);
@@ -102,6 +85,28 @@ void SyntheticPinchGesture::ForwardTouchEvent(SyntheticGestureTarget* target) {
InputEvent(touch_event_, ui::LatencyInfo(), false));
}
+void SyntheticPinchGesture::SetupCoordinates(SyntheticGestureTarget* target) {
+ const float kTouchSlopInDips = target->GetTouchSlopInDips();
+ float inner_distance_to_anchor = 2 * kTouchSlopInDips;
+ float outer_distance_to_anchor = inner_distance_to_anchor +
+ params_.total_num_pixels_covered / 2.0f +
+ kTouchSlopInDips;
+
+ // Move pointers away from each other to zoom in
+ // or towards each other to zoom out.
+ if (params_.zoom_in) {
+ current_y_0_ = params_.anchor.y() - inner_distance_to_anchor;
+ current_y_1_ = params_.anchor.y() + inner_distance_to_anchor;
+ target_y_0_ = params_.anchor.y() - outer_distance_to_anchor;
+ target_y_1_ = params_.anchor.y() + outer_distance_to_anchor;
+ } else {
+ current_y_0_ = params_.anchor.y() - outer_distance_to_anchor;
+ current_y_1_ = params_.anchor.y() + outer_distance_to_anchor;
+ target_y_0_ = params_.anchor.y() - inner_distance_to_anchor;
+ target_y_1_ = params_.anchor.y() + inner_distance_to_anchor;
+ }
+}
+
float SyntheticPinchGesture::GetDeltaForPointer0(
const base::TimeDelta& interval) const {
float total_abs_delta =
diff --git a/content/browser/renderer_host/input/synthetic_pinch_gesture.h b/content/browser/renderer_host/input/synthetic_pinch_gesture.h
index 9ca8082..6555a2a 100644
--- a/content/browser/renderer_host/input/synthetic_pinch_gesture.h
+++ b/content/browser/renderer_host/input/synthetic_pinch_gesture.h
@@ -36,6 +36,7 @@ class CONTENT_EXPORT SyntheticPinchGesture : public SyntheticGesture {
void ForwardTouchEvent(SyntheticGestureTarget* target);
+ void SetupCoordinates(SyntheticGestureTarget* target);
float GetDeltaForPointer0(const base::TimeDelta& interval) const;
float ComputeAbsoluteRemainingDistance() const;
bool HasFinished() const;
diff --git a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc
index 24f8734..5d87cd1 100644
--- a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc
+++ b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc
@@ -51,10 +51,14 @@ void SyntheticSmoothScrollGesture::ForwardTouchInputEvents(
switch (state_) {
case STARTED:
// Check for an early finish.
- if (HasScrolledEntireDistance()) {
+ if (params_.distance == 0) {
state_ = DONE;
break;
}
+ if (params_.distance > 0)
+ params_.distance += target->GetTouchSlopInDips();
+ else
+ params_.distance -= target->GetTouchSlopInDips();
touch_event_.PressPoint(params_.anchor.x(), current_y_);
ForwardTouchEvent(target);
state_ = MOVING;
diff --git a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h
index 05aa5a9..60cd7e0 100644
--- a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h
+++ b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h
@@ -32,12 +32,6 @@ class CONTENT_EXPORT SyntheticSmoothScrollGesture : public SyntheticGesture {
STOPPING,
DONE
};
- SyntheticSmoothScrollGestureParams params_;
- float current_y_;
- SyntheticWebTouchEvent touch_event_;
- SyntheticGestureParams::GestureSourceType gesture_source_type_;
- GestureState state_;
- base::TimeDelta total_stopping_wait_time_;
void ForwardTouchInputEvents(
const base::TimeDelta& interval, SyntheticGestureTarget* target);
@@ -52,6 +46,13 @@ class CONTENT_EXPORT SyntheticSmoothScrollGesture : public SyntheticGesture {
float ComputeAbsoluteRemainingDistance() const;
bool HasScrolledEntireDistance() const;
+ SyntheticSmoothScrollGestureParams params_;
+ float current_y_;
+ SyntheticWebTouchEvent touch_event_;
+ SyntheticGestureParams::GestureSourceType gesture_source_type_;
+ GestureState state_;
+ base::TimeDelta total_stopping_wait_time_;
+
DISALLOW_COPY_AND_ASSIGN(SyntheticSmoothScrollGesture);
};