From ad9821d8ed314d8acd02da05c9ebbc25f6d8d577 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 10 Jan 2025 17:39:26 +0000 Subject: [PATCH] Fix how touch deadzone work in RecentsView - The new design have 3 deadzones Rect: - TaskView (for desktop tasks, focused task or all tasks in small screen) - Top row - Bottom row - The shorter row between top/bottom row is expanded to cover space between the 2 rows - The large tile row is expanded to cover space between large and small tiles - Rect illustration: http://screen/8vHAqrYdUB5Rqbc.png Fix: 323143607 Fix: 323143607 Test: Tap empty space between tasks, Oveview should not dismiss Test: Tap empty space on shorter rows in grid, Overview should dismiss Flag: EXEMPT bugfix Change-Id: Id59c1238df33dfbe67a696d0836ba393321b38ac --- .../android/quickstep/views/RecentsView.java | 26 +++---- .../quickstep/views/RecentsViewUtils.kt | 76 +++++++++++++++++++ 2 files changed, 88 insertions(+), 14 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 770a6597f0..d8f6381ad6 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -551,6 +551,8 @@ public abstract class RecentsView< private final ClearAllButton mClearAllButton; private final Rect mClearAllButtonDeadZoneRect = new Rect(); private final Rect mTaskViewDeadZoneRect = new Rect(); + private final Rect mTopRowDeadZoneRect = new Rect(); + private final Rect mBottomRowDeadZoneRect = new Rect(); /** * Reflects if Recents is currently in the middle of a gesture, and if so, which tasks are * running. If a gesture is not in progress, this will be null. @@ -1705,8 +1707,11 @@ public abstract class RecentsView< mClearAllButton.getAlpha() == 1 && mClearAllButtonDeadZoneRect.contains(x, y); final boolean cameFromNavBar = (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0; + int adjustedX = x + getScrollX(); if (!clearAllButtonDeadZoneConsumed && !cameFromNavBar - && !mTaskViewDeadZoneRect.contains(x + getScrollX(), y)) { + && !mTaskViewDeadZoneRect.contains(adjustedX, y) + && !mTopRowDeadZoneRect.contains(adjustedX, y) + && !mBottomRowDeadZoneRect.contains(adjustedX, y)) { mTouchDownToStartHome = true; } } @@ -2084,7 +2089,7 @@ public abstract class RecentsView< /** Returns true if there are at least one TaskView has been added to the RecentsView. */ public boolean hasTaskViews() { - return CollectionsKt.any(getTaskViews()); + return mUtils.hasTaskViews(); } public int getTaskViewCount() { @@ -2699,7 +2704,7 @@ public abstract class RecentsView< } @Nullable - private TaskView getTaskViewFromTaskViewId(int taskViewId) { + TaskView getTaskViewFromTaskViewId(int taskViewId) { if (taskViewId == -1) { return null; } @@ -4354,7 +4359,7 @@ public abstract class RecentsView< /** * Returns all the tasks in the top row, without the focused task */ - private IntArray getTopRowIdArray() { + IntArray getTopRowIdArray() { if (mTopRowIdSet.isEmpty()) { return new IntArray(0); } @@ -4371,7 +4376,7 @@ public abstract class RecentsView< /** * Returns all the tasks in the bottom row, without the focused task */ - private IntArray getBottomRowIdArray() { + IntArray getBottomRowIdArray() { int bottomRowIdArraySize = getBottomRowTaskCountForTablet(); if (bottomRowIdArraySize <= 0) { return new IntArray(0); @@ -5508,15 +5513,8 @@ public abstract class RecentsView< mClearAllButtonDeadZoneRect.inset(-getPaddingRight() / 2, -verticalMargin); } - // Get the deadzone rect between the task views - mTaskViewDeadZoneRect.setEmpty(); - if (hasTaskViews()) { - final View firstTaskView = getFirstTaskView(); - mUtils.getLastTaskView().getHitRect(mTaskViewDeadZoneRect); - mTaskViewDeadZoneRect.union(firstTaskView.getLeft(), firstTaskView.getTop(), - firstTaskView.getRight(), - firstTaskView.getBottom()); - } + mUtils.updateTaskViewDeadZoneRect(mTaskViewDeadZoneRect, mTopRowDeadZoneRect, + mBottomRowDeadZoneRect); } private void updateEmptyStateUi(boolean sizeChanged) { diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt index 3ac3349a6e..dcb954a811 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt +++ b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt @@ -16,9 +16,11 @@ package com.android.quickstep.views +import android.graphics.Rect import android.view.View import androidx.core.view.children import com.android.launcher3.Flags.enableLargeDesktopWindowingTile +import com.android.launcher3.util.IntArray import com.android.quickstep.util.GroupTask import com.android.quickstep.views.RecentsView.RUNNING_TASK_ATTACH_ALPHA import com.android.systemui.shared.recents.model.ThumbnailData @@ -169,4 +171,78 @@ class RecentsViewUtils(private val recentsView: RecentsView<*, *>) { FULL_SCREEN, DESKTOP, } + + /** Returns true if there are at least one TaskView has been added to the RecentsView. */ + fun hasTaskViews() = taskViews.any() + + private fun getRowRect(firstView: View?, lastView: View?, outRowRect: Rect) { + outRowRect.setEmpty() + firstView?.let { + it.getHitRect(TEMP_RECT) + outRowRect.union(TEMP_RECT) + } + lastView?.let { + it.getHitRect(TEMP_RECT) + outRowRect.union(TEMP_RECT) + } + } + + private fun getRowRect(rowTaskViewIds: IntArray, outRowRect: Rect) { + if (rowTaskViewIds.isEmpty) { + outRowRect.setEmpty() + return + } + getRowRect( + recentsView.getTaskViewFromTaskViewId(rowTaskViewIds.get(0)), + recentsView.getTaskViewFromTaskViewId(rowTaskViewIds.get(rowTaskViewIds.size() - 1)), + outRowRect, + ) + } + + fun updateTaskViewDeadZoneRect( + outTaskViewRowRect: Rect, + outTopRowRect: Rect, + outBottomRowRect: Rect, + ) { + if (!(recentsView.mContainer as RecentsViewContainer).deviceProfile.isTablet) { + getRowRect(getFirstTaskView(), getLastTaskView(), outTaskViewRowRect) + return + } + getRowRect(getFirstLargeTaskView(), getLastLargeTaskView(), outTaskViewRowRect) + getRowRect(recentsView.getTopRowIdArray(), outTopRowRect) + getRowRect(recentsView.getBottomRowIdArray(), outBottomRowRect) + + // Expand large tile Rect to include space between top/bottom row. + val nonEmptyRowRect = + when { + !outTopRowRect.isEmpty -> outTopRowRect + !outBottomRowRect.isEmpty -> outBottomRowRect + else -> return + } + if (recentsView.isRtl) { + if (outTaskViewRowRect.left > nonEmptyRowRect.right) { + outTaskViewRowRect.left = nonEmptyRowRect.right + } + } else { + if (outTaskViewRowRect.right < nonEmptyRowRect.left) { + outTaskViewRowRect.right = nonEmptyRowRect.left + } + } + + // Expand the shorter row Rect to include the space between the 2 rows. + if (outTopRowRect.isEmpty || outBottomRowRect.isEmpty) return + if (outTopRowRect.width() <= outBottomRowRect.width()) { + if (outTopRowRect.bottom < outBottomRowRect.top) { + outTopRowRect.bottom = outBottomRowRect.top + } + } else { + if (outBottomRowRect.top > outTopRowRect.bottom) { + outBottomRowRect.top = outTopRowRect.bottom + } + } + } + + companion object { + val TEMP_RECT = Rect() + } }