Merge "Use onTouchListener to listen for long press on maximize window button" into main
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index ca91d58..716f8b8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -57,6 +57,7 @@
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.window.TransitionInfo;
import android.window.WindowContainerToken;
@@ -362,7 +363,7 @@
private class DesktopModeTouchEventListener extends GestureDetector.SimpleOnGestureListener
implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener,
- DragDetector.MotionEventHandler{
+ DragDetector.MotionEventHandler {
private final int mTaskId;
private final WindowContainerToken mTaskToken;
@@ -371,6 +372,7 @@
private final GestureDetector mGestureDetector;
private boolean mIsDragging;
+ private boolean mHasLongClicked;
private boolean mShouldClick;
private int mDragPointerId = -1;
@@ -394,11 +396,9 @@
RunningTaskInfo remainingTask = getOtherSplitTask(mTaskId);
mSplitScreenController.moveTaskToFullscreen(remainingTask.taskId);
}
- decoration.closeMaximizeMenu();
} else if (id == R.id.back_button) {
mTaskOperations.injectBackKey();
} else if (id == R.id.caption_handle || id == R.id.open_menu_button) {
- decoration.closeMaximizeMenu();
if (!decoration.isHandleMenuActive()) {
moveTaskToFront(mTaskOrganizer.getRunningTaskInfo(mTaskId));
decoration.createHandleMenu();
@@ -433,7 +433,6 @@
mDesktopTasksController.ifPresent(c -> c.moveToNextDisplay(mTaskId));
}
} else if (id == R.id.maximize_window) {
- moveTaskToFront(decoration.mTaskInfo);
if (decoration.isMaximizeMenuActive()) {
decoration.closeMaximizeMenu();
return;
@@ -467,10 +466,26 @@
public boolean onTouch(View v, MotionEvent e) {
final int id = v.getId();
if (id != R.id.caption_handle && id != R.id.desktop_mode_caption
- && id != R.id.open_menu_button && id != R.id.close_window) {
+ && id != R.id.open_menu_button && id != R.id.close_window
+ && id != R.id.maximize_window) {
return false;
}
moveTaskToFront(mTaskOrganizer.getRunningTaskInfo(mTaskId));
+
+ if (!mHasLongClicked) {
+ final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
+ decoration.closeMaximizeMenu();
+ }
+
+ final long eventDuration = e.getEventTime() - e.getDownTime();
+ final boolean shouldLongClick = id == R.id.maximize_window && !mIsDragging
+ && !mHasLongClicked && eventDuration >= ViewConfiguration.getLongPressTimeout();
+ if (shouldLongClick) {
+ v.performLongClick();
+ mHasLongClicked = true;
+ return true;
+ }
+
return mDragDetector.onMotionEvent(v, e);
}
@@ -483,7 +498,6 @@
if (decoration.isMaximizeMenuActive()) {
decoration.closeMaximizeMenu();
} else {
- decoration.closeHandleMenu();
decoration.createMaximizeMenu();
}
return true;
@@ -519,11 +533,13 @@
e.getRawY(0));
mIsDragging = false;
mShouldClick = true;
+ mHasLongClicked = false;
return true;
}
case MotionEvent.ACTION_MOVE: {
final DesktopModeWindowDecoration decoration =
mWindowDecorByTaskId.get(mTaskId);
+ decoration.closeMaximizeMenu();
if (e.findPointerIndex(mDragPointerId) == -1) {
mDragPointerId = e.getPointerId(0);
}
@@ -542,7 +558,7 @@
case MotionEvent.ACTION_CANCEL: {
final boolean wasDragging = mIsDragging;
if (!wasDragging) {
- if (mShouldClick && v != null) {
+ if (mShouldClick && v != null && !mHasLongClicked) {
v.performClick();
mShouldClick = false;
return true;
@@ -685,14 +701,16 @@
// If an UP/CANCEL action is received outside of caption bounds, turn off handle menu
private void handleEventOutsideFocusedCaption(MotionEvent ev,
DesktopModeWindowDecoration relevantDecor) {
+ // Returns if event occurs within caption
+ if (relevantDecor == null || relevantDecor.checkTouchEventInCaption(ev)) {
+ return;
+ }
+
final int action = ev.getActionMasked();
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
- if (relevantDecor == null) {
- return;
- }
-
if (!mTransitionDragActive) {
relevantDecor.closeHandleMenuIfNeeded(ev);
+ relevantDecor.closeMaximizeMenuIfNeeded(ev);
}
}
}
@@ -1024,7 +1042,6 @@
public void onDragStart(int taskId) {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
decoration.closeHandleMenu();
- decoration.closeMaximizeMenu();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index a976584..eba1a36 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -521,6 +521,20 @@
}
}
+ /**
+ * Close an open maximize menu if input is outside of menu coordinates
+ *
+ * @param ev the tapped point to compare against
+ */
+ void closeMaximizeMenuIfNeeded(MotionEvent ev) {
+ if (!isMaximizeMenuActive()) return;
+
+ final PointF inputPoint = offsetCaptionLocation(ev);
+ if (!mMaximizeMenu.isValidMenuInput(inputPoint)) {
+ closeMaximizeMenu();
+ }
+ }
+
boolean isFocused() {
return mTaskInfo.isFocused;
}
@@ -560,6 +574,13 @@
}
/**
+ * Returns true if motion event is within the caption's root view's bounds.
+ */
+ boolean checkTouchEventInCaption(MotionEvent ev) {
+ return checkEventInCaptionView(ev, getCaptionViewId());
+ }
+
+ /**
* Check a passed MotionEvent if a click has occurred on any button on this caption
* Note this should only be called when a regular onClick is not possible
* (i.e. the button was clicked through status bar layer)
@@ -574,6 +595,7 @@
clickIfPointInView(new PointF(ev.getX(), ev.getY()), handle);
} else {
mHandleMenu.checkClickEvent(ev);
+ closeHandleMenuIfNeeded(ev);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
index 050d1e9..921708f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
@@ -25,6 +25,7 @@
import android.view.SurfaceControl
import android.view.SurfaceControl.Transaction
import android.view.SurfaceControlViewHost
+import android.view.View
import android.view.View.OnClickListener
import android.view.WindowManager
import android.view.WindowlessWindowManager
@@ -151,4 +152,28 @@
R.id.maximize_menu_snap_left_button
).setOnClickListener(onClickListener)
}
+
+ /**
+ * A valid menu input is one of the following:
+ * An input that happens in the menu views.
+ * Any input before the views have been laid out.
+ *
+ * @param inputPoint the input to compare against.
+ */
+ fun isValidMenuInput(inputPoint: PointF): Boolean {
+ val menuView = maximizeMenu?.mWindowViewHost?.view ?: return true
+ return !viewsLaidOut() || pointInView(menuView, inputPoint.x - menuPosition.x,
+ inputPoint.y - menuPosition.y)
+ }
+
+ private fun pointInView(v: View, x: Float, y: Float): Boolean {
+ return v.left <= x && v.right >= x && v.top <= y && v.bottom >= y
+ }
+
+ /**
+ * Check if the views for maximize menu can be seen.
+ */
+ private fun viewsLaidOut(): Boolean {
+ return maximizeMenu?.mWindowViewHost?.view?.isLaidOut ?: false
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
index d64312a..b739ad3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
@@ -41,6 +41,7 @@
openMenuButton.setOnTouchListener(onCaptionTouchListener)
closeWindowButton.setOnClickListener(onCaptionButtonClickListener)
maximizeWindowButton.setOnClickListener(onCaptionButtonClickListener)
+ maximizeWindowButton.setOnTouchListener(onCaptionTouchListener)
maximizeWindowButton.onLongClickListener = onLongClickListener
closeWindowButton.setOnTouchListener(onCaptionTouchListener)
appNameTextView.text = appName