JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
15.42k stars 1.12k forks source link

[Web][Wasm] Inconsistent onKeyEvent API across web/desktop + focus issue #4673

Open egorikftp opened 2 months ago

egorikftp commented 2 months ago

Describe the bug Desktop platform provides API to listen global key events inside Window function

fun main() {
    application {
        Window(
            onKeyEvent = {
                println("event: $it")
            },
            content = { App() }
        )
    }
}

On Wasm there is no such API, but since 1.6.10-beta01 (https://github.com/JetBrains/compose-multiplatform/issues/2296, https://github.com/JetBrains/compose-multiplatform/issues/3644) we can handle it following way

fun main() {
    val focusRequester = FocusRequester()
    CanvasBasedWindow(canvasElementId = "YourTarget") {
        Box(
            modifier = Modifier
                .fillMaxSize()
                .focusRequester(focusRequester)
                .focusTarget()
                .onKeyEvent {
                    println("event: $it")
                    false
                }
        ) {
            // nested content
        }
        SideEffect {
            focusRequester.requestFocus()
        }
    }
}

But in this case, if we open some nested screen, we lose focus and key events not passes to root modifier until we make root function focused again.

In demo page focuses on start and receive key events, after losing focus doesn't receive any events

https://github.com/JetBrains/compose-multiplatform/assets/16294951/413e078f-362c-4d0a-8f69-fe7b24ebda02

For testing purpose we can make this hack, but it break all the app logic 🙂

// workaround to make window always focused
LaunchedEffect(Unit) {
    while (true) {
        delay(100)
        focusRequester.requestFocus()
    }
}

Can it be done without manual focus manipulation?

Affected platforms

Kotlin version: 2.0.0-RC1 Compose Multiplatform version: 1.6.10-beta01

Schahen commented 2 months ago

Hi @egorikftp - yep, we've tried to introduce basic support for virtual keyboard but missed a couple of very serious things to consider. In next beta this will be addressed in desktop browser and one beta release after that in mobile browsers as well. Will close this issue whenever it will be completely gone.

okushnikov commented 9 hours ago

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