diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java index 94d62b2c8f..745defc18b 100644 --- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java +++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java @@ -425,7 +425,7 @@ public class KeyboardQuickSwitchView extends ConstraintLayout { @Override public boolean onKeyUp(int keyCode, KeyEvent event) { - return (mViewCallbacks != null && mViewCallbacks.onKeyUp(keyCode, event)) + return (mViewCallbacks != null && mViewCallbacks.onKeyUp(keyCode, event, mIsRtl)) || super.onKeyUp(keyCode, event); } diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java index f0f361ed51..c1f764f148 100644 --- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java @@ -19,6 +19,7 @@ import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import android.animation.Animator; import android.view.KeyEvent; +import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -125,18 +126,26 @@ public class KeyboardQuickSwitchViewController { } private int launchTaskAt(int index) { - KeyboardQuickSwitchTaskView taskView = mKeyboardQuickSwitchView.getTaskAt(index); + if (mCloseAnimation != null) { + // Ignore taps on task views and alt key unpresses while the close animation is running. + return -1; + } + // Even with a valid index, this can be null if the user tries to quick switch before the + // views have been added in the KeyboardQuickSwitchView. + View taskView = mKeyboardQuickSwitchView.getTaskAt(index); GroupTask task = mControllerCallbacks.getTaskAt(index); - if (taskView == null || task == null) { + if (task == null) { return Math.max(0, index); } else if (task.task2 == null) { UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance().startActivityFromRecents( task.task1.key, mControllers.taskbarActivityContext.getActivityLaunchOptions( - taskView, null).options)); + taskView == null ? mKeyboardQuickSwitchView : taskView, null) + .options)); } else { - mControllers.uiController.launchSplitTasks(taskView, task); + mControllers.uiController.launchSplitTasks( + taskView == null ? mKeyboardQuickSwitchView : taskView, task); } return -1; } @@ -160,15 +169,26 @@ public class KeyboardQuickSwitchViewController { class ViewCallbacks { - boolean onKeyUp(int keyCode, KeyEvent event) { - if (keyCode != KeyEvent.KEYCODE_TAB) { + boolean onKeyUp(int keyCode, KeyEvent event, boolean isRTL) { + if (keyCode != KeyEvent.KEYCODE_TAB + && keyCode != KeyEvent.KEYCODE_DPAD_RIGHT + && keyCode != KeyEvent.KEYCODE_DPAD_LEFT + && keyCode != KeyEvent.KEYCODE_GRAVE + && keyCode != KeyEvent.KEYCODE_ESCAPE) { return false; } + if (keyCode == KeyEvent.KEYCODE_GRAVE || keyCode == KeyEvent.KEYCODE_ESCAPE) { + closeQuickSwitchView(true); + return true; + } + boolean traverseBackwards = (keyCode == KeyEvent.KEYCODE_TAB && event.isShiftPressed()) + || (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT && !isRTL) + || (keyCode == KeyEvent.KEYCODE_DPAD_LEFT && isRTL); int taskCount = mControllerCallbacks.getTaskCount(); int toIndex = mCurrentFocusIndex == -1 // Focus the second-most recent app if possible ? (taskCount > 1 ? 1 : 0) - : (event.isShiftPressed() + : (traverseBackwards // focus a more recent task or loop back to the opposite end ? Math.max(0, mCurrentFocusIndex == 0 ? taskCount - 1 : mCurrentFocusIndex - 1) diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index dcef6d3536..3046076ec3 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -388,8 +388,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController { } @Override - public void launchSplitTasks(View taskView, GroupTask groupTask) { - super.launchSplitTasks(taskView, groupTask); + public void launchSplitTasks(@NonNull View taskView, @NonNull GroupTask groupTask) { mLauncher.launchSplitTasks(taskView, groupTask); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index 10d339bdeb..24a089cd8d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -25,6 +25,7 @@ import android.view.MotionEvent; import android.view.View; import androidx.annotation.CallSuper; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.model.data.ItemInfo; @@ -252,15 +253,6 @@ public class TaskbarUIController { mControllers.keyboardQuickSwitchController.openQuickSwitchView(); } - /** - * Closes the Keyboard Quick Switch View. - * - * No-op if the view is already closed - */ - public void closeQuickSwitchView() { - mControllers.keyboardQuickSwitchController.closeQuickSwitchView(); - } - /** * Launches the focused task and closes the Keyboard Quick Switch View. * @@ -280,5 +272,5 @@ public class TaskbarUIController { * * No-op if the view is not yet open. */ - public void launchSplitTasks(View taskview, GroupTask groupTask) { } + public void launchSplitTasks(@NonNull View taskview, @NonNull GroupTask groupTask) { } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 80ce3693bb..46cd045c8c 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -1214,7 +1214,7 @@ public class QuickstepLauncher extends Launcher { * * If the second split task is missing, launches the first task normally. */ - public void launchSplitTasks(View taskView, GroupTask groupTask) { + public void launchSplitTasks(@NonNull View taskView, @NonNull GroupTask groupTask) { if (groupTask.task2 == null) { UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance().startActivityFromRecents(