Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +29 −12 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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; Loading Loading @@ -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); } Loading @@ -483,7 +498,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { if (decoration.isMaximizeMenuActive()) { decoration.closeMaximizeMenu(); } else { decoration.closeHandleMenu(); decoration.createMaximizeMenu(); } return true; Loading Loading @@ -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); } Loading @@ -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; Loading Loading @@ -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) { final int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { if (relevantDecor == null) { // 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 (!mTransitionDragActive) { relevantDecor.closeHandleMenuIfNeeded(ev); relevantDecor.closeMaximizeMenuIfNeeded(ev); } } } Loading Loading @@ -1024,7 +1042,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { public void onDragStart(int taskId) { final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId); decoration.closeHandleMenu(); decoration.closeMaximizeMenu(); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +22 −0 Original line number Diff line number Diff line Loading @@ -521,6 +521,20 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin } } /** * 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; } Loading Loading @@ -559,6 +573,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin return checkEventInCaptionView(ev, R.id.caption_handle); } /** * 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 Loading @@ -574,6 +595,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin clickIfPointInView(new PointF(ev.getX(), ev.getY()), handle); } else { mHandleMenu.checkClickEvent(ev); closeHandleMenuIfNeeded(ev); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt +25 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.view.LayoutInflater 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 Loading Loading @@ -151,4 +152,28 @@ class MaximizeMenu( 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 } } libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +29 −12 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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; Loading Loading @@ -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); } Loading @@ -483,7 +498,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { if (decoration.isMaximizeMenuActive()) { decoration.closeMaximizeMenu(); } else { decoration.closeHandleMenu(); decoration.createMaximizeMenu(); } return true; Loading Loading @@ -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); } Loading @@ -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; Loading Loading @@ -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) { final int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { if (relevantDecor == null) { // 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 (!mTransitionDragActive) { relevantDecor.closeHandleMenuIfNeeded(ev); relevantDecor.closeMaximizeMenuIfNeeded(ev); } } } Loading Loading @@ -1024,7 +1042,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { public void onDragStart(int taskId) { final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId); decoration.closeHandleMenu(); decoration.closeMaximizeMenu(); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +22 −0 Original line number Diff line number Diff line Loading @@ -521,6 +521,20 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin } } /** * 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; } Loading Loading @@ -559,6 +573,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin return checkEventInCaptionView(ev, R.id.caption_handle); } /** * 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 Loading @@ -574,6 +595,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin clickIfPointInView(new PointF(ev.getX(), ev.getY()), handle); } else { mHandleMenu.checkClickEvent(ev); closeHandleMenuIfNeeded(ev); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt +25 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.view.LayoutInflater 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 Loading Loading @@ -151,4 +152,28 @@ class MaximizeMenu( 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 } }
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading