improvement: Support "Follow system theme" option for Flatpak users #382

This commit is contained in:
Artem Chepurnoy 2024-06-26 18:22:47 +03:00
parent 57dd991069
commit e994265ef0
No known key found for this signature in database
GPG Key ID: FAC37D0CF674043E
4 changed files with 87 additions and 1 deletions

View File

@ -0,0 +1,8 @@
package com.artemchep.keyguard.platform.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.Composable
import com.artemchep.keyguard.platform.Platform
@Composable
actual fun Platform.hasDarkThemeEnabled(): Boolean = isSystemInDarkTheme()

View File

@ -0,0 +1,7 @@
package com.artemchep.keyguard.platform.theme
import androidx.compose.runtime.Composable
import com.artemchep.keyguard.platform.Platform
@Composable
expect fun Platform.hasDarkThemeEnabled(): Boolean

View File

@ -22,6 +22,8 @@ import com.artemchep.keyguard.common.usecase.GetColors
import com.artemchep.keyguard.common.usecase.GetFont
import com.artemchep.keyguard.common.usecase.GetTheme
import com.artemchep.keyguard.common.usecase.GetThemeUseAmoledDark
import com.artemchep.keyguard.platform.CurrentPlatform
import com.artemchep.keyguard.platform.theme.hasDarkThemeEnabled
import com.artemchep.keyguard.res.Res
import com.artemchep.keyguard.res.*
import com.artemchep.keyguard.ui.theme.monet.ColorSchemeFactory
@ -275,7 +277,7 @@ fun KeyguardTheme(
val isDarkColorScheme = when (theme) {
AppTheme.DARK -> true
AppTheme.LIGHT -> false
null -> isSystemInDarkTheme()
null -> CurrentPlatform.hasDarkThemeEnabled()
}
val scheme = kotlin.run {

View File

@ -0,0 +1,69 @@
package com.artemchep.keyguard.platform.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import com.artemchep.keyguard.platform.Platform
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.withContext
import java.util.concurrent.TimeUnit
@Composable
actual fun Platform.hasDarkThemeEnabled(): Boolean = when (this) {
is Platform.Desktop.Linux -> isLinuxPortalInDarkTheme()
else -> isSystemInDarkTheme()
}
@Composable
private fun isLinuxPortalInDarkTheme(): Boolean {
val darkThemeDefault = isSystemInDarkTheme()
var darkThemeState by remember {
mutableStateOf(darkThemeDefault)
}
LaunchedEffect(Unit) {
while (true) {
kotlin.runCatching {
darkThemeState = readLinuxPortalInDarkTheme()
}.getOrElse {
// Stop checking for the appearance, just use
// whatever Compose provides.
darkThemeState = darkThemeDefault
return@LaunchedEffect
}
delay(2000L)
ensureActive()
}
}
return darkThemeState
}
private suspend fun readLinuxPortalInDarkTheme() = withContext(Dispatchers.IO) {
val command = listOf(
"gdbus",
"call",
"--session",
"--dest=org.freedesktop.portal.Desktop",
"--object-path=/org/freedesktop/portal/desktop",
"--method=org.freedesktop.portal.Settings.Read",
"org.freedesktop.appearance",
"color-scheme",
)
val pb = ProcessBuilder(command)
.redirectError(ProcessBuilder.Redirect.INHERIT)
val process = pb.start().apply {
waitFor(60, TimeUnit.MINUTES)
}
val result = process.inputStream.reader().readText()
// 0: No preference
// 1: Prefer dark appearance
// 2: Prefer light appearance
result[10] == '1'
}