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

Commit 461d325b authored by Jorge Gil's avatar Jorge Gil
Browse files

Do not mark mouse events as 'drag' on ACTION_DOWN

An ACTION_DOWN event from a mouse was previously considered
a 'drag event' even though it could also be just the start of
a simple click. This caused the Desktop Mode to consume the
click event without letting it pass through to the handle bar's
click listener, resulting in the handle menu not being shown
on mouse clicks.
Instead, let DragDetector directly forward mouse events to the
EventHandler since the it has no reason to take the slop
threshold considerations unless they're touch events.

Additionaly, adds 'drag' tracking to the window decor view model
that is agnostic of the event source instead of peeking into the
internal state of DragDetector, whose mDragEvent is now only
used to detect *touch* drags.

Bug: 270761142
Test: manual - use mouse/trackpad to click on the caption handle
bar, verify it opens the handle menu

Change-Id: I3a38acbf88f42ce9a372773599b39a893fd118e4
parent ec3a11ac
Loading
Loading
Loading
Loading
+16 −15
Original line number Diff line number Diff line
@@ -193,6 +193,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
        private final DragDetector mDragDetector;

        private int mDragPointerId = -1;
        private boolean mIsDragging;

        private CaptionTouchEventListener(
                RunningTaskInfo taskInfo,
@@ -223,19 +224,15 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
            if (v.getId() != R.id.caption) {
                return false;
            }
            mDragDetector.onMotionEvent(e);

            if (e.getAction() != MotionEvent.ACTION_DOWN) {
                return false;
            }
            if (e.getAction() == MotionEvent.ACTION_DOWN) {
                final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
            if (taskInfo.isFocused) {
                return false;
            }
                if (!taskInfo.isFocused) {
                    final WindowContainerTransaction wct = new WindowContainerTransaction();
                    wct.reorder(mTaskToken, true /* onTop */);
                    mSyncQueue.queue(wct);
            return true;
                }
            }
            return mDragDetector.onMotionEvent(e);
        }

        /**
@@ -253,20 +250,24 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
                    mDragPointerId = e.getPointerId(0);
                    mDragPositioningCallback.onDragPositioningStart(
                            0 /* ctrlType */, e.getRawX(0), e.getRawY(0));
                    break;
                    mIsDragging = false;
                    return false;
                }
                case MotionEvent.ACTION_MOVE: {
                    int dragPointerIdx = e.findPointerIndex(mDragPointerId);
                    mDragPositioningCallback.onDragPositioningMove(
                            e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
                    break;
                    mIsDragging = true;
                    return true;
                }
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL: {
                    int dragPointerIdx = e.findPointerIndex(mDragPointerId);
                    mDragPositioningCallback.onDragPositioningEnd(
                            e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
                    break;
                    final boolean wasDragging = mIsDragging;
                    mIsDragging = false;
                    return wasDragging;
                }
            }
            return true;
+9 −20
Original line number Diff line number Diff line
@@ -223,6 +223,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        private final DragPositioningCallback mDragPositioningCallback;
        private final DragDetector mDragDetector;

        private boolean mIsDragging;
        private int mDragPointerId = -1;

        private DesktopModeTouchEventListener(
@@ -273,23 +274,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            if (id != R.id.caption_handle && id != R.id.desktop_mode_caption) {
                return false;
            }
            switch (e.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mDragDetector.onMotionEvent(e);
                    final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
                    if (taskInfo.isFocused) {
                        return mDragDetector.isDragEvent();
                    }
                    return false;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    boolean res = mDragDetector.isDragEvent();
                    mDragDetector.onMotionEvent(e);
                    return res;
                default:
                    mDragDetector.onMotionEvent(e);
                    return mDragDetector.isDragEvent();
            }
            return mDragDetector.onMotionEvent(e);
        }

        /**
@@ -313,13 +298,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                    mDragPointerId = e.getPointerId(0);
                    mDragPositioningCallback.onDragPositioningStart(
                            0 /* ctrlType */, e.getRawX(0), e.getRawY(0));
                    break;
                    mIsDragging = false;
                    return false;
                }
                case MotionEvent.ACTION_MOVE: {
                    final int dragPointerIdx = e.findPointerIndex(mDragPointerId);
                    mDragPositioningCallback.onDragPositioningMove(
                            e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
                    break;
                    mIsDragging = true;
                    return true;
                }
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL: {
@@ -336,7 +323,9 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                                    c -> c.moveToFullscreen(taskInfo));
                        }
                    }
                    break;
                    final boolean wasDragging = mIsDragging;
                    mIsDragging = false;
                    return wasDragging;
                }
            }
            return true;
+11 −6
Original line number Diff line number Diff line
@@ -56,10 +56,15 @@ class DragDetector {
     * {@link #mEventHandler} handles the previous down event if the event shouldn't be passed
    */
    boolean onMotionEvent(MotionEvent ev) {
        final boolean isTouchScreen =
                (ev.getSource() & SOURCE_TOUCHSCREEN) == SOURCE_TOUCHSCREEN;
        if (!isTouchScreen) {
            // Only touches generate noisy moves, so mouse/trackpad events don't need to filtered
            // to take the slop threshold into consideration.
            return mEventHandler.handleMotionEvent(ev);
        }
        switch (ev.getActionMasked()) {
            case ACTION_DOWN: {
                // Only touch screens generate noisy moves.
                mIsDragEvent = (ev.getSource() & SOURCE_TOUCHSCREEN) != SOURCE_TOUCHSCREEN;
                mDragPointerId = ev.getPointerId(0);
                float rawX = ev.getRawX(0);
                float rawY = ev.getRawY(0);
@@ -72,8 +77,12 @@ class DragDetector {
                    int dragPointerIndex = ev.findPointerIndex(mDragPointerId);
                    float dx = ev.getRawX(dragPointerIndex) - mInputDownPoint.x;
                    float dy = ev.getRawY(dragPointerIndex) - mInputDownPoint.y;
                    // Touches generate noisy moves, so only once the move is past the touch
                    // slop threshold should it be considered a drag.
                    mIsDragEvent = Math.hypot(dx, dy) > mTouchSlop;
                }
                // The event handler should only be notified about 'move' events if a drag has been
                // detected.
                if (mIsDragEvent) {
                    return mEventHandler.handleMotionEvent(ev);
                } else {
@@ -94,10 +103,6 @@ class DragDetector {
        mTouchSlop = touchSlop;
    }

    boolean isDragEvent() {
        return mIsDragEvent;
    }

    private void resetState() {
        mIsDragEvent = false;
        mInputDownPoint.set(0, 0);