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

Commit 16c0b582 authored by Alan Viverette's avatar Alan Viverette Committed by Android Git Automerger
Browse files

am 5e9d2bfb: Merge "Allow medium-long-press to initiate drag-to-open menus" into lmp-dev

* commit '5e9d2bfb0321c7711a274f25c673da814624155b':
  Allow medium-long-press to initiate drag-to-open menus
parents 9b3f1ca7 ef7ebbdf
Loading
Loading
Loading
Loading
+78 −8
Original line number Diff line number Diff line
@@ -1186,15 +1186,27 @@ public class ListPopupWindow {
        /** Timeout before disallowing intercept on the source's parent. */
        private final int mTapTimeout;

        /** Timeout before accepting a long-press to start forwarding. */
        private final int mLongPressTimeout;

        /** Source view from which events are forwarded. */
        private final View mSrc;

        /** Runnable used to prevent conflicts with scrolling parents. */
        private Runnable mDisallowIntercept;

        /** Runnable used to trigger forwarding on long-press. */
        private Runnable mTriggerLongPress;

        /** Whether this listener is currently forwarding touch events. */
        private boolean mForwarding;

        /**
         * Whether forwarding was initiated by a long-press. If so, we won't
         * force the window to dismiss when the touch stream ends.
         */
        private boolean mWasLongPress;

        /** The id of the first pointer down in the current event stream. */
        private int mActivePointerId;

@@ -1203,6 +1215,9 @@ public class ListPopupWindow {
            mScaledTouchSlop = ViewConfiguration.get(src.getContext()).getScaledTouchSlop();
            mTapTimeout = ViewConfiguration.getTapTimeout();

            // Use a medium-press timeout. Halfway between tap and long-press.
            mLongPressTimeout = (mTapTimeout + ViewConfiguration.getLongPressTimeout()) / 2;

            src.addOnAttachStateChangeListener(this);
        }

@@ -1223,7 +1238,14 @@ public class ListPopupWindow {
            final boolean wasForwarding = mForwarding;
            final boolean forwarding;
            if (wasForwarding) {
                if (mWasLongPress) {
                    // If we started forwarding as a result of a long-press,
                    // just silently stop forwarding events so that the window
                    // stays open.
                    forwarding = onTouchForwarded(event);
                } else {
                    forwarding = onTouchForwarded(event) || !onForwardingStopped();
                }
            } else {
                forwarding = onTouchObserved(event) && onForwardingStarted();

@@ -1305,21 +1327,29 @@ public class ListPopupWindow {
            switch (actionMasked) {
                case MotionEvent.ACTION_DOWN:
                    mActivePointerId = srcEvent.getPointerId(0);
                    mWasLongPress = false;

                    if (mDisallowIntercept == null) {
                        mDisallowIntercept = new DisallowIntercept();
                    }
                    src.postDelayed(mDisallowIntercept, mTapTimeout);

                    if (mTriggerLongPress == null) {
                        mTriggerLongPress = new TriggerLongPress();
                    }
                    src.postDelayed(mTriggerLongPress, mLongPressTimeout);
                    break;
                case MotionEvent.ACTION_MOVE:
                    final int activePointerIndex = srcEvent.findPointerIndex(mActivePointerId);
                    if (activePointerIndex >= 0) {
                        final float x = srcEvent.getX(activePointerIndex);
                        final float y = srcEvent.getY(activePointerIndex);

                        // Has the pointer has moved outside of the view?
                        if (!src.pointInView(x, y, mScaledTouchSlop)) {
                            // The pointer has moved outside of the view.
                            if (mDisallowIntercept != null) {
                                src.removeCallbacks(mDisallowIntercept);
                            }
                            clearCallbacks();

                            // Don't let the parent intercept our events.
                            src.getParent().requestDisallowInterceptTouchEvent(true);
                            return true;
                        }
@@ -1327,15 +1357,48 @@ public class ListPopupWindow {
                    break;
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP:
                    if (mDisallowIntercept != null) {
                        src.removeCallbacks(mDisallowIntercept);
                    }
                    clearCallbacks();
                    break;
            }

            return false;
        }

        private void clearCallbacks() {
            if (mTriggerLongPress != null) {
                mSrc.removeCallbacks(mTriggerLongPress);
            }

            if (mDisallowIntercept != null) {
                mSrc.removeCallbacks(mDisallowIntercept);
            }
        }

        private void onLongPress() {
            clearCallbacks();

            final View src = mSrc;
            if (!src.isEnabled()) {
                return;
            }

            if (!onForwardingStarted()) {
                return;
            }

            // Don't let the parent intercept our events.
            mSrc.getParent().requestDisallowInterceptTouchEvent(true);

            // Make sure we cancel any ongoing source event stream.
            final long now = SystemClock.uptimeMillis();
            final MotionEvent e = MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0);
            mSrc.onTouchEvent(e);
            e.recycle();

            mForwarding = true;
            mWasLongPress = true;
        }

        /**
         * Handled forwarded motion events and determines when to stop
         * forwarding.
@@ -1379,6 +1442,13 @@ public class ListPopupWindow {
                parent.requestDisallowInterceptTouchEvent(true);
            }
        }

        private class TriggerLongPress implements Runnable {
            @Override
            public void run() {
                onLongPress();
            }
        }
    }

    /**