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

Commit 86340be1 authored by Phil Weaver's avatar Phil Weaver Committed by ryanlwlin
Browse files

Address drag unreliability during touch exploration

The code was trying to set the location of the drag, but MotionEvent doesn't behave consistently when setting a single location to a multi-touch event.

All that's needed is to select the correct pointer, so removing messing with the location gives more consistent behavior.

Bug: 163105030
Change-Id: I6c315cf0a1e48847cc778ec8c34b382d13ce3555
Test: Manually testing at this point of the passthrough, and relying on treehugger.
parent b511a73d
Loading
Loading
Loading
Loading
+16 −33
Original line number Diff line number Diff line
@@ -631,7 +631,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
                    // Two pointers moving in the same direction within
                    // a given distance perform a drag.
                    mState.startDragging();
                    adjustEventLocationForDrag(event);
                    computeDraggingPointerIdIfNeeded(event);
                    pointerIdBits = 1 << mDraggingPointerId;
                    event.setEdgeFlags(mReceivedPointerTracker.getLastReceivedDownEdgeFlags());
                    mDispatcher.sendMotionEvent(
@@ -794,7 +794,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
                    case 2:
                        if (isDraggingGesture(event)) {
                            // If still dragging send a drag event.
                            adjustEventLocationForDrag(event);
                            computeDraggingPointerIdIfNeeded(event);
                            mDispatcher.sendMotionEvent(
                                    event, ACTION_MOVE, rawEvent, pointerIdBits, policyFlags);
                        } else {
@@ -959,44 +959,27 @@ public class TouchExplorer extends BaseEventStreamTransformation
    }

    /**
     * Adjust the location of an injected event when performing a drag. The location will be the
     * location of the finger closest to an edge of the screen.
     * Computes {@link #mDraggingPointerId} if it is invalid. The pointer will be the finger
     * closet to an edge of the screen.
     */
    private void adjustEventLocationForDrag(MotionEvent event) {
    private void computeDraggingPointerIdIfNeeded(MotionEvent event) {
        if (mDraggingPointerId != INVALID_POINTER_ID) {
            // If we have a valid pointer ID, we should be good
            final int pointerIndex = event.findPointerIndex(mDraggingPointerId);
            if (event.findPointerIndex(pointerIndex) >= 0) {
                return;
            }
        }
        // Use the pointer that is closest to its closest edge.
        final float firstPtrX = event.getX(0);
        final float firstPtrY = event.getY(0);
        final int firstPtrId = event.getPointerId(0);
        final float secondPtrX = event.getX(1);
        final float secondPtrY = event.getY(1);
        final int secondPtrId = event.getPointerId(1);
        float draggingX = firstPtrX;
        float draggingY = firstPtrY;
        if (mDraggingPointerId != INVALID_POINTER_ID) {
            // Just use the coordinates of the dragging pointer.
            int pointerIndex = event.findPointerIndex(mDraggingPointerId);
            if (pointerIndex >= 0) {
                draggingX = event.getX(pointerIndex);
                draggingY = event.getY(pointerIndex);
            } else {
                // We've lost track of the dragging pointer. Try to recover by invalidating it.
                // We'll the drop into the code below to choose a new one.
                mDraggingPointerId = INVALID_POINTER_ID;
            }
        }
        // Not quite an else, since the above code can invalidate the pointer
        if (mDraggingPointerId == INVALID_POINTER_ID) {
            // The goal is to use the coordinates of the finger that is closest to its closest edge.
            if (getDistanceToClosestEdge(firstPtrX, firstPtrY)
                    < getDistanceToClosestEdge(secondPtrX, secondPtrY)) {
                // X and Y initialized to firstPtrX and Y was right
                mDraggingPointerId = firstPtrId;
            } else {
                draggingX = secondPtrX;
                draggingY = secondPtrY;
                mDraggingPointerId = secondPtrId;
            }
        }
        event.setLocation(draggingX, draggingY);
        mDraggingPointerId = (getDistanceToClosestEdge(firstPtrX, firstPtrY)
                 < getDistanceToClosestEdge(secondPtrX, secondPtrY))
                 ? firstPtrId : secondPtrId;
    }

    private float getDistanceToClosestEdge(float x, float y) {