From 52d5f9cc259325ae26dab0063f3afccd7d068abf Mon Sep 17 00:00:00 2001 From: Maryam Dehaini Date: Mon, 2 Oct 2023 11:23:24 -0700 Subject: Use onTouchListener to listen for long press on maximize window button Currently, an onLongPressListener is being used in order to check if a user long presses the maximize menu button. The issue with this approach is that we cannot drag the window from the maximize button. So, if a window is small or is positioned so that only the right edge of the caption is visible, it would be very hard for the user to drag the task without accidentally maximizing or opening the maximize window. In this approach, we use the onTouchListener instead to check if there is a long press. This way, we can allow the user to drag the task around if they begin a drag from the maximize menu button and redirect the touch to the onClickListener or onTouchListener depending on how long they are holding the button if the task is not dragged. Bug: 298267890 Test: Drag a task using maximize menu button Change-Id: I96eaba90b137f65cf201654433a0d12ed6fe69bb --- .../DesktopModeWindowDecorViewModel.java | 41 +++++++++++++++------- .../windowdecor/DesktopModeWindowDecoration.java | 22 ++++++++++++ .../android/wm/shell/windowdecor/MaximizeMenu.kt | 25 +++++++++++++ ...topModeAppControlsWindowDecorationViewHolder.kt | 1 + 4 files changed, 77 insertions(+), 12 deletions(-) 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 ca91d580b4ac..716f8b81f158 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.MotionEvent; 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 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { 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 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private final GestureDetector mGestureDetector; private boolean mIsDragging; + private boolean mHasLongClicked; private boolean mShouldClick; private int mDragPointerId = -1; @@ -394,11 +396,9 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { 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 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { 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 class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { 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 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { if (decoration.isMaximizeMenuActive()) { decoration.closeMaximizeMenu(); } else { - decoration.closeHandleMenu(); decoration.createMaximizeMenu(); } return true; @@ -519,11 +533,13 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { 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 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { 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 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { // 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 class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { 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 a976584e9811..eba1a36ef29f 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 @@ public class DesktopModeWindowDecoration extends WindowDecoration= 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 d64312a1c0c8..b739ad3793e4 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 @@ internal class DesktopModeAppControlsWindowDecorationViewHolder( openMenuButton.setOnTouchListener(onCaptionTouchListener) closeWindowButton.setOnClickListener(onCaptionButtonClickListener) maximizeWindowButton.setOnClickListener(onCaptionButtonClickListener) + maximizeWindowButton.setOnTouchListener(onCaptionTouchListener) maximizeWindowButton.onLongClickListener = onLongClickListener closeWindowButton.setOnTouchListener(onCaptionTouchListener) appNameTextView.text = appName -- cgit v1.2.3-59-g8ed1b