From 359ac14d132a0008f250d03fbc58d4d299407a00 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Thu, 23 Feb 2023 12:57:03 +0000 Subject: [PATCH] Fix various animation issues when total width of grid tasks < screen width Bug fixes: - Unusual long scroll when only focus task left after split select - Animation jump when tasks cannot fit screen width after dismiss or split select To fix the above issue, generified calculations when total grid task width < screen width: - Removed some special case handling when only focus task left (getSnapToFocusedTaskScrollDiff), and instead replace with generic logic that calculation that extra scroll position (shortTotalCompensation) needed when long row width is smaller than the grid size - Fixed snapped task grid translation calculation to account for shortTotalCompensation - Last task scroll calculation should account for shortTotalCompensation too - Calculate the expected shortTotalCompensation after dismiss, and use that to adjust the close gap between clearAll distance splitScrollOffset that we applied during split screen does not work well when shortTotalCompensation != 0. splitScrollOffset is not a good solution to handle split placeholder, as it allow tasks to scroll to weird position. I removed splitScrollOffset completely, and only apply split translation when split placeholder covers the tasks: - Removed splitScrollOffset on TaskView/ClearAll, so scroll position of TaskView will not change while in split to splify things. - When split placehodler will cover task's natural position (taskSize) in overview grid, apply split translation on all tasks similar to handheld - Removed isSplitPlaceholderFirstInGrid/isSplitPlaceholderLastInGrid adjustments Bug: 257952455 Test: Enter overview from home Test: Enter overview from app, with variations that quick switch and enter Test: Dismiss task from different position Test: Split select task from different position Test: Repeat with/without GRID_ONLY_OVERVIEW flag Test: Repeat with handheld Change-Id: I7689b5384845f03491041b6d910835c9ac4fab08 --- .../RecentsViewStateController.java | 5 +- .../FallbackRecentsStateController.java | 10 +- .../quickstep/views/ClearAllButton.java | 6 - .../android/quickstep/views/RecentsView.java | 341 ++++++++---------- .../com/android/quickstep/views/TaskView.java | 12 +- 5 files changed, 159 insertions(+), 215 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index e8e83288cd..07fcf48a07 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -121,8 +121,7 @@ public final class RecentsViewStateController extends private void handleSplitSelectionState(@NonNull LauncherState toState, @NonNull PendingAnimation builder, boolean animate) { if (toState != OVERVIEW_SPLIT_SELECT) { - // Not going to split, nothing to do but ensure taskviews are at correct offset - mRecentsView.resetSplitPrimaryScrollOffset(); + // Not going to split return; } @@ -153,8 +152,6 @@ public final class RecentsViewStateController extends as.start(); as.end(); } - - mRecentsView.applySplitPrimaryScrollOffset(); } private void setAlphas(PropertySetter propertySetter, StateAnimationConfig config, diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java index 062e50e30b..11b1ab8ec9 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java @@ -130,15 +130,9 @@ public class FallbackRecentsStateController implements StateHandler 0) { TaskView taskView = requireTaskViewAt(0); @@ -1732,12 +1719,12 @@ public abstract class RecentsView 0 && mTopRowIdSet.size() >= (taskCount - 1) / 2f; - // Pick the next focused task from the preferred row. - for (int i = 0; i < taskCount; i++) { - TaskView taskView = requireTaskViewAt(i); - if (taskView == dismissedTaskView) { - continue; + if (isFocusedTaskDismissed) { + if (isSplitSelectionActive()) { + isStagingFocusedTask = true; + } else { + nextFocusedTaskFromTop = + mTopRowIdSet.size() > 0 && mTopRowIdSet.size() >= (taskCount - 1) / 2f; + // Pick the next focused task from the preferred row. + for (int i = 0; i < taskCount; i++) { + TaskView taskView = requireTaskViewAt(i); + if (taskView == dismissedTaskView) { + continue; + } + boolean isTopRow = mTopRowIdSet.contains(taskView.getTaskViewId()); + if ((nextFocusedTaskFromTop && isTopRow + || (!nextFocusedTaskFromTop && !isTopRow))) { + nextFocusedTaskView = taskView; + break; + } } - boolean isTopRow = mTopRowIdSet.contains(taskView.getTaskViewId()); - if ((nextFocusedTaskFromTop && isTopRow - || (!nextFocusedTaskFromTop && !isTopRow))) { - nextFocusedTaskView = taskView; - break; + if (nextFocusedTaskView != null) { + nextFocusedTaskWidth = + nextFocusedTaskView.getLayoutParams().width + mPageSpacing; } } - if (nextFocusedTaskView != null) { - nextFocusedTaskWidth = - nextFocusedTaskView.getLayoutParams().width + mPageSpacing; - } } } else { getPageScrolls(oldScroll, false, SIMPLE_SCROLL_LOGIC); @@ -3245,8 +3251,6 @@ public abstract class RecentsView topGridRowSize; boolean dismissedTaskFromTop = mTopRowIdSet.contains(dismissedTaskViewId); boolean dismissedTaskFromBottom = !dismissedTaskFromTop && !isFocusedTaskDismissed; + if (dismissedTaskFromTop || (isFocusedTaskDismissed && nextFocusedTaskFromTop)) { + topGridRowSize--; + } + if (dismissedTaskFromBottom || (isFocusedTaskDismissed && !nextFocusedTaskFromTop)) { + bottomGridRowSize--; + } + int longRowWidth = Math.max(topGridRowSize, bottomGridRowSize) + * (mLastComputedGridTaskSize.width() + mPageSpacing) + + (isStagingFocusedTask ? 0 : mLastComputedTaskSize.width() + mPageSpacing); + float gapWidth = 0; if ((topRowLonger && dismissedTaskFromTop) || (bottomRowLonger && dismissedTaskFromBottom)) { gapWidth = dismissedTaskWidth; - } else if ((topRowLonger && nextFocusedTaskFromTop) - || (bottomRowLonger && !nextFocusedTaskFromTop)) { + } else if (nextFocusedTaskView != null + && ((topRowLonger && nextFocusedTaskFromTop) + || (bottomRowLonger && !nextFocusedTaskFromTop))) { gapWidth = nextFocusedTaskWidth; } if (gapWidth > 0) { - if (taskCount > 2) { - // Compensate the removed gap. - longGridRowWidthDiff += mIsRtl ? -gapWidth : gapWidth; - if (isClearAllHidden) { - // If ClearAllButton isn't fully shown, snap to the last task. - snapToLastTask = true; + if (mClearAllShortTotalWidthTranslation == 0) { + // Compensate the removed gap if we don't already have shortTotalCompensation, + // and adjust accordingly to the new shortTotalCompensation after dismiss. + int newClearAllShortTotalWidthTranslation = 0; + if (longRowWidth < mLastComputedGridSize.width()) { + DeviceProfile deviceProfile = mActivity.getDeviceProfile(); + newClearAllShortTotalWidthTranslation = + (mIsRtl + ? mLastComputedTaskSize.right + : deviceProfile.widthPx - mLastComputedTaskSize.left) + - longRowWidth - deviceProfile.overviewGridSideMargin; } - } else { - // If only focused task will be left, snap to focused task instead. - longGridRowWidthDiff += getSnapToFocusedTaskScrollDiff(isClearAllHidden); + float gapCompensation = gapWidth - newClearAllShortTotalWidthTranslation; + longGridRowWidthDiff += mIsRtl ? -gapCompensation : gapCompensation; + } + if (isClearAllHidden) { + // If ClearAllButton isn't fully shown, snap to the last task. + snapToLastTask = true; } } - if (mClearAllButton.getAlpha() != 0f && isLandscapeSplit) { - // ClearAllButton will not be available in split select, snap to last task instead. - snapToLastTask = true; + if (isLandscapeSplit && !isStagingFocusedTask) { + // LastTask's scroll is the minimum scroll in split select, if current scroll is + // beyond that, we'll need to snap to last task instead. + TaskView lastTask = getLastGridTaskView(); + if (lastTask != null) { + int primaryScroll = mOrientationHandler.getPrimaryScroll(this); + int lastTaskScroll = getScrollForPage(indexOfChild(lastTask)); + if ((mIsRtl && primaryScroll < lastTaskScroll) + || (!mIsRtl && primaryScroll > lastTaskScroll)) { + snapToLastTask = true; + } + } } if (snapToLastTask) { longGridRowWidthDiff += getSnapToLastTaskScrollDiff(); - if (isSplitPlaceholderLastInGrid) { - // Shift all the tasks to make space for split placeholder. - longGridRowWidthDiff += mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize; - } } else if (isLandscapeSplit && currentPageSnapsToEndOfGrid) { // Use last task as reference point for scroll diff and snapping calculation as it's // the only invariant point in landscape split screen. @@ -3451,8 +3479,6 @@ public abstract class RecentsView lastTaskScroll)) { pageScroll = lastTaskScroll; @@ -5274,8 +5242,7 @@ public abstract class RecentsView= 0 && (mIsRtl diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index fb856058db..b9aaef63ca 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -375,7 +375,6 @@ public class TaskView extends FrameLayout implements Reusable { // Used when in SplitScreenSelectState private float mSplitSelectTranslationY; private float mSplitSelectTranslationX; - private float mSplitSelectScrollOffsetPrimary; @Nullable private ObjectAnimator mIconAndDimAnimator; @@ -1297,10 +1296,6 @@ public class TaskView extends FrameLayout implements Reusable { applyTranslationY(); } - public void setSplitScrollOffsetPrimary(float splitSelectScrollOffsetPrimary) { - mSplitSelectScrollOffsetPrimary = splitSelectScrollOffsetPrimary; - } - private void setDismissTranslationX(float x) { mDismissTranslationX = x; applyTranslationX(); @@ -1364,19 +1359,18 @@ public class TaskView extends FrameLayout implements Reusable { applyTranslationX(); } - public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) { + public float getScrollAdjustment(boolean gridEnabled) { float scrollAdjustment = 0; if (gridEnabled) { scrollAdjustment += mGridTranslationX; } else { scrollAdjustment += getPrimaryNonGridTranslationProperty().get(this); } - scrollAdjustment += mSplitSelectScrollOffsetPrimary; return scrollAdjustment; } - public float getOffsetAdjustment(boolean fullscreenEnabled, boolean gridEnabled) { - return getScrollAdjustment(fullscreenEnabled, gridEnabled); + public float getOffsetAdjustment(boolean gridEnabled) { + return getScrollAdjustment(gridEnabled); } public float getSizeAdjustment(boolean fullscreenEnabled) {