author | Wes Johnston <wjohnston@mozilla.com> |
Tue, 02 Oct 2012 13:18:21 -0700 | |
changeset 108929 | f1646acf98b30d1e2b6f9ee6c8a85cf11c3e8196 |
parent 108928 | d5a3c148545c244b31b1a7217c31b49873f0a0f9 |
child 108930 | 25a38fc220d67790171cd7d4adaa9c28c06f746d |
push id | 15764 |
push user | wjohnston@mozilla.com |
push date | Tue, 02 Oct 2012 20:18:49 +0000 |
treeherder | mozilla-inbound@f1646acf98b3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | blassey |
bugs | 784887 |
milestone | 18.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/mobile/android/base/GeckoEvent.java +++ b/mobile/android/base/GeckoEvent.java @@ -62,16 +62,17 @@ public class GeckoEvent { private static final int UNUSED3_EVENT = 23; private static final int ACTIVITY_RESUMING = 24; private static final int SCREENSHOT = 25; private static final int UNUSED2_EVENT = 26; private static final int SCREENORIENTATION_CHANGED = 27; 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. * @see https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent#Key_location_constants */ private static final int DOM_KEY_LOCATION_STANDARD = 0; private static final int DOM_KEY_LOCATION_LEFT = 1; private static final int DOM_KEY_LOCATION_RIGHT = 2; @@ -93,16 +94,20 @@ public class GeckoEvent { public static final int IME_RANGE_SELECTEDRAWTEXT = 3; public static final int IME_RANGE_CONVERTEDTEXT = 4; public static final int IME_RANGE_SELECTEDCONVERTEDTEXT = 5; public static final int IME_RANGE_UNDERLINE = 1; 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; public Point[] mPoints; public int[] mPointIndicies; public int mPointerIndex; // index of the point that has changed public float[] mOrientations; public float[] mPressures; @@ -255,16 +260,31 @@ public class GeckoEvent { case KeyEvent.KEYCODE_BUTTON_15: case KeyEvent.KEYCODE_BUTTON_16: return true; default: return false; } } + 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); return event; } private void initMotionEvent(MotionEvent m) { mAction = m.getAction();
--- a/mobile/android/base/ui/PanZoomController.java +++ b/mobile/android/base/ui/PanZoomController.java @@ -865,16 +865,18 @@ public class PanZoomController if (!mTarget.getZoomConstraints().getAllowZoom()) return false; setState(PanZoomState.PINCHING); mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY()); cancelTouch(); + GeckoAppShell.sendEventToGecko(GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY_START, mLastZoomFocus, getMetrics().zoomFactor)); + return true; } @Override public boolean onScale(SimpleScaleGestureDetector detector) { if (GeckoApp.mAppContext == null || GeckoApp.mAppContext.mDOMFullScreen) return false; @@ -933,29 +935,36 @@ public class PanZoomController scrollBy(new PointF(mLastZoomFocus.x - detector.getFocusX(), mLastZoomFocus.y - detector.getFocusY())); PointF focus = new PointF(detector.getFocusX(), detector.getFocusY()); scaleWithFocus(newZoomFactor, focus); } mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY()); + GeckoEvent event = GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY, mLastZoomFocus, getMetrics().zoomFactor); + GeckoAppShell.sendEventToGecko(event); + return true; } @Override public void onScaleEnd(SimpleScaleGestureDetector detector) { if (mState == PanZoomState.ANIMATED_ZOOM) return; // switch back to the touching state startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime()); // 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); } /** * Scales the viewport, keeping the given focus point in the same place before and after the * scale operation. You must hold the monitor while calling this. */ private void scaleWithFocus(float zoomFactor, PointF focus) { ViewportMetrics viewportMetrics = getMutableMetrics();
--- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -506,16 +506,25 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jo mDomKeyLocation = jenv->GetIntField(jobj, jDomKeyLocationField); mFlags = jenv->GetIntField(jobj, jFlagsField); mKeyCode = jenv->GetIntField(jobj, jKeyCodeField); mUnicodeChar = jenv->GetIntField(jobj, jUnicodeCharField); mRepeatCount = jenv->GetIntField(jobj, jRepeatCountField); 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); mCount = jenv->GetIntField(jobj, jCountField); mPointerIndex = jenv->GetIntField(jobj, jPointerIndexField); ReadPointArray(mPointRadii, jenv, jPointRadii, mCount); ReadFloatArray(mOrientations, jenv, jOrientations, mCount);
--- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -550,16 +550,19 @@ public: ACTION_MOVE = 2, ACTION_CANCEL = 3, ACTION_OUTSIDE = 4, ACTION_POINTER_DOWN = 5, ACTION_POINTER_UP = 6, 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, EDGE_BOTTOM = 0x00000002, EDGE_LEFT = 0x00000004, EDGE_RIGHT = 0x00000008, SAMPLE_X = 0, SAMPLE_Y = 1, @@ -756,16 +759,17 @@ public: UNUSED3_EVENT = 23, ACTIVITY_RESUMING = 24, SCREENSHOT = 25, UNUSED2_EVENT = 26, SCREENORIENTATION_CHANGED = 27, COMPOSITOR_PAUSE = 28, COMPOSITOR_RESUME = 29, PAINT_LISTEN_START_EVENT = 30, + NATIVE_GESTURE_EVENT = 31, dummy_java_enum_list_end }; enum { IME_COMPOSITION_END = 0, IME_COMPOSITION_BEGIN = 1, IME_SET_TEXT = 2, IME_GET_TEXT = 3,
--- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -225,20 +225,16 @@ nsWindow::Create(nsIWidget *aParent, gTopLevelWindows.AppendElement(this); } if (parent) { parent->mChildren.AppendElement(this); mParent = parent; } - float dpi = GetDPI(); - mSwipeMaxPinchDelta = SWIPE_MAX_PINCH_DELTA_INCHES * dpi; - mSwipeMinDistance = SWIPE_MIN_DISTANCE_INCHES * dpi; - return NS_OK; } NS_IMETHODIMP nsWindow::Destroy(void) { nsBaseWidget::mOnDestroyCalled = true; @@ -840,27 +836,37 @@ nsWindow::OnGlobalAndroidEvent(AndroidGe ALOG("MOTION_EVENT %f,%f -> %p (visible: %d children: %d)", pt.x, pt.y, (void*)target, target ? target->mIsVisible : 0, target ? target->mChildren.Length() : 0); DumpWindows(); #endif if (target) { bool preventDefaultActions = target->OnMultitouchEvent(ae); - if (!preventDefaultActions && ae->Count() == 2) { - target->OnGestureEvent(ae); - } - if (!preventDefaultActions && ae->Count() < 2) target->OnMouseEvent(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) win->mFocus->OnKeyEvent(ae); break; case AndroidGeckoEvent::DRAW: layers::renderTraceEventStart("Global draw start", "414141"); @@ -1333,24 +1339,16 @@ send_again: return; if (msg == NS_MOUSE_BUTTON_DOWN) { msg = NS_MOUSE_MOVE; goto 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); // This is set to true once we have called SetPreventPanning() exactly // once for a given sequence of touch events. It is reset on the start // of the next sequence. static bool sDefaultPreventedNotified = false; @@ -1445,90 +1443,44 @@ nsWindow::DispatchMultitouchEvent(nsTouc } nsEventStatus status; DispatchEvent(&event, status); return (status == nsEventStatus_eConsumeNoDefault); } void -nsWindow::OnGestureEvent(AndroidGeckoEvent *ae) +nsWindow::OnNativeGestureEvent(AndroidGeckoEvent *ae) { - uint32_t 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(); - - 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; - } + nsIntPoint pt(ae->Points()[0].x, + ae->Points()[0].y); + double delta = ae->X(); + int msg = 0; - 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; + 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; + } - 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 nsWindow::DispatchGestureEvent(uint32_t msg, uint32_t direction, double delta, const nsIntPoint &refPoint, uint64_t time) { nsSimpleGestureEvent event(true, msg, this, direction, delta);
--- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -45,17 +45,17 @@ public: static gfxIntSize GetAndroidScreenBounds(); static nsWindow* TopWindow(); nsWindow* FindWindowForPoint(const nsIntPoint& pt); 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); void OnSizeChanged(const gfxIntSize& aSize); void InitEvent(nsGUIEvent& event, nsIntPoint* aPoint = 0); @@ -172,24 +172,18 @@ protected: // event (like a keypress or mouse click). void UserActivity(); bool mIsVisible; nsTArray<nsWindow*> mChildren; 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; bool mIMEComposing; nsString mIMEComposingText; nsString mIMELastDispatchedComposingText; nsAutoTArray<nsTextRange, 4> mIMERanges;