Merge "Prevent handle menu from opening on drag." into tm-qpr-dev am: 0977b1af31 am: 851aa34195
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20355140 Change-Id: Ie3deb33904fa1e29d0693fa18719927e005579b6 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -124,7 +124,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
|
||||
TaskPositioner taskPositioner = new TaskPositioner(mTaskOrganizer, windowDecoration,
|
||||
mDragStartListener);
|
||||
CaptionTouchEventListener touchEventListener =
|
||||
new CaptionTouchEventListener(taskInfo, taskPositioner);
|
||||
new CaptionTouchEventListener(taskInfo, taskPositioner,
|
||||
windowDecoration.getDragDetector());
|
||||
windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
|
||||
windowDecoration.setDragResizeCallback(taskPositioner);
|
||||
setupWindowDecorationForTransition(taskInfo, startT, finishT);
|
||||
@@ -173,16 +174,18 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
|
||||
private final int mTaskId;
|
||||
private final WindowContainerToken mTaskToken;
|
||||
private final DragResizeCallback mDragResizeCallback;
|
||||
private final DragDetector mDragDetector;
|
||||
|
||||
private int mDragPointerId = -1;
|
||||
private boolean mDragActive = false;
|
||||
|
||||
private CaptionTouchEventListener(
|
||||
RunningTaskInfo taskInfo,
|
||||
DragResizeCallback dragResizeCallback) {
|
||||
DragResizeCallback dragResizeCallback,
|
||||
DragDetector dragDetector) {
|
||||
mTaskId = taskInfo.taskId;
|
||||
mTaskToken = taskInfo.token;
|
||||
mDragResizeCallback = dragResizeCallback;
|
||||
mDragDetector = dragDetector;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -231,19 +234,21 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent e) {
|
||||
boolean isDrag = false;
|
||||
int id = v.getId();
|
||||
if (id != R.id.caption_handle && id != R.id.caption) {
|
||||
return false;
|
||||
}
|
||||
if (id == R.id.caption_handle || mDragActive) {
|
||||
if (id == R.id.caption_handle) {
|
||||
isDrag = mDragDetector.detectDragEvent(e);
|
||||
handleEventForMove(e);
|
||||
}
|
||||
if (e.getAction() != MotionEvent.ACTION_DOWN) {
|
||||
return false;
|
||||
return isDrag;
|
||||
}
|
||||
RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
|
||||
if (taskInfo.isFocused) {
|
||||
return false;
|
||||
return isDrag;
|
||||
}
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.reorder(mTaskToken, true /* onTop */);
|
||||
@@ -251,6 +256,10 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param e {@link MotionEvent} to process
|
||||
* @return {@code true} if a drag is happening; or {@code false} if it is not
|
||||
*/
|
||||
private void handleEventForMove(MotionEvent e) {
|
||||
RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
|
||||
int windowingMode = mDesktopModeController
|
||||
@@ -259,12 +268,12 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
|
||||
return;
|
||||
}
|
||||
switch (e.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mDragActive = true;
|
||||
mDragPointerId = e.getPointerId(0);
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
mDragPointerId = e.getPointerId(0);
|
||||
mDragResizeCallback.onDragResizeStart(
|
||||
0 /* ctrlType */, e.getRawX(0), e.getRawY(0));
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
int dragPointerIdx = e.findPointerIndex(mDragPointerId);
|
||||
mDragResizeCallback.onDragResizeMove(
|
||||
@@ -273,7 +282,6 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
|
||||
}
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL: {
|
||||
mDragActive = false;
|
||||
int dragPointerIdx = e.findPointerIndex(mDragPointerId);
|
||||
int statusBarHeight = mDisplayController.getDisplayLayout(taskInfo.displayId)
|
||||
.stableInsets().top;
|
||||
|
||||
@@ -62,6 +62,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
|
||||
|
||||
private boolean mDesktopActive;
|
||||
|
||||
private DragDetector mDragDetector;
|
||||
|
||||
private AdditionalWindow mHandleMenu;
|
||||
|
||||
CaptionWindowDecoration(
|
||||
@@ -79,6 +81,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
|
||||
mChoreographer = choreographer;
|
||||
mSyncQueue = syncQueue;
|
||||
mDesktopActive = DesktopModeStatus.isActive(mContext);
|
||||
mDragDetector = new DragDetector(ViewConfiguration.get(context).getScaledTouchSlop());
|
||||
}
|
||||
|
||||
void setCaptionListeners(
|
||||
@@ -92,6 +95,10 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
|
||||
mDragResizeCallback = dragResizeCallback;
|
||||
}
|
||||
|
||||
DragDetector getDragDetector() {
|
||||
return mDragDetector;
|
||||
}
|
||||
|
||||
@Override
|
||||
void relayout(ActivityManager.RunningTaskInfo taskInfo) {
|
||||
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
@@ -182,6 +189,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
|
||||
}
|
||||
|
||||
int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext()).getScaledTouchSlop();
|
||||
mDragDetector.setTouchSlop(touchSlop);
|
||||
|
||||
int resize_handle = mResult.mRootView.getResources()
|
||||
.getDimensionPixelSize(R.dimen.freeform_resize_handle);
|
||||
int resize_corner = mResult.mRootView.getResources()
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.wm.shell.windowdecor;
|
||||
|
||||
import static android.view.MotionEvent.ACTION_CANCEL;
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
import static android.view.MotionEvent.ACTION_MOVE;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* A detector for touch inputs that differentiates between drag and click inputs.
|
||||
* All touch events must be passed through this class to track a drag event.
|
||||
*/
|
||||
public class DragDetector {
|
||||
private int mTouchSlop;
|
||||
private PointF mInputDownPoint;
|
||||
private boolean mIsDragEvent;
|
||||
private int mDragPointerId;
|
||||
public DragDetector(int touchSlop) {
|
||||
mTouchSlop = touchSlop;
|
||||
mInputDownPoint = new PointF();
|
||||
mIsDragEvent = false;
|
||||
mDragPointerId = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if {@link MotionEvent} is part of a drag event.
|
||||
* @return {@code true} if this is a drag event, {@code false} if not
|
||||
*/
|
||||
public boolean detectDragEvent(MotionEvent ev) {
|
||||
switch (ev.getAction()) {
|
||||
case ACTION_DOWN: {
|
||||
mDragPointerId = ev.getPointerId(0);
|
||||
float rawX = ev.getRawX(0);
|
||||
float rawY = ev.getRawY(0);
|
||||
mInputDownPoint.set(rawX, rawY);
|
||||
return false;
|
||||
}
|
||||
case ACTION_MOVE: {
|
||||
if (!mIsDragEvent) {
|
||||
int dragPointerIndex = ev.findPointerIndex(mDragPointerId);
|
||||
float dx = ev.getRawX(dragPointerIndex) - mInputDownPoint.x;
|
||||
float dy = ev.getRawY(dragPointerIndex) - mInputDownPoint.y;
|
||||
if (Math.hypot(dx, dy) > mTouchSlop) {
|
||||
mIsDragEvent = true;
|
||||
}
|
||||
}
|
||||
return mIsDragEvent;
|
||||
}
|
||||
case ACTION_UP: {
|
||||
boolean result = mIsDragEvent;
|
||||
mIsDragEvent = false;
|
||||
mInputDownPoint.set(0, 0);
|
||||
mDragPointerId = -1;
|
||||
return result;
|
||||
}
|
||||
case ACTION_CANCEL: {
|
||||
mIsDragEvent = false;
|
||||
mInputDownPoint.set(0, 0);
|
||||
mDragPointerId = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return mIsDragEvent;
|
||||
}
|
||||
|
||||
public void setTouchSlop(int touchSlop) {
|
||||
mTouchSlop = touchSlop;
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERL
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.hardware.input.InputManager;
|
||||
@@ -38,6 +37,7 @@ import android.view.InputEventReceiver;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.PointerIcon;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.WindowManagerGlobal;
|
||||
|
||||
import com.android.internal.view.BaseIWindow;
|
||||
@@ -76,7 +76,7 @@ class DragResizeInputListener implements AutoCloseable {
|
||||
private Rect mRightBottomCornerBounds;
|
||||
|
||||
private int mDragPointerId = -1;
|
||||
private int mTouchSlop;
|
||||
private DragDetector mDragDetector;
|
||||
|
||||
DragResizeInputListener(
|
||||
Context context,
|
||||
@@ -115,6 +115,7 @@ class DragResizeInputListener implements AutoCloseable {
|
||||
mInputEventReceiver = new TaskResizeInputEventReceiver(
|
||||
mInputChannel, mHandler, mChoreographer);
|
||||
mCallback = callback;
|
||||
mDragDetector = new DragDetector(ViewConfiguration.get(context).getScaledTouchSlop());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,7 +147,7 @@ class DragResizeInputListener implements AutoCloseable {
|
||||
mHeight = height;
|
||||
mResizeHandleThickness = resizeHandleThickness;
|
||||
mCornerSize = cornerSize;
|
||||
mTouchSlop = touchSlop;
|
||||
mDragDetector.setTouchSlop(touchSlop);
|
||||
|
||||
Region touchRegion = new Region();
|
||||
final Rect topInputBounds = new Rect(0, 0, mWidth, mResizeHandleThickness);
|
||||
@@ -228,7 +229,6 @@ class DragResizeInputListener implements AutoCloseable {
|
||||
private boolean mConsumeBatchEventScheduled;
|
||||
private boolean mShouldHandleEvents;
|
||||
private boolean mDragging;
|
||||
private final PointF mActionDownPoint = new PointF();
|
||||
|
||||
private TaskResizeInputEventReceiver(
|
||||
InputChannel inputChannel, Handler handler, Choreographer choreographer) {
|
||||
@@ -276,7 +276,9 @@ class DragResizeInputListener implements AutoCloseable {
|
||||
// Check if this is a touch event vs mouse event.
|
||||
// Touch events are tracked in four corners. Other events are tracked in resize edges.
|
||||
boolean isTouch = (e.getSource() & SOURCE_TOUCHSCREEN) == SOURCE_TOUCHSCREEN;
|
||||
|
||||
if (isTouch) {
|
||||
mDragging = mDragDetector.detectDragEvent(e);
|
||||
}
|
||||
switch (e.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
float x = e.getX(0);
|
||||
@@ -290,7 +292,6 @@ class DragResizeInputListener implements AutoCloseable {
|
||||
mDragPointerId = e.getPointerId(0);
|
||||
float rawX = e.getRawX(0);
|
||||
float rawY = e.getRawY(0);
|
||||
mActionDownPoint.set(rawX, rawY);
|
||||
int ctrlType = calculateCtrlType(isTouch, x, y);
|
||||
mCallback.onDragResizeStart(ctrlType, rawX, rawY);
|
||||
result = true;
|
||||
@@ -304,14 +305,7 @@ class DragResizeInputListener implements AutoCloseable {
|
||||
int dragPointerIndex = e.findPointerIndex(mDragPointerId);
|
||||
float rawX = e.getRawX(dragPointerIndex);
|
||||
float rawY = e.getRawY(dragPointerIndex);
|
||||
if (isTouch) {
|
||||
// Check for touch slop for touch events
|
||||
float dx = rawX - mActionDownPoint.x;
|
||||
float dy = rawY - mActionDownPoint.y;
|
||||
if (!mDragging && Math.hypot(dx, dy) > mTouchSlop) {
|
||||
mDragging = true;
|
||||
}
|
||||
} else {
|
||||
if (!isTouch) {
|
||||
// For all other types allow immediate dragging.
|
||||
mDragging = true;
|
||||
}
|
||||
@@ -330,7 +324,6 @@ class DragResizeInputListener implements AutoCloseable {
|
||||
}
|
||||
mDragging = false;
|
||||
mShouldHandleEvents = false;
|
||||
mActionDownPoint.set(0, 0);
|
||||
mDragPointerId = -1;
|
||||
result = true;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user