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
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index e8e8328..07fcf48 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -121,8 +121,7 @@
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 @@
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 062e50e..11b1ab8 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
@@ -130,15 +130,9 @@
mRecentsView.getPagedOrientationHandler().getSplitSelectTaskOffset(
TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
mActivity.getDeviceProfile());
+ setter.setFloat(mRecentsView, taskViewsFloat.first, isSplitSelectionState(state)
+ ? mRecentsView.getSplitSelectTranslation() : 0, LINEAR);
setter.setFloat(mRecentsView, taskViewsFloat.second, 0, LINEAR);
- if (isSplitSelectionState(state)) {
- mRecentsView.applySplitPrimaryScrollOffset();
- setter.setFloat(mRecentsView, taskViewsFloat.first,
- mRecentsView.getSplitSelectTranslation(), LINEAR);
- } else {
- mRecentsView.resetSplitPrimaryScrollOffset();
- setter.setFloat(mRecentsView, taskViewsFloat.first, 0, LINEAR);
- }
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index d098ffc..6813857 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -67,7 +67,6 @@
private float mGridTranslationPrimary;
private float mGridScrollOffset;
private float mScrollOffsetPrimary;
- private float mSplitSelectScrollOffsetPrimary;
private int mSidePadding;
@@ -176,10 +175,6 @@
mScrollOffsetPrimary = scrollOffsetPrimary;
}
- public void setSplitSelectScrollOffsetPrimary(float splitSelectScrollOffsetPrimary) {
- mSplitSelectScrollOffsetPrimary = splitSelectScrollOffsetPrimary;
- }
-
public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) {
float scrollAdjustment = 0;
if (fullscreenEnabled) {
@@ -189,7 +184,6 @@
scrollAdjustment += mGridTranslationPrimary + mGridScrollOffset;
}
scrollAdjustment += mScrollOffsetPrimary;
- scrollAdjustment += mSplitSelectScrollOffsetPrimary;
return scrollAdjustment;
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index e529b04..6ec0a4d 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -53,8 +53,6 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA;
@@ -79,7 +77,6 @@
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.WindowConfiguration;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.LocusId;
@@ -517,6 +514,7 @@
private float mTaskThumbnailSplashAlpha = 0;
private boolean mShowAsGridLastOnLayout = false;
private final IntSet mTopRowIdSet = new IntSet();
+ private int mClearAllShortTotalWidthTranslation = 0;
// The GestureEndTarget that is still in progress.
@Nullable
@@ -1233,21 +1231,9 @@
return clearAllScroll + (mIsRtl ? distance : -distance);
}
- private int getSnapToFocusedTaskScrollDiff(boolean isClearAllHidden) {
- int screenStart = mOrientationHandler.getPrimaryScroll(this);
- int targetScroll = getScrollForPage(indexOfChild(getFocusedTaskView()));
- if (!isClearAllHidden) {
- int clearAllWidth = mOrientationHandler.getPrimarySize(mClearAllButton);
- int taskGridHorizontalDiff = mLastComputedTaskSize.right - mLastComputedGridSize.right;
- int clearAllFocusScrollDiff = taskGridHorizontalDiff - clearAllWidth;
- targetScroll += mIsRtl ? clearAllFocusScrollDiff : -clearAllFocusScrollDiff;
- }
- return screenStart - targetScroll;
- }
-
private boolean isTaskViewWithinBounds(TaskView tv, int start, int end) {
int taskStart = mOrientationHandler.getChildStart(tv) + (int) tv.getOffsetAdjustment(
- showAsFullscreen(), showAsGrid());
+ showAsGrid());
int taskSize = (int) (mOrientationHandler.getMeasuredSize(tv) * tv.getSizeAdjustment(
showAsFullscreen()));
int taskEnd = taskStart + taskSize;
@@ -1257,7 +1243,7 @@
private boolean isTaskViewFullyWithinBounds(TaskView tv, int start, int end) {
int taskStart = mOrientationHandler.getChildStart(tv) + (int) tv.getOffsetAdjustment(
- showAsFullscreen(), showAsGrid());
+ showAsGrid());
int taskSize = (int) (mOrientationHandler.getMeasuredSize(tv) * tv.getSizeAdjustment(
showAsFullscreen()));
int taskEnd = taskStart + taskSize;
@@ -1564,7 +1550,7 @@
return;
}
- int currentTaskId = -1;
+ int currentTaskId = INVALID_TASK_ID;
TaskView currentTaskView = getTaskViewAt(mCurrentPage);
if (currentTaskView != null && currentTaskView.getTask() != null) {
currentTaskId = currentTaskView.getTask().key.id;
@@ -1574,7 +1560,8 @@
unloadVisibleTaskData(TaskView.FLAG_UPDATE_ALL);
TaskView ignoreResetTaskView =
- mIgnoreResetTaskId == -1 ? null : getTaskViewByTaskId(mIgnoreResetTaskId);
+ mIgnoreResetTaskId == INVALID_TASK_ID
+ ? null : getTaskViewByTaskId(mIgnoreResetTaskId);
// Save running task ID if it exists before rebinding all taskViews, otherwise the task from
// the runningTaskView currently bound could get assigned to another TaskView
@@ -1677,20 +1664,20 @@
newFocusedTaskView = getTaskViewAt(1);
}
}
- mFocusedTaskViewId = newFocusedTaskView != null ?
- newFocusedTaskView.getTaskViewId() : -1;
+ mFocusedTaskViewId =
+ newFocusedTaskView != null ? newFocusedTaskView.getTaskViewId() : INVALID_TASK_ID;
updateTaskSize();
updateChildTaskOrientations();
TaskView newRunningTaskView = null;
- if (runningTaskId != -1) {
+ if (runningTaskId != INVALID_TASK_ID) {
// Update mRunningTaskViewId to be the new TaskView that was assigned by binding
// the full list of tasks to taskViews
newRunningTaskView = getTaskViewByTaskId(runningTaskId);
if (newRunningTaskView != null) {
mRunningTaskViewId = newRunningTaskView.getTaskViewId();
} else {
- mRunningTaskViewId = -1;
+ mRunningTaskViewId = INVALID_TASK_ID;
}
}
@@ -1698,7 +1685,7 @@
if (mNextPage != INVALID_PAGE) {
// Restore mCurrentPage but don't call setCurrentPage() as that clobbers the scroll.
mCurrentPage = previousCurrentPage;
- if (currentTaskId != -1) {
+ if (currentTaskId != INVALID_TASK_ID) {
currentTaskView = getTaskViewByTaskId(currentTaskId);
if (currentTaskView != null) {
targetPage = indexOfChild(currentTaskView);
@@ -1706,7 +1693,7 @@
}
} else {
// Set the current page to the running task, but not if settling on new task.
- if (runningTaskId != -1) {
+ if (runningTaskId != INVALID_TASK_ID) {
targetPage = indexOfChild(newRunningTaskView);
} else if (getTaskViewCount() > 0) {
TaskView taskView = requireTaskViewAt(0);
@@ -1732,12 +1719,12 @@
});
}
- if (mIgnoreResetTaskId != -1 &&
+ if (mIgnoreResetTaskId != INVALID_TASK_ID &&
getTaskViewByTaskId(mIgnoreResetTaskId) != ignoreResetTaskView) {
// If the taskView mapping is changing, do not preserve the visuals. Since we are
// mostly preserving the first task, and new taskViews are added to the end, it should
// generally map to the same task.
- mIgnoreResetTaskId = -1;
+ mIgnoreResetTaskId = INVALID_TASK_ID;
}
resetTaskVisuals();
onTaskStackUpdated();
@@ -2477,8 +2464,7 @@
for (TaskViewSimulator tvs : taskViewSimulators) {
if (animatorSet == null) {
setGridProgress(1);
- tvs.taskPrimaryTranslation.value =
- runningTaskPrimaryGridTranslation;
+ tvs.taskPrimaryTranslation.value = runningTaskPrimaryGridTranslation;
} else {
animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1));
animatorSet.play(tvs.taskPrimaryTranslation.animateToValue(
@@ -2720,7 +2706,8 @@
return;
}
- int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
+ DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+ int taskTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
int topRowWidth = 0;
int bottomRowWidth = 0;
@@ -2862,7 +2849,7 @@
float snappedTaskGridTranslationX = 0;
if (snappedTaskView != null) {
snappedTaskNonGridScrollAdjustment = snappedTaskView.getScrollAdjustment(
- /*fullscreenEnabled=*/true, /*gridEnabled=*/false);
+ /*gridEnabled=*/false);
snappedTaskGridTranslationX = gridTranslations[snappedPage];
}
@@ -2887,18 +2874,28 @@
// If the total width is shorter than one grid's width, move ClearAllButton further away
// accordingly. Update longRowWidth if ClearAllButton has been moved.
- float clearAllShortTotalCompensation = 0;
+ float clearAllShortTotalWidthTranslation = 0;
int longRowWidth = Math.max(topRowWidth, bottomRowWidth);
if (longRowWidth < mLastComputedGridSize.width()) {
- float shortTotalCompensation = mLastComputedGridSize.width() - longRowWidth;
- clearAllShortTotalCompensation =
- mIsRtl ? -shortTotalCompensation : shortTotalCompensation;
- longRowWidth = mLastComputedGridSize.width();
+ mClearAllShortTotalWidthTranslation =
+ (mIsRtl
+ ? mLastComputedTaskSize.right
+ : deviceProfile.widthPx - mLastComputedTaskSize.left)
+ - longRowWidth - deviceProfile.overviewGridSideMargin;
+ clearAllShortTotalWidthTranslation = mIsRtl
+ ? -mClearAllShortTotalWidthTranslation : mClearAllShortTotalWidthTranslation;
+ if (snappedTaskRowWidth == longRowWidth) {
+ // Updated snappedTaskRowWidth as well if it's same as longRowWidth.
+ snappedTaskRowWidth += mClearAllShortTotalWidthTranslation;
+ }
+ longRowWidth += mClearAllShortTotalWidthTranslation;
+ } else {
+ mClearAllShortTotalWidthTranslation = 0;
}
float clearAllTotalTranslationX =
clearAllAccumulatedTranslation + clearAllShorterRowCompensation
- + clearAllShortTotalCompensation + snappedTaskNonGridScrollAdjustment;
+ + clearAllShortTotalWidthTranslation + snappedTaskNonGridScrollAdjustment;
if (focusedTaskIndex < taskCount) {
// Shift by focused task's width and spacing if a task is focused.
clearAllTotalTranslationX +=
@@ -2908,11 +2905,15 @@
// Make sure there are enough space between snapped page and ClearAllButton, for the case
// of swiping up after quick switch.
if (snappedTaskView != null) {
- int distanceFromClearAll = longRowWidth - snappedTaskRowWidth + mPageSpacing;
+ int distanceFromClearAll = longRowWidth - snappedTaskRowWidth;
// ClearAllButton should be off screen when snapped task is in its snapped position.
int minimumDistance =
- mTaskWidth - snappedTaskView.getLayoutParams().width
- + (mLastComputedGridSize.width() - mTaskWidth) / 2;
+ (mIsRtl
+ ? mLastComputedTaskSize.left
+ : deviceProfile.widthPx - mLastComputedTaskSize.right)
+ - deviceProfile.overviewGridSideMargin - mPageSpacing
+ + (mTaskWidth - snappedTaskView.getLayoutParams().width)
+ - mClearAllShortTotalWidthTranslation;
if (distanceFromClearAll < minimumDistance) {
int distanceDifference = minimumDistance - distanceFromClearAll;
snappedTaskGridTranslationX += mIsRtl ? distanceDifference : -distanceDifference;
@@ -3195,6 +3196,7 @@
// Grid specific properties.
boolean isFocusedTaskDismissed = false;
+ boolean isStagingFocusedTask = false;
TaskView nextFocusedTaskView = null;
boolean nextFocusedTaskFromTop = false;
float dismissedTaskWidth = 0;
@@ -3209,26 +3211,30 @@
if (showAsGrid) {
dismissedTaskWidth = dismissedTaskView.getLayoutParams().width + mPageSpacing;
isFocusedTaskDismissed = dismissedTaskViewId == mFocusedTaskViewId;
- if (isFocusedTaskDismissed && !isSplitSelectionActive()) {
- 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;
+ 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 @@
boolean snapToLastTask = false;
boolean isLandscapeSplit =
mActivity.getDeviceProfile().isLandscape && isSplitSelectionActive();
- boolean isSplitPlaceholderFirstInGrid = isSplitPlaceholderFirstInGrid();
- boolean isSplitPlaceholderLastInGrid = isSplitPlaceholderLastInGrid();
TaskView lastGridTaskView = showAsGrid ? getLastGridTaskView() : null;
int currentPageScroll = getScrollForPage(mCurrentPage);
int lastGridTaskScroll = getScrollForPage(indexOfChild(lastGridTaskView));
@@ -3263,37 +3267,61 @@
boolean bottomRowLonger = bottomGridRowSize > 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 @@
// dismissed index or next focused index. Offset successive task dismissal
// durations for a staggered effect.
distanceFromDismissedTask++;
- boolean isStagingFocusedTask =
- isFocusedTaskDismissed && nextFocusedTaskView == null;
int staggerColumn = isStagingFocusedTask
? (int) Math.ceil(distanceFromDismissedTask / 2f)
: distanceFromDismissedTask;
@@ -3508,11 +3534,6 @@
int focusedTaskScrollDiff = primaryScroll - focusedTaskScroll;
primaryTranslation +=
mIsRtl ? focusedTaskScrollDiff : -focusedTaskScrollDiff;
- if (isSplitPlaceholderFirstInGrid) {
- // Moves less if split placeholder is at the start.
- primaryTranslation +=
- mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
- }
}
anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(),
@@ -3641,14 +3662,6 @@
RecentsView.this);
int currentPageScroll = getScrollForPage(mCurrentPage);
mCurrentPageScrollDiff = primaryScroll - currentPageScroll;
- // Compensate for coordinate shift by split placeholder.
- if (isSplitPlaceholderFirstInGrid && !finalSnapToLastTask) {
- mCurrentPageScrollDiff +=
- mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
- } else if (isSplitPlaceholderLastInGrid && finalSnapToLastTask) {
- mCurrentPageScrollDiff +=
- mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize;
- }
}
}
} else if (dismissedIndex < pageToSnapTo || pageToSnapTo == taskCount - 1) {
@@ -3688,8 +3701,7 @@
int screenStart = mOrientationHandler.getPrimaryScroll(
RecentsView.this);
int taskStart = mOrientationHandler.getChildStart(taskView)
- + (int) taskView.getOffsetAdjustment(/*fullscreenEnabled=*/
- false, /*gridEnabled=*/ true);
+ + (int) taskView.getOffsetAdjustment(/*gridEnabled=*/ true);
// Rebalance only if there is a maximum gap between the task and the
// screen's edge; this ensures that rebalanced tasks are outside the
@@ -3848,14 +3860,6 @@
REMOVE_TASK_WAIT_FOR_APP_STOP_MS);
}
- /**
- * Returns {@code true} if one of the task thumbnails would intersect/overlap with the
- * {@link #mFirstFloatingTaskView}.
- */
- public boolean shouldShiftThumbnailsForSplitSelect() {
- return !mActivity.getDeviceProfile().isTablet || !mActivity.getDeviceProfile().isLandscape;
- }
-
protected void onDismissAnimationEnds() {
AccessibilityManagerCompat.sendDismissAnimationEndsEventToTest(getContext());
}
@@ -4414,65 +4418,6 @@
}
/**
- * Apply scroll offset to children of RecentsView when entering split select.
- */
- public void applySplitPrimaryScrollOffset() {
- float taskSplitScrollOffsetPrimary = 0f;
- float clearAllSplitScrollOffsetPrimar = 0f;
- if (isSplitPlaceholderFirstInGrid()) {
- taskSplitScrollOffsetPrimary = mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize;
- } else if (isSplitPlaceholderLastInGrid()) {
- clearAllSplitScrollOffsetPrimar =
- mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
- }
-
- for (int i = 0; i < getTaskViewCount(); i++) {
- requireTaskViewAt(i).setSplitScrollOffsetPrimary(taskSplitScrollOffsetPrimary);
- }
- mClearAllButton.setSplitSelectScrollOffsetPrimary(clearAllSplitScrollOffsetPrimar);
- }
-
- /**
- * Returns if split placeholder is at the beginning of RecentsView. Always returns {@code false}
- * if RecentsView is in portrait or RecentsView isn't shown as grid.
- */
- private boolean isSplitPlaceholderFirstInGrid() {
- if (!mActivity.getDeviceProfile().isLandscape || !showAsGrid()
- || !isSplitSelectionActive()) {
- return false;
- }
- @StagePosition int position = mSplitSelectStateController.getActiveSplitStagePosition();
- return mIsRtl
- ? position == STAGE_POSITION_BOTTOM_OR_RIGHT
- : position == STAGE_POSITION_TOP_OR_LEFT;
- }
-
- /**
- * Returns if split placeholder is at the end of RecentsView. Always returns {@code false} if
- * RecentsView is in portrait or RecentsView isn't shown as grid.
- */
- private boolean isSplitPlaceholderLastInGrid() {
- if (!mActivity.getDeviceProfile().isLandscape || !showAsGrid()
- || !isSplitSelectionActive()) {
- return false;
- }
- @StagePosition int position = mSplitSelectStateController.getActiveSplitStagePosition();
- return mIsRtl
- ? position == STAGE_POSITION_TOP_OR_LEFT
- : position == STAGE_POSITION_BOTTOM_OR_RIGHT;
- }
-
- /**
- * Reset scroll offset on children of RecentsView when exiting split select.
- */
- public void resetSplitPrimaryScrollOffset() {
- for (int i = 0; i < getTaskViewCount(); i++) {
- requireTaskViewAt(i).setSplitScrollOffsetPrimary(0);
- }
- mClearAllButton.setSplitSelectScrollOffsetPrimary(0);
- }
-
- /**
* Resets the visuals when exit modal state.
*/
public void resetModalVisuals() {
@@ -4680,14 +4625,29 @@
* Note that the translation can be its primary or secondary dimension.
*/
public float getSplitSelectTranslation() {
- int splitPosition = getSplitSelectController().getActiveSplitStagePosition();
- if (!shouldShiftThumbnailsForSplitSelect()) {
- return 0f;
- }
+ DeviceProfile deviceProfile = mActivity.getDeviceProfile();
PagedOrientationHandler orientationHandler = getPagedOrientationHandler();
+ int splitPosition = getSplitSelectController().getActiveSplitStagePosition();
+ int splitPlaceholderSize =
+ mActivity.getResources().getDimensionPixelSize(R.dimen.split_placeholder_size);
int direction = orientationHandler.getSplitTranslationDirectionFactor(
- splitPosition, mActivity.getDeviceProfile());
- return mActivity.getResources().getDimension(R.dimen.split_placeholder_size) * direction;
+ splitPosition, deviceProfile);
+
+ if (deviceProfile.isTablet && deviceProfile.isLandscape) {
+ // Only shift TaskViews if there is not enough space on the side of
+ // mLastComputedTaskSize to minimize motion.
+ int sideSpace = mIsRtl
+ ? deviceProfile.widthPx - mLastComputedTaskSize.right
+ : mLastComputedTaskSize.left;
+ int extraSpace = splitPlaceholderSize + mPageSpacing - sideSpace;
+ if (extraSpace <= 0f) {
+ return 0f;
+ }
+
+ return extraSpace * direction;
+ }
+
+ return splitPlaceholderSize * direction;
}
protected void onRotateInSplitSelectionState() {
@@ -4709,8 +4669,6 @@
if (mSplitInstructionsView != null) {
mSplitInstructionsView.ensureProperRotation();
}
-
- applySplitPrimaryScrollOffset();
}
private void updateDeadZoneRects() {
@@ -5201,11 +5159,21 @@
}
private int getLastViewIndex() {
- return mDisallowScrollToClearAll
- ? mShowAsGridLastOnLayout
- ? indexOfChild(getLastGridTaskView())
- : getTaskViewCount() - 1
- : indexOfChild(mClearAllButton);
+ if (!mDisallowScrollToClearAll) {
+ return indexOfChild(mClearAllButton);
+ }
+
+ if (!mShowAsGridLastOnLayout) {
+ return getTaskViewCount() - 1;
+ }
+
+ TaskView lastGridTaskView = getLastGridTaskView();
+ if (lastGridTaskView != null) {
+ return indexOfChild(lastGridTaskView);
+ }
+
+ // Returns focus task if there are no grid tasks.
+ return indexOfChild(getFocusedTaskView());
}
/**
@@ -5246,11 +5214,11 @@
}
final int taskCount = getTaskViewCount();
+ int lastTaskScroll = getLastTaskScroll(clearAllScroll, clearAllWidth);
for (int i = 0; i < taskCount; i++) {
TaskView taskView = requireTaskViewAt(i);
- float scrollDiff = taskView.getScrollAdjustment(showAsFullscreen, showAsGrid);
+ float scrollDiff = taskView.getScrollAdjustment(showAsGrid);
int pageScroll = newPageScrolls[i] + (int) scrollDiff;
- int lastTaskScroll = getLastTaskScroll(clearAllScroll, clearAllWidth);
if ((mIsRtl && pageScroll < lastTaskScroll)
|| (!mIsRtl && pageScroll > lastTaskScroll)) {
pageScroll = lastTaskScroll;
@@ -5274,8 +5242,7 @@
int childOffset = super.getChildOffset(index);
View child = getChildAt(index);
if (child instanceof TaskView) {
- childOffset += ((TaskView) child).getOffsetAdjustment(showAsFullscreen(),
- showAsGrid());
+ childOffset += ((TaskView) child).getOffsetAdjustment(showAsGrid());
} else if (child instanceof ClearAllButton) {
childOffset += ((ClearAllButton) child).getOffsetAdjustment(mOverviewFullscreenEnabled,
showAsGrid());
@@ -5383,17 +5350,19 @@
int gridTaskSizeAndSpacing = mLastComputedGridTaskSize.width() + mPageSpacing;
int positionDiff = gridTaskSizeAndSpacing * (lastGridTaskViewPosition - taskViewPosition);
- int lastTaskEnd = (mIsRtl
- ? mLastComputedGridSize.left
- : mLastComputedGridSize.right)
- + (mIsRtl ? mPageSpacing : -mPageSpacing);
- int taskEnd = lastTaskEnd + (mIsRtl ? positionDiff : -positionDiff);
+ int taskEnd = getLastTaskEnd() + (mIsRtl ? positionDiff : -positionDiff);
int normalTaskEnd = mIsRtl
? mLastComputedGridTaskSize.left
: mLastComputedGridTaskSize.right;
return taskEnd - normalTaskEnd;
}
+ private int getLastTaskEnd() {
+ return mIsRtl
+ ? mLastComputedGridSize.left + mPageSpacing + mClearAllShortTotalWidthTranslation
+ : mLastComputedGridSize.right - mPageSpacing - mClearAllShortTotalWidthTranslation;
+ }
+
private int getPositionInRow(
TaskView taskView, IntArray topRowIdArray, IntArray bottomRowIdArray) {
int position = topRowIdArray.indexOf(taskView.getTaskViewId());
@@ -5693,14 +5662,10 @@
taskView = getTaskViewAt(--targetPage);
}
// Target a scroll where targetPage is on left of screen but still fully visible.
- int lastTaskEnd = (mIsRtl
- ? mLastComputedGridSize.left
- : mLastComputedGridSize.right)
- + (mIsRtl ? mPageSpacing : -mPageSpacing);
int normalTaskEnd = mIsRtl
? mLastComputedGridTaskSize.left
: mLastComputedGridTaskSize.right;
- int targetScroll = getScrollForPage(targetPage) + normalTaskEnd - lastTaskEnd;
+ int targetScroll = getScrollForPage(targetPage) + normalTaskEnd - getLastTaskEnd();
// Find a page that is close to targetScroll while not over it.
while (targetPage - 1 >= 0
&& (mIsRtl
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index fb85605..b9aaef6 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -375,7 +375,6 @@
// Used when in SplitScreenSelectState
private float mSplitSelectTranslationY;
private float mSplitSelectTranslationX;
- private float mSplitSelectScrollOffsetPrimary;
@Nullable
private ObjectAnimator mIconAndDimAnimator;
@@ -1297,10 +1296,6 @@
applyTranslationY();
}
- public void setSplitScrollOffsetPrimary(float splitSelectScrollOffsetPrimary) {
- mSplitSelectScrollOffsetPrimary = splitSelectScrollOffsetPrimary;
- }
-
private void setDismissTranslationX(float x) {
mDismissTranslationX = x;
applyTranslationX();
@@ -1364,19 +1359,18 @@
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) {