diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java index d40f2ae017..0dcd723363 100644 --- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java @@ -36,6 +36,7 @@ import androidx.annotation.RequiresApi; import com.android.launcher3.BaseActivity; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.R; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.popup.SystemShortcut; @@ -77,9 +78,11 @@ public class TaskOverlayFactory implements ResourceBasedOverride { RecentsOrientedState orientedState = taskView.getRecentsView().getPagedViewOrientedState(); boolean canLauncherRotate = orientedState.isRecentsActivityRotationAllowed(); boolean isInLandscape = orientedState.getTouchRotation() != ROTATION_0; + boolean isTablet = activity.getDeviceProfile().isTablet; // Add overview actions to the menu when in in-place rotate landscape mode. - if (!canLauncherRotate && isInLandscape) { + if ((!canLauncherRotate && isInLandscape) + || (isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get())) { // Add screenshot action to task menu. List screenshotShortcuts = TaskShortcutFactory.SCREENSHOT .getShortcuts(activity, taskContainer); diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java index eeabdc83d1..0d21e6048b 100644 --- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java +++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java @@ -55,7 +55,8 @@ public class OverviewActionsView extends FrameLayo HIDDEN_NO_TASKS, HIDDEN_NO_RECENTS, HIDDEN_SPLIT_SCREEN, - HIDDEN_SPLIT_SELECT_ACTIVE + HIDDEN_SPLIT_SELECT_ACTIVE, + HIDDEN_ACTIONS_IN_MENU }) @Retention(RetentionPolicy.SOURCE) public @interface ActionsHiddenFlags { } @@ -65,6 +66,7 @@ public class OverviewActionsView extends FrameLayo public static final int HIDDEN_NO_RECENTS = 1 << 2; public static final int HIDDEN_SPLIT_SCREEN = 1 << 3; public static final int HIDDEN_SPLIT_SELECT_ACTIVE = 1 << 4; + public static final int HIDDEN_ACTIONS_IN_MENU = 1 << 5; @IntDef(flag = true, value = { DISABLED_SCROLLING, diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 8facb0a35e..61d6179a43 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -42,6 +42,7 @@ import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.OVERSHOOT_0_75; import static com.android.launcher3.anim.Interpolators.clampToProgress; +import static com.android.launcher3.config.FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW; import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCH_FROM_STAGED_APP; import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_ACTIONS_SPLIT; @@ -60,6 +61,7 @@ import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA; import static com.android.quickstep.views.DesktopTaskView.DESKTOP_MODE_SUPPORTED; import static com.android.quickstep.views.OverviewActionsView.FLAG_IS_NOT_TABLET; import static com.android.quickstep.views.OverviewActionsView.FLAG_SINGLE_TASK; +import static com.android.quickstep.views.OverviewActionsView.HIDDEN_ACTIONS_IN_MENU; import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION; import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS; import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS; @@ -1864,6 +1866,9 @@ public abstract class RecentsView : ArrowPopup { fun showForTask( taskContainer: TaskIdAttributeContainer, - alignSecondRow: Boolean = false + alignedOptionIndex: Int = 0 ): Boolean { val activity = BaseDraggingActivity.fromContext( @@ -59,7 +59,7 @@ class TaskMenuViewWithArrow : ArrowPopup { false ) as TaskMenuViewWithArrow<*> - return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignSecondRow) + return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignedOptionIndex) } } @@ -82,9 +82,9 @@ class TaskMenuViewWithArrow : ArrowPopup { CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION } - private var alignSecondRow: Boolean = false - private val extraSpaceForSecondRowAlignment: Int - get() = if (alignSecondRow) optionMeasuredHeight else 0 + private var alignedOptionIndex: Int = 0 + private val extraSpaceForRowAlignment: Int + get() = optionMeasuredHeight * alignedOptionIndex private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid) private lateinit var taskView: TaskView @@ -125,7 +125,7 @@ class TaskMenuViewWithArrow : ArrowPopup { private fun populateAndShowForTask( taskContainer: TaskIdAttributeContainer, - alignSecondRow: Boolean + alignedOptionIndex: Int ): Boolean { if (isAttachedToWindow) { return false @@ -133,7 +133,7 @@ class TaskMenuViewWithArrow : ArrowPopup { taskView = taskContainer.taskView this.taskContainer = taskContainer - this.alignSecondRow = alignSecondRow + this.alignedOptionIndex = alignedOptionIndex if (!populateMenu()) return false addScrim() show() @@ -257,8 +257,7 @@ class TaskMenuViewWithArrow : ArrowPopup { } /** - * Orients this container to the left or right of the given icon, aligning with the first option - * or second. + * Orients this container to the left or right of the given icon, aligning with the desired row. * * These are the preferred orientations, in order (RTL prefers right-aligned over left): * - Right and first option aligned @@ -298,7 +297,7 @@ class TaskMenuViewWithArrow : ArrowPopup { // Offset y so that the arrow and row are center-aligned with the original icon. val iconHeight = mTempRect.height() val yOffset = (optionMeasuredHeight - iconHeight) / 2 - var menuStartY = mTempRect.top - yOffset - extraSpaceForSecondRowAlignment + var menuStartY = mTempRect.top - yOffset - extraSpaceForRowAlignment // Insets are added later, so subtract them now. menuStartX -= insets.left @@ -316,8 +315,7 @@ class TaskMenuViewWithArrow : ArrowPopup { override fun addArrow() { popupContainer.addView(mArrow) mArrow.x = getArrowX() - mArrow.y = - y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) + extraSpaceForSecondRowAlignment + mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) + extraSpaceForRowAlignment updateArrowColor() diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index b23c87349c..8c8c2ba8aa 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -71,6 +71,7 @@ import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.Interpolators; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.statemanager.StatefulActivity; @@ -953,10 +954,20 @@ public class TaskView extends FrameLayout implements Reusable { protected boolean showTaskMenuWithContainer(IconView iconView) { TaskIdAttributeContainer menuContainer = mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1]; - if (mActivity.getDeviceProfile().isTablet) { - boolean alignSecondRow = getRecentsView().isOnGridBottomRow(menuContainer.getTaskView()) - && mActivity.getDeviceProfile().isLandscape; - return TaskMenuViewWithArrow.Companion.showForTask(menuContainer, alignSecondRow); + DeviceProfile dp = mActivity.getDeviceProfile(); + if (dp.isTablet) { + int alignedOptionIndex = 0; + if (getRecentsView().isOnGridBottomRow(menuContainer.getTaskView()) && dp.isLandscape) { + if (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) { + // With no focused task, there is less available space below the tasks, so align + // the arrow to the third option in the menu. + alignedOptionIndex = 2; + } else { + // Bottom row of landscape grid aligns arrow to second option to avoid clipping + alignedOptionIndex = 1; + } + } + return TaskMenuViewWithArrow.Companion.showForTask(menuContainer, alignedOptionIndex); } else { return TaskMenuView.showForTask(menuContainer); } diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 0cefb7e666..0070f95666 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -1411,8 +1411,10 @@ public class DeviceProfile { /** Gets the space that the overview actions will take, including bottom margin. */ public int getOverviewActionsClaimedSpace() { - return overviewActionsTopMarginPx + overviewActionsHeight - + getOverviewActionsClaimedSpaceBelow(); + int overviewActionsSpace = isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get() + ? 0 + : (overviewActionsTopMarginPx + overviewActionsHeight); + return overviewActionsSpace + getOverviewActionsClaimedSpaceBelow(); } /** diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 16be5978b1..4f4e65ca2b 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -394,6 +394,10 @@ public final class FeatureFlags { "Enables taskbar pinning to allow user to switch between transient and persistent " + "taskbar flavors"); + public static final BooleanFlag ENABLE_GRID_ONLY_OVERVIEW = getDebugFlag( + "ENABLE_GRID_ONLY_OVERVIEW", false, + "Enable a grid-only overview without a focused task."); + public static void initialize(Context context) { synchronized (sDebugFlags) { for (DebugFlag flag : sDebugFlags) {