diff --git a/quickstep/res/layout/keyboard_quick_switch_view.xml b/quickstep/res/layout/keyboard_quick_switch_view.xml index 2420a4624e..4118500656 100644 --- a/quickstep/res/layout/keyboard_quick_switch_view.xml +++ b/quickstep/res/layout/keyboard_quick_switch_view.xml @@ -22,6 +22,7 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/keyboard_quick_switch_margin_top" android:layout_marginHorizontal="@dimen/keyboard_quick_switch_margin_ends" + android:layout_gravity="center_horizontal" android:background="@drawable/keyboard_quick_switch_view_background" android:clipToOutline="true" android:alpha="0" diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java index 23a5a27984..3b7ad3e618 100644 --- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java +++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java @@ -139,18 +139,42 @@ public final class KeyboardQuickSwitchController implements @NonNull Set taskIdsToExclude, boolean wasOpenedFromTaskbar) { if (mQuickSwitchViewController != null) { - if (!mQuickSwitchViewController.isCloseAnimationRunning() - && mQuickSwitchViewController.wasOpenedFromTaskbar() == wasOpenedFromTaskbar) { - return; - } + if (!mQuickSwitchViewController.isCloseAnimationRunning()) { + if (mQuickSwitchViewController.wasOpenedFromTaskbar() == wasOpenedFromTaskbar) { + return; + } - // Allow the KQS to be reopened during the close animation to make it more responsive. - // Similarly, if KQS was opened in different mode (from taskbar vs. keyboard event), - // close it so it can be reopened in the correct mode. - // TODO(b/368119679) Consider updating list of shown tasks in place, or at least reopen - // the view in the same vertical location. - closeQuickSwitchView(false); + // Relayout the KQS view instead of recreating a new one if it is the current + // trigger surface is different than the previous one. + final int currentFocusIndexOverride = + currentFocusedIndex == -1 && !mControllerCallbacks.isFirstTaskRunning() + ? 0 : currentFocusedIndex; + + // Skip the task reload if the list is not changed. + if (!mModel.isTaskListValid(mTaskListChangeId) || !taskIdsToExclude.equals( + mExcludedTaskIds)) { + mExcludedTaskIds = taskIdsToExclude; + mTaskListChangeId = mModel.getTasks((tasks) -> { + processLoadedTasks(tasks, taskIdsToExclude); + mQuickSwitchViewController.updateQuickSwitchView( + mTasks, + mNumHiddenTasks, + currentFocusIndexOverride, + mHasDesktopTask, + mWasDesktopTaskFilteredOut); + }); + } + + mQuickSwitchViewController.updateLayoutForSurface(wasOpenedFromTaskbar, + currentFocusIndexOverride); + return; + } else { + // Allow the KQS to be reopened during the close animation to make it more + // responsive. + closeQuickSwitchView(false); + } } + mOverlayContext = mControllers.taskbarOverlayController.requestWindow(); if (Flags.taskbarOverflow()) { mOverlayContext.getDragLayer().addTouchController(this); @@ -186,13 +210,7 @@ public final class KeyboardQuickSwitchController implements mExcludedTaskIds = taskIdsToExclude; mTaskListChangeId = mModel.getTasks((tasks) -> { - mHasDesktopTask = false; - mWasDesktopTaskFilteredOut = false; - if (onDesktop) { - processLoadedTasksOnDesktop(tasks, taskIdsToExclude); - } else { - processLoadedTasks(tasks, taskIdsToExclude); - } + processLoadedTasks(tasks, taskIdsToExclude); // Check if the first task is running after the recents model has updated so that we use // the correct index. mQuickSwitchViewController.openQuickSwitchView( @@ -213,6 +231,17 @@ public final class KeyboardQuickSwitchController implements } private void processLoadedTasks(List tasks, Set taskIdsToExclude) { + mHasDesktopTask = false; + mWasDesktopTaskFilteredOut = false; + if (mControllers.taskbarDesktopModeController.getAreDesktopTasksVisible()) { + processLoadedTasksOnDesktop(tasks, taskIdsToExclude); + } else { + processLoadedTasksOutsideDesktop(tasks, taskIdsToExclude); + } + } + + private void processLoadedTasksOutsideDesktop(List tasks, + Set taskIdsToExclude) { // Only store MAX_TASK tasks, from most to least recent Collections.reverse(tasks); mTasks = tasks.stream() diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java index 05d34b5cb7..1967dfd980 100644 --- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java +++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java @@ -201,6 +201,8 @@ public class KeyboardQuickSwitchView extends ConstraintLayout { int currentFocusIndexOverride, @NonNull KeyboardQuickSwitchViewController.ViewCallbacks viewCallbacks, boolean useDesktopTaskView) { + mContent.removeAllViews(); + mViewCallbacks = viewCallbacks; Resources resources = context.getResources(); Resources.Theme theme = context.getTheme(); @@ -333,11 +335,17 @@ public class KeyboardQuickSwitchView extends ConstraintLayout { return closeAnimation; } - private void animateOpen(int currentFocusIndexOverride) { + protected void animateOpen(int currentFocusIndexOverride) { if (mOpenAnimation != null) { // Restart animation since currentFocusIndexOverride can change the initial scroll. mOpenAnimation.cancel(); } + + // Reset the alpha for the case where the KQS view is opened before. + setAlpha(0); + mScrollView.setAlpha(0); + mNoRecentItemsPane.setAlpha(0); + mOpenAnimation = new AnimatorSet(); Animator outlineAnimation = mOutlineAnimationProgress.animateToValue(1f); diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java index 390112e676..985cc26d8e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java @@ -128,6 +128,23 @@ public class KeyboardQuickSwitchViewController { /* useDesktopTaskView= */ !onDesktop && hasDesktopTask); } + protected void updateQuickSwitchView( + @NonNull List tasks, + int numHiddenTasks, + int currentFocusIndexOverride, + boolean hasDesktopTask, + boolean wasDesktopTaskFilteredOut) { + mWasDesktopTaskFilteredOut = wasDesktopTaskFilteredOut; + mKeyboardQuickSwitchView.applyLoadPlan( + mOverlayContext, + tasks, + numHiddenTasks, + /* updateTasks= */ true, + currentFocusIndexOverride, + mViewCallbacks, + /* useDesktopTaskView= */ !mOnDesktop && hasDesktopTask); + } + protected void positionView(boolean wasOpenedFromTaskbar, boolean isTransientTaskbar) { if (!wasOpenedFromTaskbar) { // Keep the default positioning. @@ -155,6 +172,20 @@ public class KeyboardQuickSwitchViewController { mKeyboardQuickSwitchView.setLayoutParams(lp); } + protected void updateLayoutForSurface(boolean updateLayoutFromTaskbar, + int currentFocusIndexOverride) { + BaseDragLayer.LayoutParams lp = + (BaseDragLayer.LayoutParams) mKeyboardQuickSwitchView.getLayoutParams(); + + if (updateLayoutFromTaskbar) { + lp.width = BaseDragLayer.LayoutParams.WRAP_CONTENT; + } else { + lp.width = BaseDragLayer.LayoutParams.MATCH_PARENT; + } + + mKeyboardQuickSwitchView.animateOpen(currentFocusIndexOverride); + } + boolean isCloseAnimationRunning() { return mCloseAnimation != null; }