I'm implementing a chess clock in Jetpack Compose for Desktop. But it seems I'm facing a strange behaviour : on Linux (at least on Ubuntu 22.04 64 bits), when you switch window so that the clock host is in background process, the clock is paused instead of going on. Whereas on Windows 11 (64 bits) it works perfectly.
My build.gradle.kts
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
}
group = "com.loloof64"
version = "1.0-SNAPSHOT"
repositories {
google()
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
kotlin {
jvm {
jvmToolchain(11)
withJava()
}
sourceSets {
val jvmMain by getting {
dependencies {
implementation(compose.desktop.currentOs)
}
}
val jvmTest by getting
}
}
compose.desktop {
application {
mainClass = "MainKt"
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "PeerChess"
packageVersion = "1.0.0"
}
}
}
My source file Main.kt
@Composable
fun SimpleClockComponent(
modifier: Modifier = Modifier,
whiteTimeInDeciSeconds: Int,
blackTimeInDeciSeconds: Int,
whiteTimeActive: Boolean,
) {
val whiteText = getTimeText(whiteTimeInDeciSeconds)
val blackText = getTimeText(blackTimeInDeciSeconds)
var whiteZoneFgColor = Color.Black
var blackZoneFgColor = Color.White
var whiteZoneBgColor = Color.White
var blackZoneBgColor = Color.Black
if (whiteTimeActive) {
if (whiteTimeInDeciSeconds < 600) {
whiteZoneBgColor = Color.Red
whiteZoneFgColor = Color.White
} else {
whiteZoneBgColor = Color.Blue
whiteZoneFgColor = Color.Yellow
}
} else {
if (blackTimeInDeciSeconds < 600) {
blackZoneBgColor = Color.Red
blackZoneFgColor = Color.White
} else {
blackZoneBgColor = Color.Blue
blackZoneFgColor = Color.Yellow
}
}
Row(
modifier = modifier.fillMaxWidth().fillMaxHeight(0.1f).border(width = 1.dp, color = Color.Black)
) {
Box(
modifier = Modifier.fillMaxWidth(0.5f).fillMaxHeight().background(whiteZoneBgColor),
contentAlignment = Alignment.Center,
) {
Text(
text = whiteText,
color = whiteZoneFgColor,
textAlign = TextAlign.Center,
)
}
Box(
modifier = Modifier.fillMaxWidth().fillMaxHeight().background(blackZoneBgColor),
contentAlignment = Alignment.Center,
) {
Text(
text = blackText,
color = blackZoneFgColor,
textAlign = TextAlign.Center,
)
}
}
}
fun startClock(
coroutineScope: CoroutineScope,
whiteTimeActive: Boolean,
onWhiteTimeDec: () -> Unit,
onBlackTimeDec: () -> Unit
) : Job? {
return coroutineScope.launch {
while (isActive) {
delay(100)
if (whiteTimeActive) {
onWhiteTimeDec()
} else {
onBlackTimeDec()
}
}
}
}
@Preview
@Composable
fun WorkingClockComponentPreview() {
val allocatedTimeDeciSeconds = 15 * 10
val coroutineScope = rememberCoroutineScope()
var whiteTimeInDeciSeconds by remember { mutableStateOf(allocatedTimeDeciSeconds) }
var blackTimeInDeciSeconds by remember { mutableStateOf(allocatedTimeDeciSeconds) }
var clockActive by remember { mutableStateOf(false) }
var clockJob by remember { mutableStateOf<Job?>(null) }
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
SimpleClockComponent(
whiteTimeInDeciSeconds = whiteTimeInDeciSeconds,
blackTimeInDeciSeconds = blackTimeInDeciSeconds,
whiteTimeActive = true,
)
Button({
whiteTimeInDeciSeconds = allocatedTimeDeciSeconds
blackTimeInDeciSeconds = allocatedTimeDeciSeconds
clockJob = startClock(coroutineScope, true, {
whiteTimeInDeciSeconds--
if (whiteTimeInDeciSeconds <= 0) {
clockActive = false
clockJob?.cancel()
}
}, {
blackTimeInDeciSeconds--
if (blackTimeInDeciSeconds <= 0) {
clockActive = false
clockJob?.cancel()
}
})
}) {
Text("Start")
}
}
}
fun main() = application {
Window(onCloseRequest = ::exitApplication) {
window.minimumSize = Dimension(400, 500)
WorkingClockComponentPreview()
}
}
I've tested with Intellij Idea Community 2022.3.3
So what's wrong with my code ?