зеркало из https://github.com/mozilla/gecko-dev.git
Bug 784887 - Use Native Gesture detector for MozGesture events. r=blassey
This commit is contained in:
Родитель
50477fa285
Коммит
294974b16e
|
@ -67,6 +67,7 @@ public class GeckoEvent {
|
|||
private static final int COMPOSITOR_PAUSE = 28;
|
||||
private static final int COMPOSITOR_RESUME = 29;
|
||||
private static final int PAINT_LISTEN_START_EVENT = 30;
|
||||
private static final int NATIVE_GESTURE_EVENT = 31;
|
||||
|
||||
/**
|
||||
* These DOM_KEY_LOCATION constants mirror the DOM KeyboardEvent's constants.
|
||||
|
@ -98,6 +99,10 @@ public class GeckoEvent {
|
|||
public static final int IME_RANGE_FORECOLOR = 2;
|
||||
public static final int IME_RANGE_BACKCOLOR = 4;
|
||||
|
||||
public static final int ACTION_MAGNIFY_START = 11;
|
||||
public static final int ACTION_MAGNIFY = 12;
|
||||
public static final int ACTION_MAGNIFY_END = 13;
|
||||
|
||||
final public int mType;
|
||||
public int mAction;
|
||||
public long mTime;
|
||||
|
@ -260,6 +265,21 @@ public class GeckoEvent {
|
|||
}
|
||||
}
|
||||
|
||||
public static GeckoEvent createNativeGestureEvent(int action, PointF pt, double size) {
|
||||
GeckoEvent event = new GeckoEvent(NATIVE_GESTURE_EVENT);
|
||||
event.mAction = action;
|
||||
event.mCount = 1;
|
||||
event.mPoints = new Point[1];
|
||||
|
||||
PointF geckoPoint = new PointF(pt.x, pt.y);
|
||||
geckoPoint = GeckoApp.mAppContext.getLayerView().convertViewPointToLayerPoint(geckoPoint);
|
||||
event.mPoints[0] = new Point(Math.round(geckoPoint.x), Math.round(geckoPoint.y));
|
||||
|
||||
event.mX = size;
|
||||
event.mTime = System.currentTimeMillis();
|
||||
return event;
|
||||
}
|
||||
|
||||
public static GeckoEvent createMotionEvent(MotionEvent m) {
|
||||
GeckoEvent event = new GeckoEvent(MOTION_EVENT);
|
||||
event.initMotionEvent(m);
|
||||
|
|
|
@ -870,6 +870,8 @@ public class PanZoomController
|
|||
mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY());
|
||||
cancelTouch();
|
||||
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY_START, mLastZoomFocus, getMetrics().zoomFactor));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -938,6 +940,9 @@ public class PanZoomController
|
|||
|
||||
mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY());
|
||||
|
||||
GeckoEvent event = GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY, mLastZoomFocus, getMetrics().zoomFactor);
|
||||
GeckoAppShell.sendEventToGecko(event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -951,6 +956,10 @@ public class PanZoomController
|
|||
|
||||
// Force a viewport synchronisation
|
||||
mTarget.setForceRedraw();
|
||||
|
||||
PointF point = new PointF(detector.getFocusX(), detector.getFocusY());
|
||||
GeckoEvent event = GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY_END, point, getMetrics().zoomFactor);
|
||||
GeckoAppShell.sendEventToGecko(event);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -511,6 +511,15 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
|
|||
ReadCharactersField(jenv);
|
||||
break;
|
||||
|
||||
case NATIVE_GESTURE_EVENT:
|
||||
mTime = jenv->GetLongField(jobj, jTimeField);
|
||||
mMetaState = jenv->GetIntField(jobj, jMetaStateField);
|
||||
mCount = jenv->GetIntField(jobj, jCountField);
|
||||
ReadPointArray(mPoints, jenv, jPoints, mCount);
|
||||
mX = jenv->GetDoubleField(jobj, jXField);
|
||||
|
||||
break;
|
||||
|
||||
case MOTION_EVENT:
|
||||
mTime = jenv->GetLongField(jobj, jTimeField);
|
||||
mMetaState = jenv->GetIntField(jobj, jMetaStateField);
|
||||
|
|
|
@ -555,6 +555,9 @@ public:
|
|||
ACTION_HOVER_MOVE = 7,
|
||||
ACTION_HOVER_ENTER = 9,
|
||||
ACTION_HOVER_EXIT = 10,
|
||||
ACTION_MAGNIFY_START = 11,
|
||||
ACTION_MAGNIFY = 12,
|
||||
ACTION_MAGNIFY_END = 13,
|
||||
ACTION_POINTER_ID_MASK = 0xff00,
|
||||
ACTION_POINTER_ID_SHIFT = 8,
|
||||
EDGE_TOP = 0x00000001,
|
||||
|
@ -761,6 +764,7 @@ public:
|
|||
COMPOSITOR_PAUSE = 28,
|
||||
COMPOSITOR_RESUME = 29,
|
||||
PAINT_LISTEN_START_EVENT = 30,
|
||||
NATIVE_GESTURE_EVENT = 31,
|
||||
dummy_java_enum_list_end
|
||||
};
|
||||
|
||||
|
|
|
@ -230,10 +230,6 @@ nsWindow::Create(nsIWidget *aParent,
|
|||
mParent = parent;
|
||||
}
|
||||
|
||||
float dpi = GetDPI();
|
||||
mSwipeMaxPinchDelta = SWIPE_MAX_PINCH_DELTA_INCHES * dpi;
|
||||
mSwipeMinDistance = SWIPE_MIN_DISTANCE_INCHES * dpi;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -845,10 +841,6 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
|||
#endif
|
||||
if (target) {
|
||||
bool preventDefaultActions = target->OnMultitouchEvent(ae);
|
||||
if (!preventDefaultActions && ae->Count() == 2) {
|
||||
target->OnGestureEvent(ae);
|
||||
}
|
||||
|
||||
if (!preventDefaultActions && ae->Count() < 2)
|
||||
target->OnMouseEvent(ae);
|
||||
}
|
||||
|
@ -856,6 +848,20 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
|||
break;
|
||||
}
|
||||
|
||||
case AndroidGeckoEvent::NATIVE_GESTURE_EVENT: {
|
||||
nsIntPoint pt(0,0);
|
||||
nsTArray<nsIntPoint> points = ae->Points();
|
||||
if (points.Length() > 0) {
|
||||
pt = points[0];
|
||||
}
|
||||
pt.x = clamped(pt.x, 0, NS_MAX(gAndroidBounds.width - 1, 0));
|
||||
pt.y = clamped(pt.y, 0, NS_MAX(gAndroidBounds.height - 1, 0));
|
||||
nsWindow *target = win->FindWindowForPoint(pt);
|
||||
|
||||
target->OnNativeGestureEvent(ae);
|
||||
break;
|
||||
}
|
||||
|
||||
case AndroidGeckoEvent::KEY_EVENT:
|
||||
win->UserActivity();
|
||||
if (win->mFocus)
|
||||
|
@ -1338,14 +1344,6 @@ send_again:
|
|||
}
|
||||
}
|
||||
|
||||
static double
|
||||
getDistance(const nsIntPoint &p1, const nsIntPoint &p2)
|
||||
{
|
||||
double deltaX = p2.x - p1.x;
|
||||
double deltaY = p2.y - p1.y;
|
||||
return sqrt(deltaX*deltaX + deltaY*deltaY);
|
||||
}
|
||||
|
||||
bool nsWindow::OnMultitouchEvent(AndroidGeckoEvent *ae)
|
||||
{
|
||||
nsRefPtr<nsWindow> kungFuDeathGrip(this);
|
||||
|
@ -1450,80 +1448,34 @@ nsWindow::DispatchMultitouchEvent(nsTouchEvent &event, AndroidGeckoEvent *ae)
|
|||
}
|
||||
|
||||
void
|
||||
nsWindow::OnGestureEvent(AndroidGeckoEvent *ae)
|
||||
nsWindow::OnNativeGestureEvent(AndroidGeckoEvent *ae)
|
||||
{
|
||||
uint32_t msg = 0;
|
||||
nsIntPoint pt(ae->Points()[0].x,
|
||||
ae->Points()[0].y);
|
||||
double delta = ae->X();
|
||||
int msg = 0;
|
||||
|
||||
nsIntPoint midPoint;
|
||||
midPoint.x = ((ae->Points()[0].x + ae->Points()[1].x) / 2);
|
||||
midPoint.y = ((ae->Points()[0].y + ae->Points()[1].y) / 2);
|
||||
nsIntPoint refPoint = midPoint - WidgetToScreenOffset();
|
||||
switch (ae->Action() & AndroidMotionEvent::ACTION_MASK) {
|
||||
case AndroidMotionEvent::ACTION_MAGNIFY_START:
|
||||
msg = NS_SIMPLE_GESTURE_MAGNIFY_START;
|
||||
mStartDist = delta;
|
||||
mLastDist = delta;
|
||||
break;
|
||||
case AndroidMotionEvent::ACTION_MAGNIFY:
|
||||
msg = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
|
||||
delta -= mLastDist;
|
||||
mLastDist += delta;
|
||||
break;
|
||||
case AndroidMotionEvent::ACTION_MAGNIFY_END:
|
||||
msg = NS_SIMPLE_GESTURE_MAGNIFY;
|
||||
delta -= mStartDist;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
double pinchDist = getDistance(ae->Points()[0], ae->Points()[1]);
|
||||
double pinchDelta = 0;
|
||||
|
||||
switch (ae->Action() & AndroidMotionEvent::ACTION_MASK) {
|
||||
case AndroidMotionEvent::ACTION_POINTER_DOWN:
|
||||
msg = NS_SIMPLE_GESTURE_MAGNIFY_START;
|
||||
mStartPoint = new nsIntPoint(midPoint);
|
||||
mStartDist = mLastDist = pinchDist;
|
||||
mGestureFinished = false;
|
||||
break;
|
||||
case AndroidMotionEvent::ACTION_MOVE:
|
||||
msg = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
|
||||
pinchDelta = pinchDist - mLastDist;
|
||||
mLastDist = pinchDist;
|
||||
break;
|
||||
case AndroidMotionEvent::ACTION_POINTER_UP:
|
||||
msg = NS_SIMPLE_GESTURE_MAGNIFY;
|
||||
pinchDelta = pinchDist - mStartDist;
|
||||
mStartPoint = nullptr;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mGestureFinished) {
|
||||
nsRefPtr<nsWindow> kungFuDeathGrip(this);
|
||||
DispatchGestureEvent(msg, 0, pinchDelta, refPoint, ae->Time());
|
||||
if (Destroyed())
|
||||
return;
|
||||
|
||||
// If the cumulative pinch delta goes past the threshold, treat this
|
||||
// as a pinch only, and not a swipe.
|
||||
if (fabs(pinchDist - mStartDist) > mSwipeMaxPinchDelta)
|
||||
mStartPoint = nullptr;
|
||||
|
||||
// If we have traveled more than SWIPE_MIN_DISTANCE from the start
|
||||
// point, stop the pinch gesture and fire a swipe event.
|
||||
if (mStartPoint) {
|
||||
double swipeDistance = getDistance(midPoint, *mStartPoint);
|
||||
if (swipeDistance > mSwipeMinDistance) {
|
||||
uint32_t direction = 0;
|
||||
nsIntPoint motion = midPoint - *mStartPoint;
|
||||
|
||||
if (motion.x < -swipeDistance/2)
|
||||
direction |= nsIDOMSimpleGestureEvent::DIRECTION_LEFT;
|
||||
if (motion.x > swipeDistance/2)
|
||||
direction |= nsIDOMSimpleGestureEvent::DIRECTION_RIGHT;
|
||||
if (motion.y < -swipeDistance/2)
|
||||
direction |= nsIDOMSimpleGestureEvent::DIRECTION_UP;
|
||||
if (motion.y > swipeDistance/2)
|
||||
direction |= nsIDOMSimpleGestureEvent::DIRECTION_DOWN;
|
||||
|
||||
// Finish the pinch gesture, then fire the swipe event:
|
||||
msg = NS_SIMPLE_GESTURE_MAGNIFY;
|
||||
DispatchGestureEvent(msg, 0, pinchDist - mStartDist, refPoint, ae->Time());
|
||||
if (Destroyed())
|
||||
return;
|
||||
msg = NS_SIMPLE_GESTURE_SWIPE;
|
||||
DispatchGestureEvent(msg, direction, 0, refPoint, ae->Time());
|
||||
|
||||
// Don't generate any more gesture events for this touch.
|
||||
mGestureFinished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
nsRefPtr<nsWindow> kungFuDeathGrip(this);
|
||||
DispatchGestureEvent(msg, 0, delta, pt, ae->Time());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
void OnAndroidEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnDraw(mozilla::AndroidGeckoEvent *ae);
|
||||
bool OnMultitouchEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnGestureEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnNativeGestureEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnMouseEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnKeyEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
void OnIMEEvent(mozilla::AndroidGeckoEvent *ae);
|
||||
|
@ -177,14 +177,8 @@ protected:
|
|||
nsWindow* mParent;
|
||||
nsWindow* mFocus;
|
||||
|
||||
bool mGestureFinished;
|
||||
double mStartDist;
|
||||
double mLastDist;
|
||||
nsAutoPtr<nsIntPoint> mStartPoint;
|
||||
|
||||
// Multitouch swipe thresholds in screen pixels
|
||||
double mSwipeMaxPinchDelta;
|
||||
double mSwipeMinDistance;
|
||||
|
||||
nsCOMPtr<nsIIdleServiceInternal> mIdleService;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче