From cd705961ca25a55a37173c29c103df491ac60747 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 2 Nov 2026 18:48:53 +0100 Subject: [PATCH] fix(appearance): a black navigation bar in the Black theme The tab bar sat on surfaceContainer, which the Black theme only dims, and the three-button scrim was the dark theme's grey. Both are black now, so the bottom of the screen is black down to the system bar (#28). --- .../de/jeanlucmakiola/clockula/MainActivity.kt | 14 ++++++++++---- .../clockula/ui/shell/ClockulaShell.kt | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/de/jeanlucmakiola/clockula/MainActivity.kt b/app/src/main/java/de/jeanlucmakiola/clockula/MainActivity.kt index d24f478..acba4ae 100644 --- a/app/src/main/java/de/jeanlucmakiola/clockula/MainActivity.kt +++ b/app/src/main/java/de/jeanlucmakiola/clockula/MainActivity.kt @@ -101,15 +101,17 @@ class MainActivity : ComponentActivity() { // flag: with the device dark and ThemeMode.LIGHT stored, deriving the // icon colours from the system would paint white icons onto a light // background. Re-applied whenever the stored preference changes. - LaunchedEffect(darkTheme) { applyEdgeToEdge(darkTheme) } + val pureBlack = darkTheme && appearance.themeMode.isPureBlack + LaunchedEffect(darkTheme, pureBlack) { applyEdgeToEdge(darkTheme, pureBlack) } ClockulaTheme( darkTheme = darkTheme, dynamicColor = appearance.dynamicColor, - pureBlack = appearance.themeMode.isPureBlack, + pureBlack = pureBlack, ) { ClockulaShell( modifier = Modifier.fillMaxSize(), + pureBlack = pureBlack, openRequest = openRequest, // Consumed once: a request left standing would re-select the // tab on every recomposition and fight the user's taps. @@ -136,10 +138,11 @@ class MainActivity : ComponentActivity() { } } - private fun applyEdgeToEdge(darkTheme: Boolean) { + private fun applyEdgeToEdge(darkTheme: Boolean, pureBlack: Boolean) { + val darkScrim = if (pureBlack) NAV_BAR_BLACK_SCRIM else NAV_BAR_DARK_SCRIM enableEdgeToEdge( statusBarStyle = SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT) { darkTheme }, - navigationBarStyle = SystemBarStyle.auto(NAV_BAR_LIGHT_SCRIM, NAV_BAR_DARK_SCRIM) { darkTheme }, + navigationBarStyle = SystemBarStyle.auto(NAV_BAR_LIGHT_SCRIM, darkScrim) { darkTheme }, ) } @@ -187,3 +190,6 @@ class MainActivity : ComponentActivity() { /** The scrims androidx uses for a three-button navigation bar, matched exactly. */ private val NAV_BAR_LIGHT_SCRIM = Color.argb(0xe6, 0xFF, 0xFF, 0xFF) private val NAV_BAR_DARK_SCRIM = Color.argb(0x80, 0x1b, 0x1b, 0x1b) + +/** The Black theme's: the dark one's alpha over black, so the bar reads black (#28). */ +private val NAV_BAR_BLACK_SCRIM = Color.argb(0x80, 0x00, 0x00, 0x00) diff --git a/app/src/main/java/de/jeanlucmakiola/clockula/ui/shell/ClockulaShell.kt b/app/src/main/java/de/jeanlucmakiola/clockula/ui/shell/ClockulaShell.kt index 713674a..bc2be7b 100644 --- a/app/src/main/java/de/jeanlucmakiola/clockula/ui/shell/ClockulaShell.kt +++ b/app/src/main/java/de/jeanlucmakiola/clockula/ui/shell/ClockulaShell.kt @@ -12,8 +12,10 @@ import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo +import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteDefaults import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteItem import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffoldDefaults @@ -77,10 +79,15 @@ import kotlin.math.sign * state is saveable, so the tab survives rotation and process death with no * mirror of ours to drift — and the `NavHost` holds only what is pushed over * the tabs: the editors, the timer setup page, Settings. + * + * With [pureBlack] the bar sits on the black ground rather than on + * `surfaceContainer`, so the bottom of the screen is black down to the + * system navigation bar (#28). */ @Composable fun ClockulaShell( modifier: Modifier = Modifier, + pureBlack: Boolean = false, openRequest: ShellRequest? = null, onRequestConsumed: () -> Unit = {}, viewModel: ShellViewModel = hiltViewModel(), @@ -192,6 +199,14 @@ fun ClockulaShell( enabled = back is ShellBackAction.GoTo, ), navigationSuiteType = navigationSuiteType, + navigationSuiteColors = if (pureBlack) { + NavigationSuiteDefaults.colors( + shortNavigationBarContainerColor = MaterialTheme.colorScheme.background, + navigationBarContainerColor = MaterialTheme.colorScheme.background, + ) + } else { + NavigationSuiteDefaults.colors() + }, ) { Box(Modifier.fillMaxSize()) { CompositionLocalProvider(