From 633b94abf16f94cd03984c19cafd084544cc19ee Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Thu, 20 Feb 2025 12:50:02 -0800 Subject: [PATCH] Fix icon positioning for flexible split in Overview In flexible split ratios like 90:10 and 10:90, we hide the Overview icon of the smaller app completely. This resulted in a bug where the single remaining visible icon was positioned badly. Fixed this by adding a check in updateIconPlacement() so that we can skip the two-icon positioning and center the visible icon alone. Also fixed the cases where split select is initiated on a split tile (from Taskbar). Now the correct icon should be shown and centered. Fixes: 391865942 Flag: com.android.wm.shell.enable_flexible_two_app_split Test: Single icon is positioned correctly in the middle. When split select is initiated, the right icon is shown and centered. When app chip menus are enabled, the (existing) correct behavior is not changed. Change-Id: I79842222fc325a7661cbabbb54d277389a317504 --- .../orientation/LandscapePagedViewHandler.kt | 27 +++++-- .../orientation/PortraitPagedViewHandler.java | 79 +++++++++++++------ .../RecentsPagedOrientationHandler.kt | 3 +- .../orientation/SeascapePagedViewHandler.kt | 22 ++++-- .../quickstep/views/GroupedTaskView.kt | 30 +++++-- .../LandscapePagedViewHandlerTest.kt | 1 + .../SeascapePagedViewHandlerTest.kt | 1 + 7 files changed, 121 insertions(+), 42 deletions(-) diff --git a/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.kt b/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.kt index 59ea8fa98a..17f861d77c 100644 --- a/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.kt +++ b/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.kt @@ -577,7 +577,8 @@ open class LandscapePagedViewHandler : RecentsPagedOrientationHandler { isRtl: Boolean, deviceProfile: DeviceProfile, splitConfig: SplitBounds, - inSplitSelection: Boolean + inSplitSelection: Boolean, + oneIconHiddenDueToSmallWidth: Boolean, ) { val spaceAboveSnapshot = deviceProfile.overviewTaskThumbnailTopMarginPx val totalThumbnailHeight = groupedTaskViewHeight - spaceAboveSnapshot @@ -590,7 +591,8 @@ open class LandscapePagedViewHandler : RecentsPagedOrientationHandler { totalThumbnailHeight, isRtl, deviceProfile.overviewTaskMarginPx, - dividerBar + dividerBar, + oneIconHiddenDueToSmallWidth, ) updateSplitIconsPosition(primaryIconView, topLeftY, isRtl) @@ -647,6 +649,7 @@ open class LandscapePagedViewHandler : RecentsPagedOrientationHandler { isRtl: Boolean, overviewTaskMarginPx: Int, dividerSize: Int, + oneIconHiddenDueToSmallWidth: Boolean, ): SplitIconPositions { return if (Flags.enableOverviewIconMenu()) { if (isRtl) { @@ -655,11 +658,21 @@ open class LandscapePagedViewHandler : RecentsPagedOrientationHandler { SplitIconPositions(0, primarySnapshotHeight + dividerSize) } } else { - val topLeftY = primarySnapshotHeight + overviewTaskMarginPx - SplitIconPositions( - topLeftY = topLeftY, - bottomRightY = topLeftY + dividerSize + taskIconHeight - ) + if (oneIconHiddenDueToSmallWidth) { + // Center both icons + val centerY = primarySnapshotHeight + overviewTaskMarginPx + + ((taskIconHeight + dividerSize) / 2) + SplitIconPositions( + topLeftY = centerY, + bottomRightY = centerY, + ) + } else { + val topLeftY = primarySnapshotHeight + overviewTaskMarginPx + SplitIconPositions( + topLeftY = topLeftY, + bottomRightY = topLeftY + dividerSize + taskIconHeight, + ) + } } } diff --git a/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java index d9ad7cec3b..c4e82d6a02 100644 --- a/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java +++ b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java @@ -671,7 +671,8 @@ public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements public void setSplitIconParams(View primaryIconView, View secondaryIconView, int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight, int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl, - DeviceProfile deviceProfile, SplitBounds splitConfig, boolean inSplitSelection) { + DeviceProfile deviceProfile, SplitBounds splitConfig, boolean inSplitSelection, + boolean oneIconHiddenDueToSmallWidth) { FrameLayout.LayoutParams primaryIconParams = (FrameLayout.LayoutParams) primaryIconView.getLayoutParams(); FrameLayout.LayoutParams secondaryIconParams = enableOverviewIconMenu() @@ -726,16 +727,30 @@ public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements secondaryIconParams.gravity = TOP | (isRtl ? END : START); if (!inSplitSelection) { if (splitConfig.initiatedFromSeascape) { - // if the split was initiated from seascape, - // the task on the right (secondary) is slightly larger - primaryIconView.setTranslationX(bottomToMidpointOffset - taskIconHeight); - secondaryIconView.setTranslationX(bottomToMidpointOffset); + if (oneIconHiddenDueToSmallWidth) { + // Center both icons + float centerX = bottomToMidpointOffset - (taskIconHeight / 2f); + primaryIconView.setTranslationX(centerX); + secondaryIconView.setTranslationX(centerX); + } else { + // the task on the right (secondary) is slightly larger + primaryIconView.setTranslationX( + bottomToMidpointOffset - taskIconHeight); + secondaryIconView.setTranslationX(bottomToMidpointOffset); + } } else { - // if not, - // the task on the left (primary) is slightly larger - primaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset - - taskIconHeight); - secondaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset); + if (oneIconHiddenDueToSmallWidth) { + // Center both icons + float centerX = + bottomToMidpointOffset + insetOffset - (taskIconHeight / 2f); + primaryIconView.setTranslationX(centerX); + secondaryIconView.setTranslationX(centerX); + } else { + // the task on the left (primary) is slightly larger + primaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset + - taskIconHeight); + secondaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset); + } } } } else { @@ -743,16 +758,30 @@ public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements secondaryIconParams.gravity = TOP | (isRtl ? START : END); if (!inSplitSelection) { if (!splitConfig.initiatedFromSeascape) { - // if the split was initiated from landscape, - // the task on the left (primary) is slightly larger - primaryIconView.setTranslationX(-bottomToMidpointOffset); - secondaryIconView.setTranslationX(-bottomToMidpointOffset + taskIconHeight); + if (oneIconHiddenDueToSmallWidth) { + // Center both icons + float centerX = -bottomToMidpointOffset + (taskIconHeight / 2f); + primaryIconView.setTranslationX(centerX); + secondaryIconView.setTranslationX(centerX); + } else { + // the task on the left (primary) is slightly larger + primaryIconView.setTranslationX(-bottomToMidpointOffset); + secondaryIconView.setTranslationX( + -bottomToMidpointOffset + taskIconHeight); + } } else { - // if not, - // the task on the right (secondary) is slightly larger - primaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset); - secondaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset - + taskIconHeight); + if (oneIconHiddenDueToSmallWidth) { + // Center both icons + float centerX = + -bottomToMidpointOffset - insetOffset + (taskIconHeight / 2f); + primaryIconView.setTranslationX(centerX); + secondaryIconView.setTranslationX(centerX); + } else { + // the task on the right (secondary) is slightly larger + primaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset); + secondaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset + + taskIconHeight); + } } } } @@ -760,9 +789,15 @@ public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements primaryIconParams.gravity = TOP | CENTER_HORIZONTAL; secondaryIconParams.gravity = TOP | CENTER_HORIZONTAL; if (!inSplitSelection) { - // shifts icon half a width left (height is used here since icons are square) - primaryIconView.setTranslationX(-(taskIconHeight / 2f)); - secondaryIconView.setTranslationX(taskIconHeight / 2f); + if (oneIconHiddenDueToSmallWidth) { + // Center both icons + primaryIconView.setTranslationX(0); + secondaryIconView.setTranslationX(0); + } else { + // shifts icon half a width left (height is used here since icons are square) + primaryIconView.setTranslationX(-(taskIconHeight / 2f)); + secondaryIconView.setTranslationX(taskIconHeight / 2f); + } } } if (!enableOverviewIconMenu() && !inSplitSelection) { diff --git a/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.kt b/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.kt index 78f9a0a556..9b3c4679b1 100644 --- a/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.kt +++ b/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.kt @@ -237,7 +237,8 @@ interface RecentsPagedOrientationHandler : PagedOrientationHandler { isRtl: Boolean, deviceProfile: DeviceProfile, splitConfig: SplitConfigurationOptions.SplitBounds, - inSplitSelection: Boolean + inSplitSelection: Boolean, + oneIconHiddenDueToSmallWidth: Boolean, ) /* diff --git a/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.kt b/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.kt index 9bfa2bf722..0cb983dbe9 100644 --- a/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.kt +++ b/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.kt @@ -353,17 +353,18 @@ class SeascapePagedViewHandler : LandscapePagedViewHandler() { isRtl: Boolean, overviewTaskMarginPx: Int, dividerSize: Int, + oneIconHiddenDueToSmallWidth: Boolean, ): SplitIconPositions { return if (Flags.enableOverviewIconMenu()) { if (isRtl) { SplitIconPositions( topLeftY = totalThumbnailHeight - primarySnapshotHeight, - bottomRightY = 0 + bottomRightY = 0, ) } else { SplitIconPositions( topLeftY = 0, - bottomRightY = -(primarySnapshotHeight + dividerSize) + bottomRightY = -(primarySnapshotHeight + dividerSize), ) } } else { @@ -372,10 +373,19 @@ class SeascapePagedViewHandler : LandscapePagedViewHandler() { // from the bottom to the almost-center of the screen using the bottom margin. // The primary snapshot is placed at the bottom, thus we translate the icons using // the size of the primary snapshot minus the icon size for the top-left icon. - SplitIconPositions( - topLeftY = primarySnapshotHeight - taskIconHeight, - bottomRightY = primarySnapshotHeight + dividerSize - ) + if (oneIconHiddenDueToSmallWidth) { + // Center both icons + val centerY = primarySnapshotHeight + ((dividerSize - taskIconHeight) / 2) + SplitIconPositions( + topLeftY = centerY, + bottomRightY = centerY, + ) + } else { + SplitIconPositions( + topLeftY = primarySnapshotHeight - taskIconHeight, + bottomRightY = primarySnapshotHeight + dividerSize, + ) + } } } diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt index 25011d784e..a8eee0a026 100644 --- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt +++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt @@ -187,14 +187,30 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu val taskIconHeight = deviceProfile.overviewTaskIconSizePx val isRtl = layoutDirection == LAYOUT_DIRECTION_RTL val inSplitSelection = getThisTaskCurrentlyInSplitSelection() != INVALID_TASK_ID + var oneIconHiddenDueToSmallWidth = false if (enableFlexibleTwoAppSplit()) { - val topLeftTaskPercent = splitBoundsConfig.leftTopTaskPercent - val bottomRightTaskPercent = splitBoundsConfig.rightBottomTaskPercent - val hideTopLeftIcon = topLeftTaskPercent < MINIMUM_RATIO_TO_SHOW_ICON - val hideBottomRightIcon = bottomRightTaskPercent < MINIMUM_RATIO_TO_SHOW_ICON - leftTopTaskContainer.iconView.setFlexSplitAlpha(if (hideTopLeftIcon) 0f else 1f) - rightBottomTaskContainer.iconView.setFlexSplitAlpha(if (hideBottomRightIcon) 0f else 1f) + // Update values for both icons' setFlexSplitAlpha. Mainly, we want to hide an icon if + // its app tile is too small. But we also have to set the alphas back if we go to + // split selection. + val hideLeftTopIcon: Boolean + val hideRightBottomIcon: Boolean + if (inSplitSelection) { + hideLeftTopIcon = + getThisTaskCurrentlyInSplitSelection() == splitBoundsConfig.leftTopTaskId + hideRightBottomIcon = + getThisTaskCurrentlyInSplitSelection() == splitBoundsConfig.rightBottomTaskId + } else { + hideLeftTopIcon = splitBoundsConfig.leftTopTaskPercent < MINIMUM_RATIO_TO_SHOW_ICON + hideRightBottomIcon = + splitBoundsConfig.rightBottomTaskPercent < MINIMUM_RATIO_TO_SHOW_ICON + if (hideLeftTopIcon || hideRightBottomIcon) { + oneIconHiddenDueToSmallWidth = true + } + } + + leftTopTaskContainer.iconView.setFlexSplitAlpha(if (hideLeftTopIcon) 0f else 1f) + rightBottomTaskContainer.iconView.setFlexSplitAlpha(if (hideRightBottomIcon) 0f else 1f) } if (enableOverviewIconMenu()) { @@ -217,6 +233,7 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu deviceProfile, splitBoundsConfig, inSplitSelection, + oneIconHiddenDueToSmallWidth, ) } else { pagedOrientationHandler.setSplitIconParams( @@ -231,6 +248,7 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu deviceProfile, splitBoundsConfig, inSplitSelection, + oneIconHiddenDueToSmallWidth, ) } } diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/LandscapePagedViewHandlerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/LandscapePagedViewHandlerTest.kt index ea52842e22..0570c26eed 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/LandscapePagedViewHandlerTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/LandscapePagedViewHandlerTest.kt @@ -62,6 +62,7 @@ class LandscapePagedViewHandlerTest { isRTL, OVERVIEW_TASK_MARGIN_PX, DIVIDER_SIZE_PX, + oneIconHiddenDueToSmallWidth = false, ) } diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/SeascapePagedViewHandlerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/SeascapePagedViewHandlerTest.kt index 2bc182c02d..37886888ea 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/SeascapePagedViewHandlerTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/SeascapePagedViewHandlerTest.kt @@ -62,6 +62,7 @@ class SeascapePagedViewHandlerTest { isRTL, OVERVIEW_TASK_MARGIN_PX, DIVIDER_SIZE_PX, + oneIconHiddenDueToSmallWidth = false, ) }