Skip to content

Commit

Permalink
Add support for touch events on Android
Browse files Browse the repository at this point in the history
Currently on Android we treat all touch events as scroll events. Servo
is already capable of distinguishing between scroll-touches and regular
touch events (see `on_touch_move` in `components/compositor/touch.rs`),
so we should just be passing touch events through.

Servo however does not natively support fling gestures, so we continue
to use `GestureDetector` for that.
  • Loading branch information
Manishearth committed Nov 21, 2018
1 parent f1dd31f commit 3bccb8c
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 18 deletions.
42 changes: 41 additions & 1 deletion ports/libsimpleservo/src/api.rs
Expand Up @@ -9,7 +9,7 @@ use servo::embedder_traits::resources::{self, Resource};
use servo::embedder_traits::EmbedderMsg;
use servo::euclid::{TypedPoint2D, TypedScale, TypedSize2D, TypedVector2D};
use servo::msg::constellation_msg::TraversalDirection;
use servo::script_traits::{MouseButton, TouchEventType};
use servo::script_traits::{MouseButton, TouchEventType, TouchId};
use servo::servo_config::opts;
use servo::servo_config::prefs::{PrefValue, PREFS};
use servo::servo_url::ServoUrl;
Expand Down Expand Up @@ -312,6 +312,46 @@ impl ServoGlue {
self.process_event(event)
}

/// Touch event: press down
pub fn touch_down(&mut self, x: f32, y: f32, pointer_id: i32) -> Result<(), &'static str> {
let event = WindowEvent::Touch(
TouchEventType::Down,
TouchId(pointer_id),
TypedPoint2D::new(x as f32, y as f32),
);
self.process_event(event)
}

/// Touch event: move touching finger
pub fn touch_move(&mut self, x: f32, y: f32, pointer_id: i32) -> Result<(), &'static str> {
let event = WindowEvent::Touch(
TouchEventType::Move,
TouchId(pointer_id),
TypedPoint2D::new(x as f32, y as f32),
);
self.process_event(event)
}

/// Touch event: Lift touching finger
pub fn touch_up(&mut self, x: f32, y: f32, pointer_id: i32) -> Result<(), &'static str> {
let event = WindowEvent::Touch(
TouchEventType::Up,
TouchId(pointer_id),
TypedPoint2D::new(x as f32, y as f32),
);
self.process_event(event)
}

/// Cancel touch event
pub fn touch_cancel(&mut self, x: f32, y: f32, pointer_id: i32) -> Result<(), &'static str> {
let event = WindowEvent::Touch(
TouchEventType::Cancel,
TouchId(pointer_id),
TypedPoint2D::new(x as f32, y as f32),
);
self.process_event(event)
}

/// Start pinchzoom.
/// x/y are pinch origin coordinates.
pub fn pinchzoom_start(&mut self, factor: f32, _x: u32, _y: u32) -> Result<(), &'static str> {
Expand Down
24 changes: 24 additions & 0 deletions ports/libsimpleservo/src/capi.rs
Expand Up @@ -205,6 +205,30 @@ pub extern "C" fn scroll(dx: i32, dy: i32, x: i32, y: i32) {
call(|s| s.scroll(dx as i32, dy as i32, x as u32, y as u32));
}

#[no_mangle]
pub extern "C" fn touch_down(x: f32, y: f32, pointer_id: i32) {
debug!("touch down");
call(|s| s.touch_down(x, y, pointer_id));
}

#[no_mangle]
pub extern "C" fn touch_up(x: f32, y: f32, pointer_id: i32) {
debug!("touch up");
call(|s| s.touch_up(x, y, pointer_id));
}

#[no_mangle]
pub extern "C" fn touch_move(x: f32, y: f32, pointer_id: i32) {
debug!("touch move");
call(|s| s.touch_move(x, y, pointer_id));
}

#[no_mangle]
pub extern "C" fn touch_cancel(x: f32, y: f32, pointer_id: i32) {
debug!("touch cancel");
call(|s| s.touch_cancel(x, y, pointer_id));
}

