From be92ff0b3dc0586d485ef83c37a4bee8fa40707e Mon Sep 17 00:00:00 2001 From: Seb3thehacker Date: Thu, 5 Nov 2026 17:48:14 -0800 Subject: [PATCH] Car apps opened from the launcher show no back arrow on their first screen, where the close button already is --- .../java/app/seb3thehacker/gearslip/car/TemplateParts.kt | 4 ++++ .../app/seb3thehacker/gearslip/host/CarAppConnection.kt | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/TemplateParts.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/TemplateParts.kt index 0cfbbd9..c583221 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/TemplateParts.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/TemplateParts.kt @@ -363,6 +363,10 @@ internal fun ActionButton(action: Action, large: Boolean = false, modifier: Modi AppIconBadge() return } + // On an app's first screen, opened from the launcher, Gearslip's own close button is already + // the way out; a back arrow beside it did the same thing twice. Deeper in, it stays. + val atRoot by connection.atRoot.collectAsState() + if (action.type == Action.TYPE_BACK && atRoot && connection === CarServices.browse) return val dark = MaterialTheme.colorScheme.surface.luminanceIsDark() val title = action.title.text() val panOn by connection.panMode.collectAsState() diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/host/CarAppConnection.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/host/CarAppConnection.kt index 6c14bb9..ca82185 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/host/CarAppConnection.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/host/CarAppConnection.kt @@ -451,12 +451,19 @@ class CarAppConnection(private val context: Context, private val session: Sessio return@call } GearslipLog.i("host: template = ${template.javaClass.simpleName}") + // The app's ScreenManager lists every screen on its stack; one or none is its first. + _atRoot.value = ((value as? TemplateWrapper)?.templateInfosForScreenStack?.size ?: 1) <= 1 _template.value = template update { it.copy(template = template.javaClass.simpleName) } autoRoute.onTemplate(template) }) { manager.getTemplate(it) } } + private val _atRoot = MutableStateFlow(true) + + /** True while the app shows its first screen, where its own back would only close it. */ + val atRoot: StateFlow = _atRoot + private val _panMode = MutableStateFlow(false) /**