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
This commit is contained in:
@@ -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) {
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.reorder(mTaskToken, true /* onTop */);
|
||||
mSyncQueue.queue(wct);
|
||||
}
|
||||
}
|
||||
final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
|
||||
if (taskInfo.isFocused) {
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user