compose-multiplatform icon indicating copy to clipboard operation
compose-multiplatform copied to clipboard

Showing a child window for the second time fails

Open Inego opened this issue 4 years ago • 6 comments

fun main() {

    val checkBoxState = mutableStateOf(false)

    Window {
        val childWindow = remember { AppWindow("Child") }
        val compositionContext = rememberCompositionContext()

        Checkbox(checkBoxState.value, {

            checkBoxState.value = it

            if (it) {
                childWindow.show(compositionContext) {
                    Text("Content")
                }
            } else {
                childWindow.close()
            }
        })
    }
}
  1. Clicking the checkbox displays the child window.
  2. Clicking the checkbox again closes the child window.
  3. Clicking the checkbox again does not show the child window again, instead, an exception is thrown:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Check failed.
	at androidx.compose.desktop.ComposeLayer.setContent$ui(ComposeLayer.desktop.kt:244)
	at androidx.compose.desktop.ComposeWindow.setContent(ComposeWindow.desktop.kt:72)
	at androidx.compose.desktop.AppWindow.onCreate(AppWindow.desktop.kt:415)
	at androidx.compose.desktop.AppWindow.show(AppWindow.desktop.kt:441)
	at TempKt$main$1$1.invoke(Temp.kt:22)

Compose Desktop 0.3.2.

Inego avatar Mar 09 '21 12:03 Inego

Judging by the code, it seems an AppWindow cannot be shown after it was closed.

    internal fun setContent(
        parentComposition: CompositionContext? = null,
        content: @Composable () -> Unit
    ) {
        check(!isDisposed)
        check(this.content == null) { "Cannot set content twice" }
        ...

Inego avatar Mar 09 '21 12:03 Inego

Thanks!

We plan to gradually replace AppWindow API by Composable Window API (prototype).

So the current example probably will be:

fun main() = Application {
    val checkBoxState = remember { mutableStateOf(false) }

    Window {
        if (checkBoxState) {
            Window("Child") {
                Text("Content")
            }
        }
 
        Checkbox(checkBoxState.value, {
            checkBoxState.value = it
        })
    }
}

(it is not a final API, don't know yet how we will support child non-modal windows).

Regarding the current API - don't know if it is good or bad to provide ability to reshow AppWindow 🤔 (we can make AppWindow nullable and just create a new AppWindow). We would intevestigate use-cases, if we aren't implementing a new API.

igordmn avatar Mar 11 '21 16:03 igordmn

We plan to gradually replace AppWindow API by Composable Window API (prototype).

So the current example probably will be: ...

This API looks great! I wonder how fine-tuning of such windows will work (like, to specify window keyboard shortcuts).

Inego avatar Mar 12 '21 00:03 Inego

how fine-tuning of such windows will work

Probably something like this:

val state = rememberWindowState(width = 100.dp)
Window(title = "Title", state = state) {
  Button(onClick = { state.resize(height= 200.dp) })
}

We will also provide the ability to manually tune underlying JFrame:

Window(title = "Title", configure = { jframe : JFrame ->
  // do something with jframe 
})

specify window keyboard shortcuts

We don't know yet about window shortcuts, but we will try to keep all the current functionality in the new API. If we remove some functionality we will provide an alternative.

igordmn avatar Mar 12 '21 12:03 igordmn

Maybe something like https://github.com/JetBrains/compose-jb/tree/master/tutorials/Swing_Integration#adding-a-swing-component-to-cfd-composition-using-swingpanel which returns JPanel would make sense.

olonho avatar Mar 15 '21 06:03 olonho

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

okushnikov avatar Aug 26 '24 17:08 okushnikov