Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b499884b authored by Jim Miller's avatar Jim Miller
Browse files

Better handling of multiple touch events in GlowPadView

This fixes a bug where a secondary touch event from the edge of the screen
would cause GlowPadView to choose the wrong target.  The issue is resolved
by keeping track of pointer ids and only allowing the one that initiated
the gesture to complete it.

Fixes bug 7133500

Change-Id: If296b60af2421bfa1a9a082e608ba77b2392a218
parent 6eeff850
Loading
Loading
Loading
Loading
+26 −7
Original line number Diff line number Diff line
@@ -197,6 +197,7 @@ public class GlowPadView extends View {
    private Tweener mBackgroundAnimator;
    private PointCloud mPointCloud;
    private float mInnerRadius;
    private int mPointerId;

    public GlowPadView(Context context) {
        this(context, null);
@@ -737,9 +738,10 @@ public class GlowPadView extends View {

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final int action = event.getAction();
        final int action = event.getActionMasked();
        boolean handled = false;
        switch (action) {
            case MotionEvent.ACTION_POINTER_DOWN:
            case MotionEvent.ACTION_DOWN:
                if (DEBUG) Log.v(TAG, "*** DOWN ***");
                handleDown(event);
@@ -753,6 +755,7 @@ public class GlowPadView extends View {
                handled = true;
                break;

            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_UP:
                if (DEBUG) Log.v(TAG, "*** UP ***");
                handleMove(event);
@@ -766,6 +769,7 @@ public class GlowPadView extends View {
                handleCancel(event);
                handled = true;
                break;

        }
        invalidate();
        return handled ? true : super.onTouchEvent(event);
@@ -777,19 +781,24 @@ public class GlowPadView extends View {
    }

    private void handleDown(MotionEvent event) {
        float eventX = event.getX();
        float eventY = event.getY();
        int actionIndex = event.getActionIndex();
        float eventX = event.getX(actionIndex);
        float eventY = event.getY(actionIndex);
        switchToState(STATE_START, eventX, eventY);
        if (!trySwitchToFirstTouchState(eventX, eventY)) {
            mDragging = false;
        } else {
            mPointerId = event.getPointerId(actionIndex);
            updateGlowPosition(eventX, eventY);
        }
    }

    private void handleUp(MotionEvent event) {
        if (DEBUG && mDragging) Log.v(TAG, "** Handle RELEASE");
        switchToState(STATE_FINISH, event.getX(), event.getY());
        int actionIndex = event.getActionIndex();
        if (event.getPointerId(actionIndex) == mPointerId) {
            switchToState(STATE_FINISH, event.getX(actionIndex), event.getY(actionIndex));
        }
    }

    private void handleCancel(MotionEvent event) {
@@ -802,7 +811,9 @@ public class GlowPadView extends View {

        // mActiveTarget = -1; // Drop the active target if canceled.

        switchToState(STATE_FINISH, event.getX(), event.getY());
        int actionIndex = event.findPointerIndex(mPointerId);
        actionIndex = actionIndex == -1 ? 0 : actionIndex;
        switchToState(STATE_FINISH, event.getX(actionIndex), event.getY(actionIndex));
    }

    private void handleMove(MotionEvent event) {
@@ -812,9 +823,17 @@ public class GlowPadView extends View {
        int ntargets = targets.size();
        float x = 0.0f;
        float y = 0.0f;
        int actionIndex = event.findPointerIndex(mPointerId);

        if (actionIndex == -1) {
            return;  // no data for this pointer
        }

        for (int k = 0; k < historySize + 1; k++) {
            float eventX = k < historySize ? event.getHistoricalX(k) : event.getX();
            float eventY = k < historySize ? event.getHistoricalY(k) : event.getY();
            float eventX = k < historySize ? event.getHistoricalX(actionIndex, k)
                    : event.getX(actionIndex);
            float eventY = k < historySize ? event.getHistoricalY(actionIndex, k)
                    : event.getY(actionIndex);
            // tx and ty are relative to wave center
            float tx = eventX - mWaveCenterX;
            float ty = eventY - mWaveCenterY;