Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f9f540f authored by Daichi Hirono's avatar Daichi Hirono
Browse files

Fixes the hover color of app header buttons

Previously, header buttons used RippleDrawable for their background.
This prevented setting a specific hover background color, as
RippleDrawable automatically uses a 20% alpha version of the ripple
color for hover effects.

This change replaces RippleDrawable with ShapeDrawable, which allows the
desired hover background color to be set.

Video: http://recall/-/dvR0xNyCWFr2PAfPfPhsQ6/dW9qniSJcukXo9lWR3Xquq
Test: None
Flag: com.android.window.flags.enable_desktop_windowing_mode
Bug: 365121303
Change-Id: I43e3ac4adc95956b49916355d297b8c78f3abc86
parent e6ee377e
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ import android.annotation.DrawableRes
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.RippleDrawable
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
@@ -30,11 +30,11 @@ import android.view.ViewStub
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.ProgressBar
import android.window.DesktopModeFlags
import androidx.core.animation.doOnEnd
import androidx.core.animation.doOnStart
import androidx.core.content.ContextCompat
import com.android.wm.shell.R
import android.window.DesktopModeFlags

private const val OPEN_MAXIMIZE_MENU_DELAY_ON_HOVER_MS = 350
private const val MAX_DRAWABLE_ALPHA = 255
@@ -109,14 +109,14 @@ class MaximizeButtonView(context: Context, attrs: AttributeSet) : FrameLayout(co
        darkMode: Boolean,
        iconForegroundColor: ColorStateList? = null,
        baseForegroundColor: Int? = null,
        rippleDrawable: RippleDrawable? = null
        backgroundDrawable: Drawable? = null
    ) {
        if (DesktopModeFlags.ENABLE_THEMED_APP_HEADERS.isTrue()) {
            requireNotNull(iconForegroundColor) { "Icon foreground color must be non-null" }
            requireNotNull(baseForegroundColor) { "Base foreground color must be non-null" }
            requireNotNull(rippleDrawable) { "Ripple drawable must be non-null" }
            requireNotNull(backgroundDrawable) { "Background drawable must be non-null" }
            maximizeWindow.imageTintList = iconForegroundColor
            maximizeWindow.background = rippleDrawable
            maximizeWindow.background = backgroundDrawable
            stubProgressBarContainer.setOnInflateListener { _, inflated ->
                val progressBar = (inflated as FrameLayout)
                    .requireViewById(R.id.progress_bar) as ProgressBar
+34 −6
Original line number Diff line number Diff line
@@ -16,14 +16,13 @@
package com.android.wm.shell.windowdecor.common

import android.annotation.ColorInt
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.graphics.drawable.RippleDrawable
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RoundRectShape
import com.android.wm.shell.windowdecor.common.OPACITY_11
import com.android.wm.shell.windowdecor.common.OPACITY_15
import android.content.res.ColorStateList

/**
 * Represents drawable insets, specifying the number of pixels to inset a drawable from its bounds.
@@ -86,3 +85,32 @@ fun createRippleDrawable(
        }
    )
}

/**
 * Creates a background drawable with specified color, corner radius, and insets.
 */
fun createBackgroundDrawable(
    @ColorInt color: Int, cornerRadius: Int, drawableInsets: DrawableInsets
): Drawable = LayerDrawable(arrayOf(
    ShapeDrawable().apply {
        shape = RoundRectShape(
            FloatArray(8) { cornerRadius.toFloat() },
            /* inset= */ null,
            /* innerRadii= */ null
        )
        setTintList(ColorStateList(
            arrayOf(
                intArrayOf(android.R.attr.state_hovered),
                intArrayOf(android.R.attr.state_pressed),
            ),
            intArrayOf(
                replaceColorAlpha(color, OPACITY_11),
                replaceColorAlpha(color, OPACITY_15),
            )
        ))
    }
)).apply {
    require(numberOfLayers == 1) { "Must only contain one layer" }
    setLayerInset(/* index= */ 0,
        drawableInsets.l, drawableInsets.t, drawableInsets.r, drawableInsets.b)
}
+7 −12
Original line number Diff line number Diff line
@@ -23,10 +23,6 @@ import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Rect
import android.graphics.drawable.LayerDrawable
import android.graphics.drawable.RippleDrawable
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RoundRectShape
import android.os.Bundle
import android.view.View
import android.view.View.OnLongClickListener
@@ -55,14 +51,12 @@ import com.android.internal.R.color.materialColorSurfaceDim
import com.android.wm.shell.R
import com.android.wm.shell.windowdecor.MaximizeButtonView
import com.android.wm.shell.windowdecor.common.DecorThemeUtil
import com.android.wm.shell.windowdecor.common.DrawableInsets
import com.android.wm.shell.windowdecor.common.OPACITY_100
import com.android.wm.shell.windowdecor.common.OPACITY_11
import com.android.wm.shell.windowdecor.common.OPACITY_15
import com.android.wm.shell.windowdecor.common.OPACITY_55
import com.android.wm.shell.windowdecor.common.OPACITY_65
import com.android.wm.shell.windowdecor.common.Theme
import com.android.wm.shell.windowdecor.common.DrawableInsets
import com.android.wm.shell.windowdecor.common.createRippleDrawable
import com.android.wm.shell.windowdecor.common.createBackgroundDrawable
import com.android.wm.shell.windowdecor.extension.isLightCaptionBarAppearance
import com.android.wm.shell.windowdecor.extension.isTransparentCaptionBarAppearance

@@ -385,7 +379,7 @@ class AppHeaderViewHolder(
        val colorStateList = ColorStateList.valueOf(foregroundColor).withAlpha(foregroundAlpha)
        // App chip.
        openMenuButton.apply {
            background = createRippleDrawable(
            background = createBackgroundDrawable(
                color = foregroundColor,
                cornerRadius = headerButtonsRippleRadius,
                drawableInsets = appChipDrawableInsets,
@@ -396,11 +390,12 @@ class AppHeaderViewHolder(
                setTextColor(colorStateList)
            }
            appIconImageView.imageAlpha = foregroundAlpha
            defaultFocusHighlightEnabled = false
        }
        // Minimize button.
        minimizeWindowButton.apply {
            imageTintList = colorStateList
            background = createRippleDrawable(
            background = createBackgroundDrawable(
                color = foregroundColor,
                cornerRadius = headerButtonsRippleRadius,
                drawableInsets = minimizeDrawableInsets
@@ -413,7 +408,7 @@ class AppHeaderViewHolder(
                darkMode = header.appTheme == Theme.DARK,
                iconForegroundColor = colorStateList,
                baseForegroundColor = foregroundColor,
                rippleDrawable = createRippleDrawable(
                backgroundDrawable = createBackgroundDrawable(
                    color = foregroundColor,
                    cornerRadius = headerButtonsRippleRadius,
                    drawableInsets = maximizeDrawableInsets
@@ -451,7 +446,7 @@ class AppHeaderViewHolder(
        // Close button.
        closeWindowButton.apply {
            imageTintList = colorStateList
            background = createRippleDrawable(
            background = createBackgroundDrawable(
                color = foregroundColor,
                cornerRadius = headerButtonsRippleRadius,
                drawableInsets = closeDrawableInsets