fix: Link app drawer background opacity to correct colors (#6636)

Signed-off-by: Pun Butrach <pun.butrach@gmail.com>
This commit is contained in:
Pun Butrach authored and GitHub committed 2026-05-10 20:05:50 +08:00
1 parent b8066dc7e4
commit 0bd70f3bd0
5 files changed
+112 -43

No files matched your search

@@ -42,18 +42,22 @@ import android.util.Log
import android.util.Size import android.util.Size
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.compose.ui.util.lerp
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.core.graphics.createBitmap import androidx.core.graphics.createBitmap
import androidx.core.graphics.luminance
import androidx.core.os.UserManagerCompat import androidx.core.os.UserManagerCompat
import app.lawnchair.preferences.PreferenceManager import app.lawnchair.preferences.PreferenceManager
import app.lawnchair.preferences2.PreferenceManager2 import app.lawnchair.preferences2.PreferenceManager2
import app.lawnchair.theme.color.ColorOption import app.lawnchair.theme.color.ColorOption
import app.lawnchair.theme.color.tokens.ColorTokens import app.lawnchair.theme.color.tokens.ColorTokens
import com.android.launcher3.BaseActivity
import com.android.launcher3.BuildConfig import com.android.launcher3.BuildConfig
import com.android.launcher3.R import com.android.launcher3.R
import com.android.launcher3.Utilities import com.android.launcher3.Utilities
import com.android.launcher3.util.Executors.MAIN_EXECUTOR import com.android.launcher3.util.Executors.MAIN_EXECUTOR
import com.android.launcher3.util.Themes import com.android.launcher3.util.Themes
import com.android.launcher3.views.ActivityContext
import com.android.systemui.shared.system.QuickStepContract import com.android.systemui.shared.system.QuickStepContract
import com.patrykmichalik.opto.core.firstBlocking import com.patrykmichalik.opto.core.firstBlocking
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
@@ -145,8 +149,9 @@ fun supportsRoundedCornersOnWindows(context: Context): Boolean {
fun overrideAllAppsTextColor(textView: TextView) { fun overrideAllAppsTextColor(textView: TextView) {
val context = textView.context val context = textView.context
val luminance = getAllAppsBaseColor(context, ColorTokens.AllAppsScrimColor.resolveColor(context)).luminance
val opacity = PreferenceManager.getInstance(context).drawerOpacity.get() val opacity = PreferenceManager.getInstance(context).drawerOpacity.get()
if (opacity <= 0.3f) { if (luminance > 0.5f || opacity <= 0.3f) {
textView.setTextColor(Themes.getAttrColor(context, R.attr.allAppsAlternateTextColor)) textView.setTextColor(Themes.getAttrColor(context, R.attr.allAppsAlternateTextColor))
} }
} }
@@ -180,17 +185,20 @@ fun getFolderBackgroundAlpha(context: Context): Int {
return (prefs2.folderBackgroundOpacity.firstBlocking() * 255).toInt() return (prefs2.folderBackgroundOpacity.firstBlocking() * 255).toInt()
} }
fun getAllAppsScrimColor(context: Context): Int { /** Apply Lawnchair custom allapps colour to the provided colour */
val opacity = PreferenceManager.getInstance(context).drawerOpacity.get() private fun getAllAppsBaseColor(context: Context, defaultColor: Int): Int {
val prefs2 = PreferenceManager2.getInstance(context) val prefs2 = PreferenceManager2.getInstance(context)
var scrimColor = ColorTokens.AllAppsScrimColor.resolveColor(context)
val colorOptions: ColorOption = prefs2.appDrawerBackgroundColor.firstBlocking() val colorOptions: ColorOption = prefs2.appDrawerBackgroundColor.firstBlocking()
val color = colorOptions.colorPreferenceEntry.lightColor.invoke(context) val color = colorOptions.colorPreferenceEntry.lightColor.invoke(context)
if (color != 0) { val baseColor = if (color != 0) color else defaultColor
scrimColor = color return ColorUtils.setAlphaComponent(baseColor, 255)
} }
val alpha = (opacity * 255).roundToInt()
return ColorUtils.setAlphaComponent(scrimColor, alpha) /** Apply Lawnchair custom allapps opacity and colour to the provided colour */
fun getAllAppsBackgroundColor(context: Context, defaultColor: Int): Int {
val prefs = PreferenceManager.getInstance(context)
val userOpacity = prefs.drawerOpacity.get()
return ColorUtils.setAlphaComponent(getAllAppsBaseColor(context, defaultColor), (userOpacity * 255).roundToInt())
} }
fun Context.checkPackagePermission(packageName: String, permissionName: String): Boolean { fun Context.checkPackagePermission(packageName: String, permissionName: String): Boolean {
@@ -280,13 +280,13 @@ public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarOverla
protected int getScrimColor(Context context) { protected int getScrimColor(Context context) {
if (!mActivityContext.getDeviceProfile().shouldShowAllAppsOnSheet()) { if (!mActivityContext.getDeviceProfile().shouldShowAllAppsOnSheet()) {
// Always use an opaque scrim if there's no sheet. // Always use an opaque scrim if there's no sheet.
// Lawnchair-TODO-Colour: Check R.color.materialColorSurfaceDim return ColorTokens.AllAppsScrimColor.resolveColor(context);
return context.getResources().getColor(R.color.materialColorSurfaceDim);
} else if (!Flags.allAppsBlur()) { } else if (!Flags.allAppsBlur()) {
// If there's a sheet but no blur, use the old scrim color. // If there's a sheet but no blur, use the old scrim color.
return ColorTokens.WidgetsPickerScrim.resolveColor(context); return LawnchairUtilsKt.getAllAppsBackgroundColor(context,
ColorTokens.WidgetsPickerScrim.resolveColor(context));
} }
return LawnchairUtilsKt.getAllAppsScrimColor(context); return ColorTokens.AllAppsScrimColor.resolveColor(context);
} }
@Override @Override
@@ -29,7 +29,6 @@ import com.android.launcher3.Flags;
import com.android.launcher3.Launcher; import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherState;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.ScrimColors; import com.android.launcher3.views.ScrimColors;
import com.android.quickstep.util.BaseDepthController; import com.android.quickstep.util.BaseDepthController;
@@ -37,7 +36,6 @@ import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import app.lawnchair.LawnchairLauncher;
import app.lawnchair.util.LawnchairUtilsKt; import app.lawnchair.util.LawnchairUtilsKt;
/** /**
@@ -213,12 +211,13 @@ public class AllAppsState extends LauncherState {
int backgroundColor; int backgroundColor;
if (!launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) { if (!launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) {
// Always use an opaque scrim if there's no sheet. // Always use an opaque scrim if there's no sheet.
backgroundColor = ColorTokens.SurfaceDimColor.resolveColor(launcher); backgroundColor = ColorTokens.AllAppsScrimColor.resolveColor(launcher);
} else if (!Flags.allAppsBlur()) { } else if (!Flags.allAppsBlur()) {
// If there's a sheet but no blur, use the old scrim color. // If there's a sheet but no blur, use the old scrim color.
backgroundColor = ColorTokens.WidgetsPickerScrim.resolveColor(launcher); backgroundColor = LawnchairUtilsKt.getAllAppsBackgroundColor(launcher,
ColorTokens.WidgetsPickerScrim.resolveColor(launcher));
} else { } else {
backgroundColor = LawnchairUtilsKt.getAllAppsScrimColor(launcher); backgroundColor = ColorTokens.AllAppsScrimColor.resolveColor(launcher);
} }
return new ScrimColors(backgroundColor, /* foregroundColor */ Color.TRANSPARENT); return new ScrimColors(backgroundColor, /* foregroundColor */ Color.TRANSPARENT);
} }
@@ -26,6 +26,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.ScrollableLayoutManager.PREDICTIVE_BACK_MIN_SCALE; import static com.android.launcher3.util.ScrollableLayoutManager.PREDICTIVE_BACK_MIN_SCALE;
import static com.android.launcher3.views.RecyclerViewFastScroller.FastScrollerLocation.ALL_APPS_SCROLLER; import static com.android.launcher3.views.RecyclerViewFastScroller.FastScrollerLocation.ALL_APPS_SCROLLER;
import static com.android.window.flags2.Flags.predictiveBackThreeButtonNav; import static com.android.window.flags2.Flags.predictiveBackThreeButtonNav;
@@ -50,6 +51,7 @@ import android.os.UserManager;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.CrossWindowBlurListeners;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
@@ -57,6 +59,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewOutlineProvider; import android.view.ViewOutlineProvider;
import android.view.WindowInsets; import android.view.WindowInsets;
import android.view.WindowManager;
import android.widget.Button; import android.widget.Button;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
@@ -66,6 +69,7 @@ import androidx.annotation.Px;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils;
import androidx.core.util.Consumer; import androidx.core.util.Consumer;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@@ -114,6 +118,7 @@ import app.lawnchair.font.FontManager;
import app.lawnchair.preferences.PreferenceManager; import app.lawnchair.preferences.PreferenceManager;
import app.lawnchair.preferences2.PreferenceManager2; import app.lawnchair.preferences2.PreferenceManager2;
import app.lawnchair.theme.color.tokens.ColorTokens; import app.lawnchair.theme.color.tokens.ColorTokens;
import app.lawnchair.util.LawnchairUtilsKt;
import app.lawnchair.ui.StretchRecyclerViewContainer; import app.lawnchair.ui.StretchRecyclerViewContainer;
/** /**
@@ -199,9 +204,14 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
private int mTabsProtectionAlpha; private int mTabsProtectionAlpha;
@Nullable private AllAppsTransitionController mAllAppsTransitionController; @Nullable private AllAppsTransitionController mAllAppsTransitionController;
@Nullable private java.util.function.Consumer<Boolean> mCrossWindowBlurListener;
private final PreferenceManager2 pref2; private final PreferenceManager2 pref2;
private final PreferenceManager pref; private final PreferenceManager pref;
// LC-Note: Allapps cache colour
private int mCachedBottomSheetBgColor;
public ActivityAllAppsContainerView(Context context) { public ActivityAllAppsContainerView(Context context) {
this(context, null); this(context, null);
} }
@@ -346,6 +356,9 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
mBottomSheetBackgroundColorLegacy = ColorTokens.SurfaceDimColor.resolveColor(getContext()); mBottomSheetBackgroundColorLegacy = ColorTokens.SurfaceDimColor.resolveColor(getContext());
// LC-Note: Update our allapps cached colour
updateBottomSheetBackgroundColor();
updateBackgroundVisibility(mActivityContext.getDeviceProfile()); updateBackgroundVisibility(mActivityContext.getDeviceProfile());
mSearchUiManager.initializeSearch(this); mSearchUiManager.initializeSearch(this);
} }
@@ -354,19 +367,44 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
protected void onAttachedToWindow() { protected void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
if (isSearchBarFloating()) { if (isSearchBarFloating()) {
// Note: for Taskbar this is removed in TaskbarAllAppsController#cleanUpOverlay when the
// panel is closed. Can't do so in onDetach because we are also a child of drag layer
// so can't remove its views during that dispatch.
mActivityContext.getDragLayer().addView(mSearchContainer); mActivityContext.getDragLayer().addView(mSearchContainer);
mSearchUiDelegate.onInitializeSearchBar(); mSearchUiDelegate.onInitializeSearchBar();
} }
mActivityContext.addOnDeviceProfileChangeListener(this); mActivityContext.addOnDeviceProfileChangeListener(this);
if (Utilities.ATLEAST_S) {
java.util.function.Consumer<Boolean> listener = enabled -> {
if (updateBottomSheetBackgroundColor(enabled)) {
invalidate();
}
};
mCrossWindowBlurListener = listener;
UI_HELPER_EXECUTOR.execute(() -> {
try {
CrossWindowBlurListeners.getInstance()
.addListener(MAIN_EXECUTOR, listener);
} catch (Throwable t) {
// LC-Ignored
}
});
}
} }
@Override @Override
protected void onDetachedFromWindow() { protected void onDetachedFromWindow() {
super.onDetachedFromWindow(); super.onDetachedFromWindow();
mActivityContext.removeOnDeviceProfileChangeListener(this); mActivityContext.removeOnDeviceProfileChangeListener(this);
if (mCrossWindowBlurListener != null) {
java.util.function.Consumer<Boolean> listener = mCrossWindowBlurListener;
UI_HELPER_EXECUTOR.execute(() -> {
try {
CrossWindowBlurListeners.getInstance()
.removeListener(listener);
} catch (Throwable t) {
// LC-Ignored
}
});
mCrossWindowBlurListener = null;
}
} }
public SearchUiManager getSearchUiManager() { public SearchUiManager getSearchUiManager() {
@@ -864,22 +902,17 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
} }
protected int getHeaderColor(float blendRatio) { protected int getHeaderColor(float blendRatio) {
float opacity = 0.0f;
var showHeaderBackground = PreferenceExtensionsKt.firstBlocking(
pref2.getAppDrawerSearchBarBackground());
if (showHeaderBackground) {
opacity = pref.getDrawerOpacity().get();
}
var colorOptions = PreferenceExtensionsKt.firstBlocking(pref2.getAppDrawerBackgroundColor());
var color = colorOptions.getColorPreferenceEntry().getLightColor().invoke(mActivityContext);
if (color != 0) {
mScrimColor = color;
}
if (!mActivityContext.getDeviceProfile().shouldShowAllAppsOnSheet()) { if (!mActivityContext.getDeviceProfile().shouldShowAllAppsOnSheet()) {
float opacity = mSearchContainer.getAlpha();
var showHeaderBackground = PreferenceExtensionsKt.firstBlocking(
pref2.getAppDrawerSearchBarBackground());
if (showHeaderBackground) {
opacity = pref.getDrawerOpacity().get();
}
opacity = MathUtils.clamp(opacity, 0f, 1f);
return ColorUtils.setAlphaComponent( return ColorUtils.setAlphaComponent(
ColorUtils.blendARGB(mScrimColor, mHeaderProtectionColor, blendRatio), ColorUtils.blendARGB(getBackgroundColor(), mHeaderProtectionColor, blendRatio),
(int) (opacity * 255)); Math.round(opacity * 255));
} }
return isBackgroundBlurEnabled() return isBackgroundBlurEnabled()
? ColorUtils.setAlphaComponent(mHeaderProtectionColor, (int) (blendRatio * 255)) ? ColorUtils.setAlphaComponent(mHeaderProtectionColor, (int) (blendRatio * 255))
@@ -891,15 +924,32 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
? getBottomSheetBackgroundColor() : mScrimColor; ? getBottomSheetBackgroundColor() : mScrimColor;
} }
// LC-Note: Hey! We cache this! see updateBottomSheetBackgroundColor() for more details.
int getBottomSheetBackgroundColor() { int getBottomSheetBackgroundColor() {
return mCachedBottomSheetBgColor;
}
// LC-Note: This is getBottomSheetBackgroundColor() in AOSP, but we refactor it to cache our prefs.
private boolean updateBottomSheetBackgroundColor() {
return updateBottomSheetBackgroundColor(mActivityContext.isAllAppsBackgroundBlurEnabled());
}
// LC-Note: For listener to avoid querying stale value.
private boolean updateBottomSheetBackgroundColor(boolean blurEnabled) {
int defaultColor;
if (!Flags.allAppsBlur()) { if (!Flags.allAppsBlur()) {
return mBottomSheetBackgroundColorLegacy; defaultColor = mBottomSheetBackgroundColorLegacy;
} else if (!blurEnabled) {
defaultColor = mBottomSheetBackgroundColorBlurFallback;
} else {
defaultColor = mBottomSheetBackgroundColorOverBlur;
} }
if (!mActivityContext.isAllAppsBackgroundBlurEnabled()) { int newColor = LawnchairUtilsKt.getAllAppsBackgroundColor(mActivityContext, defaultColor);
// Don't apply any alpha if the blur is disabled. if (mCachedBottomSheetBgColor != newColor) {
return mBottomSheetBackgroundColorBlurFallback; mCachedBottomSheetBgColor = newColor;
return true;
} }
return mBottomSheetBackgroundColorOverBlur; return false;
} }
boolean isBackgroundBlurEnabled() { boolean isBackgroundBlurEnabled() {
@@ -1095,9 +1145,18 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
} }
updateBackgroundVisibility(dp); updateBackgroundVisibility(dp);
boolean needsInvalidate = false;
int navBarScrimColor = Themes.getNavBarScrimColor(mActivityContext); int navBarScrimColor = Themes.getNavBarScrimColor(mActivityContext);
if (mNavBarScrimPaint.getColor() != navBarScrimColor) { if (mNavBarScrimPaint.getColor() != navBarScrimColor) {
mNavBarScrimPaint.setColor(navBarScrimColor); mNavBarScrimPaint.setColor(navBarScrimColor);
needsInvalidate = true;
}
// LC-Note: Update our allapps cached colour
if (updateBottomSheetBackgroundColor()) {
needsInvalidate = true;
}
if (needsInvalidate) {
invalidate(); invalidate();
} }
} }
@@ -19,10 +19,12 @@ import static com.android.app.animation.Interpolators.DECELERATE;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
import android.graphics.Color; import android.graphics.Color;
import app.lawnchair.theme.color.tokens.ColorTokens;
import app.lawnchair.util.LawnchairUtilsKt;
import com.android.launcher3.Launcher; import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherState;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.ScrimColors; import com.android.launcher3.views.ScrimColors;
@@ -101,8 +103,9 @@ public class AllAppsState extends LauncherState {
public ScrimColors getWorkspaceScrimColor(Launcher launcher) { public ScrimColors getWorkspaceScrimColor(Launcher launcher) {
return new ScrimColors( return new ScrimColors(
/* backgroundColor */ launcher.getDeviceProfile().getDeviceProperties().isTablet() /* backgroundColor */ launcher.getDeviceProfile().getDeviceProperties().isTablet()
? launcher.getResources().getColor(R.color.widgets_picker_scrim) ? LawnchairUtilsKt.getAllAppsBackgroundColor(launcher,
: Themes.getAttrColor(launcher, R.attr.allAppsScrimColor), ColorTokens.WidgetsPickerScrim.resolveColor(launcher))
: ColorTokens.AllAppsScrimColor.resolveColor(launcher),
/* foregroundColor */ Color.TRANSPARENT); /* foregroundColor */ Color.TRANSPARENT);
} }
} }