car icons: drop app tints that can't be seen, mark MAPS.ME and MapQuest as working

MAPS.ME tints its map buttons dark grey for dark mode, which vanished on Gearslip's
dark buttons. A tint below 3:1 contrast now falls back to the normal text colour,
as Android Auto does.
This commit is contained in:
Seb3thehacker committed 2026-10-09 15:26:48 -07:00
1 parent 179a51ea25
commit 75dfaa3013
2 files changed
+17 -2

No files matched your search

@@ -5,6 +5,7 @@ import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalContentColor
import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.luminance
import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -468,7 +469,10 @@ internal fun CarGlyph(icon: CarIcon?, modifier: Modifier = Modifier, standard: I
val white = remember(bitmap) { bitmap.isPlainWhite() } val white = remember(bitmap) { bitmap.isPlainWhite() }
// Untinted white artwork is a template-app habit from dark surfaces; it is coloured like // Untinted white artwork is a template-app habit from dark surfaces; it is coloured like
// text so it stays readable on a light one. // text so it stays readable on a light one.
val tint = icon?.tint?.color(dark, content) ?: content.takeIf { white } // An app's own tint is kept only if it can be seen: MAPS.ME asks for dark grey on dark
// buttons. Android Auto drops colours that fail contrast the same way.
val tint = icon?.tint?.color(dark, content)?.takeIf { it.readableOn(content) }
?: content.takeIf { white || icon?.tint != null }
Image( Image(
bitmap, contentDescription = null, modifier = modifier, bitmap, contentDescription = null, modifier = modifier,
colorFilter = tint?.let { ColorFilter.tint(it) }, colorFilter = tint?.let { ColorFilter.tint(it) },
@@ -661,6 +665,17 @@ internal fun RowItem(row: CarRow, selection: RowSelection? = null, large: Boolea
/** A row's place in a single-choice list: whether it is the chosen one, and what picking it does. */ /** A row's place in a single-choice list: whether it is the chosen one, and what picking it does. */
internal class RowSelection(val selected: Boolean, val onPick: () -> Unit) internal class RowSelection(val selected: Boolean, val onPick: () -> Unit)
/**
* Whether this colour stands out against the background that [content] was chosen for: at least
* 3:1, the WCAG minimum for icons. The background is taken as the opposite of the content colour.
*/
private fun Color.readableOn(content: Color): Boolean {
val background = if (content.luminanceIsDark()) Color.White else Color(0xFF121212)
val a = luminance() + 0.05f
val b = background.luminance() + 0.05f
return maxOf(a, b) / minOf(a, b) >= 3f
}
internal fun Color.luminanceIsDark(): Boolean = internal fun Color.luminanceIsDark(): Boolean =
(red * 0.299f + green * 0.587f + blue * 0.114f) < 0.5f (red * 0.299f + green * 0.587f + blue * 0.114f) < 0.5f
@@ -19,6 +19,7 @@ object KnownApps {
"com.metrolist.music", // Metrolist: browse, play, works "com.metrolist.music", // Metrolist: browse, play, works
"nl.flitsmeister", // Flitsmeister: map, routing, alerts - works well "nl.flitsmeister", // Flitsmeister: map, routing, alerts - works well
"com.mapquest.android.ace", // MapQuest: map, routing, navigation "com.mapquest.android.ace", // MapQuest: map, routing, navigation
"com.mapswithme.maps.pro", // MAPS.ME: map, search, place pages, navigation
) )
fun works(packageName: String): Boolean = packageName in working fun works(packageName: String): Boolean = packageName in working
@@ -72,7 +73,6 @@ object KnownApps {
*/ */
private val partial = setOf( private val partial = setOf(
"app.vela", // Vela Maps: connects and draws, but rough enough not to call it working yet "app.vela", // Vela Maps: connects and draws, but rough enough not to call it working yet
"com.mapquest.android.ace", // MapQuest: map, search and routing run, but not cleanly
"com.spotify.music", // Spotify: plays through Gearslip's player, but the app has to be opened on the phone first "com.spotify.music", // Spotify: plays through Gearslip's player, but the app has to be opened on the phone first
"deezer.android.app", // Deezer: the same - it has to be opened on the phone first "deezer.android.app", // Deezer: the same - it has to be opened on the phone first
) )