From 4970befcdc4afd6a661eaf548556fe45eeade484 Mon Sep 17 00:00:00 2001 From: Jagrut Desai Date: Fri, 13 Jun 2025 11:03:38 -0700 Subject: [PATCH] Fix Taskbar Icon going beyond screen The problem: Currently, when users increases font size to fullest and also display size to fullest, taskbar icons goes beyond screen. The isssue is event worst when there is bubble bar present in the Taskbar. This is currently a problem with 3 button nav button. The Solution: The solution is in two parts. Part 1: figure out amount of icons we need to remove from hotseat for the taskbar icons to not got beyond screen and not collide with nav buttons or bubble bar. Part 2: Once we figure out how many icon we need to not show in takbar which are present in the hotseat, we need to modify the takbar icon alignment controlled to modify alpha animation and eventually the visibility of those taksbar views. We also need to modify taskbar icon layout logic so that we don't take space for invisible taksbar icons and we layout next visible icon on the place of invisible icons. Test: Manual, Presubmit Bug: 412835965 Flag: EXEMPT bugfix (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8def3264e3f4fa3a2354dfa693751ea3d5f33f36) Merged-In: I8dea948df09c0a86871a9ac649f312ecf281545a Change-Id: I8dea948df09c0a86871a9ac649f312ecf281545a --- .../launcher3/taskbar/TaskbarView.java | 92 ++++++++++++++++++- .../taskbar/TaskbarViewController.java | 20 +++- 2 files changed, 107 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index e22bad7109..409885dca8 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -115,6 +115,14 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar private int mNextViewIndex; + public int getIgnoreTaskbarIconCount() { + return mIgnoreTaskbarIconCount; + } + + // TODO: clean it up in follow up cl with removal of taskbar icon alignment. + // Only used for edge of 3 button navigation mode, where we need to hide icons which go + // beyond the bounds. + private int mIgnoreTaskbarIconCount = 0; /** * Whether the divider is between Hotseat icons and Recents, * instead of between All Apps button and Hotseat. @@ -435,6 +443,9 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar } removeView(mQsb); + mIgnoreTaskbarIconCount = getIgnoreCountForTaskbarIcons(recentTasks.size(), + hotseatItemInfos.length); + updateHotseatItems(hotseatItemInfos); if (mTaskbarDividerContainer != null && !recentTasks.isEmpty()) { @@ -472,6 +483,9 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar mNextViewIndex++; } + mIgnoreTaskbarIconCount = getIgnoreCountForTaskbarIcons(recentTasks.size(), + hotseatItemInfos.length); + // Update left section. if (mIsRtl) { updateRecents(recentTasks.reversed(), hotseatItemInfos.length); @@ -542,6 +556,53 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar return mIsRtl ? getChildCount() - mNumStaticViews - 1 : mNumStaticViews; } + /** + * Calculate how many icon we need to not show in Taskbar that are present in hotseat. + */ + private int getIgnoreCountForTaskbarIcons(int recentsIcons, int hotseatIcons) { + + if (!mActivityContext.isThreeButtonNav() + || mActivityContext.getTaskbarFeatureEvaluator().isRecentsEnabled()) { + return 0; + } + + DeviceProfile deviceProfile = mActivityContext.getDeviceProfile(); + + // Add icon for all apps. + int icons = 1; + + // Only include divider line in count if will be added to Taskbar view which is in + // conditions below. + if (mActivityContext.isInDesktopMode() && recentsIcons > 0) { + icons += 1; + } else if (recentsIcons + hotseatIcons != 0) { + icons += 1; + } + int spaceNeeded = getIconLayoutWidth(icons + recentsIcons + hotseatIcons); + + boolean areBubblesVisible = + mControllerCallbacks.isBubbleBarEnabled() && mBubbleBarLocation != null; + int screenWidth = this.getResources().getDisplayMetrics().widthPixels; + int navSpaceNeeded = deviceProfile.getHotseatProfile().getBarEndOffset(); + + int ignoreCount = 0; + //Screen Width - nav space + int amountOfSpaceTaskbarIconsCanHave = screenWidth - navSpaceNeeded; + if (areBubblesVisible) { + // size of bubbles Icon and margin on the side. + int bubbleBarMargin = getResources().getDimensionPixelSize( + R.dimen.transient_taskbar_bottom_margin); + amountOfSpaceTaskbarIconsCanHave -= (mIconTouchSize + bubbleBarMargin); + } + int taskbarIconSpaceNeeded = spaceNeeded; + while (amountOfSpaceTaskbarIconsCanHave < taskbarIconSpaceNeeded) { + ignoreCount++; + int iconSpace = mIconTouchSize + (2 * mItemMarginLeftRight); + taskbarIconSpaceNeeded -= iconSpace; + } + return ignoreCount; + } + private void updateHotseatItems(ItemInfo[] hotseatItemInfos) { int numViewsAnimated = 0; @@ -832,7 +893,15 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar return 0; } Rect iconsBounds = getTransientTaskbarIconLayoutBoundsInParent(); - return getTaskBarIconsEndForBubbleBarLocation(location) - iconsBounds.right; + + int translateXFromIgnoredIcons = + mIgnoreTaskbarIconCount * (mIconTouchSize + mItemMarginLeftRight); + // If bubble bar or right translate in opposite direction. + if (!location.isOnLeft(isLayoutRtl())) { + translateXFromIgnoredIcons *= -1; + } + return getTaskBarIconsEndForBubbleBarLocation(location) - iconsBounds.right + + translateXFromIgnoredIcons; } @Override @@ -907,6 +976,16 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar iconEnd += mAllAppsButtonTranslationOffset; } + if (mActivityContext.isThreeButtonNav()) { + boolean navbarOnLeft = mBubbleBarLocation != null && !mBubbleBarLocation.isOnLeft( + layoutRtl); + if (navbarOnLeft && layoutRtl) { + iconEnd -= (mIconTouchSize + mItemMarginLeftRight) * mIgnoreTaskbarIconCount; + } else if (!navbarOnLeft && !layoutRtl) { + iconEnd += (mIconTouchSize + mItemMarginLeftRight) * mIgnoreTaskbarIconCount; + } + } + mControllerCallbacks.onPreLayoutChildren(); int count = getChildCount(); @@ -1009,10 +1088,17 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar } /** - * Returns the space used by the icons + * Returns the space used by the icons. */ private int getIconLayoutWidth() { - int countExcludingQsb = getChildCount(); + return getIconLayoutWidth(getChildCount()); + } + + /** + * Return the space needed based on the number of taskbar icons supplied vs existing children. + */ + private int getIconLayoutWidth(int expectedNumberOfTaskbarIcons) { + int countExcludingQsb = expectedNumberOfTaskbarIcons; DeviceProfile deviceProfile = mActivityContext.getDeviceProfile(); if (deviceProfile.isQsbInline) { countExcludingQsb--; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 1a2a977c11..afcbc852c3 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -94,6 +94,7 @@ import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.launcher3.util.MultiTranslateDelegate; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.SandboxContext; +import com.android.launcher3.views.IconButtonView; import com.android.quickstep.util.GroupTask; import com.android.quickstep.util.SingleTask; import com.android.systemui.shared.recents.model.Task; @@ -1039,12 +1040,17 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar hotseatNavBarTranslationX = taskbarDp .getHotseatTranslationXForNavBar(mActivity, isBubblesOnLeft); } + + int ignoreCount = mTaskbarView.getIgnoreTaskbarIconCount(); + for (int i = 0; i < mTaskbarView.getChildCount(); i++) { View child = mTaskbarView.getChildAt(i); boolean isAllAppsButton = child == mTaskbarView.getAllAppsButtonContainer(); boolean isTaskbarDividerView = child == mTaskbarView.getTaskbarDividerViewContainer(); boolean isTaskbarOverflowView = child == mTaskbarView.getTaskbarOverflowView(); boolean isRecentTask = child.getTag() instanceof GroupTask; + boolean isRtl = Utilities.isRtl(child.getResources()); + // TODO(b/343522351): show recents on the home screen. final boolean isRecentsInHotseat = false; if (!mIsHotseatIconOnTopWhenAligned) { @@ -1073,9 +1079,19 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar ? Interpolators.clampToProgress(LINEAR, 0f, 0.17f) : Interpolators.clampToProgress(LINEAR, 0.72f, 0.84f)); } + } else if (((!isRtl && mTaskbarView.getChildCount() - i <= ignoreCount) + || (isRtl && i < ignoreCount)) + && mIsHotseatIconOnTopWhenAligned + && !(child instanceof IconButtonView)) { + setter.addFloat(child, VIEW_ALPHA, 0f, 1f, + isToHome + ? Interpolators.clampToProgress(LINEAR, 0f, 0.35f) + : mActivity.getDeviceProfile().isQsbInline + ? Interpolators.clampToProgress(LINEAR, 0f, 1f) + : Interpolators.clampToProgress(LINEAR, 0.84f, 1f)); + setter.addOnFrameListener(animator -> AlphaUpdateListener.updateVisibility(child)); } if (child == mTaskbarView.getQsb()) { - boolean isRtl = Utilities.isRtl(child.getResources()); float hotseatIconCenter = isRtl ? launcherDp.getDeviceProperties().getWidthPx() - hotseatPadding.right + borderSpacing + launcherDp.hotseatQsbWidth / 2f @@ -1392,7 +1408,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar @Override public void dumpLogs(String prefix, PrintWriter pw) { pw.println(prefix + "TaskbarViewController:"); - + pw.println(prefix + "\tignoreTaskbarIconCount=" + mTaskbarView.getIgnoreTaskbarIconCount()); mTaskbarIconAlpha.dump( prefix + "\t", pw,