#[no_mangle]
pub extern "C" fn pinchzoom_start(factor: f32, x: i32, y: i32) {
debug!("pinchzoom_start");
Expand Down
48 changes: 48 additions & 0 deletions ports/libsimpleservo/src/jniapi.rs
Expand Up @@ -230,6 +230,54 @@ pub fn Java_org_mozilla_servoview_JNIServo_scroll(
call(&env, |s| s.scroll(dx as i32, dy as i32, x as u32, y as u32));
}

#[no_mangle]
pub fn Java_org_mozilla_servoview_JNIServo_touchDown(
env: JNIEnv,
_: JClass,
x: jfloat,
y: jfloat,
pointer_id: jint,
) {
debug!("touchDown");
call(&env, |s| s.touch_down(x, y, pointer_id as i32));
}

#[no_mangle]
pub fn Java_org_mozilla_servoview_JNIServo_touchUp(
env: JNIEnv,
_: JClass,
x: jfloat,
y: jfloat,
pointer_id: jint,
) {
debug!("touchUp");
call(&env, |s| s.touch_up(x, y, pointer_id as i32));
}

#[no_mangle]
pub fn Java_org_mozilla_servoview_JNIServo_touchMove(
env: JNIEnv,
_: JClass,
x: jfloat,
y: jfloat,
pointer_id: jint,
) {
debug!("touchMove");
call(&env, |s| s.touch_move(x, y, pointer_id as i32));
}

#[no_mangle]
pub fn Java_org_mozilla_servoview_JNIServo_touchCancel(
env: JNIEnv,
_: JClass,
x: jfloat,
y: jfloat,
pointer_id: jint,
) {
debug!("touchCancel");
call(&env, |s| s.touch_cancel(x, y, pointer_id as i32));
}

#[no_mangle]
pub fn Java_org_mozilla_servoview_JNIServo_pinchZoomStart(
env: JNIEnv,
Expand Down
Expand Up @@ -50,6 +50,14 @@ public class JNIServo {

public native void scrollEnd(int dx, int dy, int x, int y);

public native void touchDown(float x, float y, int pointer_id);

public native void touchMove(float x, float y, int pointer_id);

public native void touchUp(float x, float y, int pointer_id);

public native void touchCancel(float x, float y, int pointer_id);

public native void pinchZoomStart(float factor, int x, int y);

public native void pinchZoom(float factor, int x, int y);
Expand Down
Expand Up @@ -107,6 +107,22 @@ public void scrollEnd(int dx, int dy, int x, int y) {
mRunCallback.inGLThread(() -> mJNI.scrollEnd(dx, dy, x, y));
}

public void touchDown(float x, float y, int pointerId) {
mRunCallback.inGLThread(() -> mJNI.touchDown(x, y, pointerId));
}

public void touchMove(float x, float y, int pointerId) {
mRunCallback.inGLThread(() -> mJNI.touchMove(x, y, pointerId));
}

public void touchUp(float x, float y, int pointerId) {
mRunCallback.inGLThread(() -> mJNI.touchUp(x, y, pointerId));
}

public void touchCancel(float x, float y, int pointerId) {
mRunCallback.inGLThread(() -> mJNI.touchCancel(x, y, pointerId));
}

public void pinchZoomStart(float factor, int x, int y) {
mRunCallback.inGLThread(() -> mJNI.pinchZoomStart(factor, x, y));
}
Expand Down
Expand Up @@ -53,7 +53,6 @@ public class ServoView extends GLSurfaceView
private int mLastY = 0;
private int mCurY = 0;
private boolean mFlinging;
private boolean mScrolling;

private boolean mZooming;
private float mZoomFactor = 1;
Expand Down Expand Up @@ -199,7 +198,6 @@ public void doFrame(long frameTimeNanos) {

if (mFlinging && mScroller.isFinished()) {
mFlinging = false;
mScrolling = false;
mServo.scrollEnd(0, 0, mCurX, mCurY);
}

Expand All @@ -215,7 +213,7 @@ public void doFrame(long frameTimeNanos) {
mLastX = mCurX;
mLastY = mCurY;

boolean scrollNecessary = mScrolling && (dx != 0 || dy != 0);
boolean scrollNecessary = mFlinging && (dx != 0 || dy != 0);
boolean zoomNecessary = mZooming && mZoomFactor != 1;

if (scrollNecessary) {
Expand All @@ -231,7 +229,7 @@ public void doFrame(long frameTimeNanos) {
mServo.performUpdates();
}

if (mZooming || mScrolling || mAnimating) {
if (mZooming || mFlinging || mAnimating) {
Choreographer.getInstance().postFrameCallback(this);
} else {
mRedrawing = false;
Expand All @@ -251,6 +249,8 @@ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float ve
mCurY = velocityY < 0 ? mPageHeight : 0;
mLastY = mCurY;
mScroller.fling(mCurX, mCurY, (int) velocityX, (int) velocityY, 0, mPageWidth, 0, mPageHeight);
mServo.scrollStart(0, 0, mCurX, mCurY);
startLooping();
return true;
}

Expand All @@ -264,28 +264,31 @@ public boolean onTouchEvent(final MotionEvent e) {
mScaleGestureDetector.onTouchEvent(e);

int action = e.getActionMasked();
float x = e.getX();

float y = e.getY();

int pointerIndex = e.getActionIndex();
int pointerId = e.getPointerId(pointerIndex);
switch (action) {
case (MotionEvent.ACTION_DOWN):
mCurX = (int) e.getX();
mServo.touchDown(x, y, pointerId);
mFlinging = false;
mScroller.forceFinished(true);
mCurX = (int) x;
mLastX = mCurX;
mCurY = (int) e.getY();
mCurY = (int) y;
mLastY = mCurY;
mScroller.forceFinished(true);
mFlinging = false;
mServo.scrollStart(0, 0, mCurX, mCurY);
mScrolling = true;
startLooping();
return true;
case (MotionEvent.ACTION_MOVE):
mCurX = (int) e.getX();
mCurY = (int) e.getY();
mCurX = (int) x;
mCurY = (int) y;
mServo.touchMove(x, y, pointerId);
return true;
case (MotionEvent.ACTION_UP):
mServo.touchUp(x, y, pointerId);
case (MotionEvent.ACTION_CANCEL):
if (!mFlinging) {
mScrolling = false;
mServo.scrollEnd(0, 0, mCurX, mCurY);
}
mServo.touchCancel(x, y, pointerId);
return true;
default:
return true;
Expand Down

0 comments on commit 3bccb8c

Please sign in to comment.