Closed ScottPierce closed 1 month ago
Reproduced in the following environment:
I've made a reproducible sample (see below). For convenience, there are three Gradle tasks:
runInitJcefBeforeComposeApplication
, which initializes jcef before Compose application {}
is initialized. This case freezes on resize or on when the window is closed.runInitJcefAfterComposeApplication
, which initializes jcef right after Compose application {}
is initialized.runInitJcefAfterComposeWindow
, which initializes jcef right after Compose Window()
is called.Only in the first case the app freezes on resize or when the window is closed.
// build.gradle.kts
import org.gradle.jvm.tasks.Jar
plugins {
kotlin("multiplatform") version "1.8.10"
id("org.jetbrains.compose") version "1.3.1"
}
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("me.friwi:jcefmaven:110.0.25")
implementation(compose.desktop.currentOs)
}
}
val jvmTest by getting
}
}
fun JavaExec.cofigureRunJcef() {
mainClass.set("MainKt")
val kotlinJvm = kotlin.jvm()
val compilation = kotlinJvm.compilations.getByName("main")
val jar = tasks.getByName(kotlinJvm.artifactsTaskName)
dependsOn(jar)
classpath((jar as Jar).archiveFile.get().asFile)
classpath(compilation.runtimeDependencyFiles)
}
tasks.register("runInitJcefBeforeComposeApplication", JavaExec::class) {
cofigureRunJcef()
args("before-compose-application")
}
tasks.register("runInitJcefAfterComposeApplication", JavaExec::class) {
cofigureRunJcef()
args("after-compose-application")
}
tasks.register("runInitJcefAfterComposeWindow", JavaExec::class) {
cofigureRunJcef()
args("after-compose-window")
}
// src/jvmMain/kotlin/Main.kt
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.layout.Row
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import me.friwi.jcefmaven.CefAppBuilder
@Composable
@Preview
fun App() {
MaterialTheme {
var clicks by remember { mutableStateOf(0) }
Row {
Button(onClick = { clicks++ }) {
Text("$clicks clicks")
}
}
}
}
fun String.toDashCase(): String =
buildString {
for ((index, char) in this@toDashCase.withIndex()) {
if (index > 0 && char.isUpperCase()) {
append("-")
}
append(char.lowercaseChar())
}
}
enum class InitLocation {
BeforeComposeApplication, AfterComposeApplication, AfterComposeWindow;
companion object {
fun fromDashCaseName(dashCaseName: String?): InitLocation {
if (dashCaseName == null) return values().first()
val initModeByDashCaseName = values().associateBy { it.name.toDashCase() }
return initModeByDashCaseName.getOrElse(dashCaseName) {
error("'$dashCaseName' is not a valid value for jcef init location. Valid values are: ${initModeByDashCaseName.keys.joinToString(", ") { "'$it'" }}")
}
}
}
}
fun main(args: Array<String>) {
val requestedInitLocation = InitLocation.fromDashCaseName(args.firstOrNull())
fun initJcefAt(location: InitLocation) {
if (location == requestedInitLocation) {
System.out.println("Initializing jcef at: ${location.name.toDashCase()}")
CefAppBuilder().build()
}
}
initJcefAt(InitLocation.BeforeComposeApplication)
application {
initJcefAt(InitLocation.AfterComposeApplication)
Window(onCloseRequest = ::exitApplication) {
initJcefAt(InitLocation.AfterComposeWindow)
App()
}
}
}
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
Describe the bug If JCEF is loaded before a Compose Window is displayed, the Compose window then cannot be resized, and the application will crash if a resize is attempted.
Affected platforms Select one of the platforms below:
Versions
To Reproduce Use the following library for JCEF: https://github.com/jcefmaven/jcefmaven
Steps and/or the code snippet to reproduce the behavior:
Expected behavior That window resizing works no matter when jcef is loaded.
Additional context Window resizing appears to work if you load JCEF after the compose window is created.