mirror of
https://github.com/jlengrand/compose-multiplatform.git
synced 2026-05-11 00:01:22 +00:00
128 lines
4.6 KiB
Markdown
128 lines
4.6 KiB
Markdown
# Keyboard events handling
|
|
|
|
## Prerequisites
|
|
|
|
This tutorial expects that you have already set up the Compose project as described in the [Getting Started tutorial](../Getting_Started)
|
|
|
|
## What is covered
|
|
|
|
In this tutorial, we will look at two different ways of handling keyboard events in Compose for Desktop as well as the utilities that we have to do this.
|
|
|
|
## KeySets
|
|
|
|
Compose for Desktop has a few utilities to work with shortcuts:
|
|
|
|
`KeysSet` represents a set of keys that can be simultaneously pressed. You can construct a KeysSet using the Key's extension function:
|
|
|
|
``` kotlin
|
|
Key.CtrlLeft + Key.Enter
|
|
```
|
|
|
|
## Event handlers
|
|
|
|
There are two ways to handle key events in Compose for Desktop:
|
|
|
|
- By setting up an event handler based on the element that is in focus
|
|
- By setting up an event handler in the scope of the window
|
|
|
|
## Focus related events
|
|
|
|
It works the same as Compose for Android, for details see [API Reference](https://developer.android.com/reference/kotlin/androidx/compose/ui/input/key/package-summary#keyinputfilter)
|
|
|
|
`Modifier.shortcuts` is used to define one or multiple callbacks for `KeysSet`s.
|
|
|
|
The most common use case is to define keyboard handlers for active controls like `TextField`. Here is an example:
|
|
|
|
```kotlin
|
|
import androidx.compose.desktop.Window
|
|
import androidx.compose.foundation.layout.Arrangement
|
|
import androidx.compose.foundation.layout.Column
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
import androidx.compose.material.Text
|
|
import androidx.compose.material.MaterialTheme
|
|
import androidx.compose.material.TextField
|
|
import androidx.compose.runtime.mutableStateOf
|
|
import androidx.compose.runtime.remember
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.input.key.*
|
|
import androidx.compose.ui.unit.IntSize
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.runtime.setValue
|
|
import androidx.compose.ui.input.key.shortcuts
|
|
|
|
fun main() = Window(title = "Compose for Desktop", size = IntSize(300, 300)) {
|
|
MaterialTheme {
|
|
var consumedText by remember { mutableStateOf(0) }
|
|
var text by remember { mutableStateOf("") }
|
|
Column(Modifier.fillMaxSize(), Arrangement.spacedBy(5.dp)) {
|
|
Text("Consumed text: $consumedText")
|
|
TextField(
|
|
value = text,
|
|
onValueChange = { text = it },
|
|
modifier = Modifier.shortcuts {
|
|
on(Key.CtrlLeft + Key.Minus) {
|
|
consumedText -= text.length
|
|
text = ""
|
|
}
|
|
on(Key.CtrlLeft + Key.Equals) {
|
|
consumedText += text.length
|
|
text = ""
|
|
}
|
|
}
|
|
)
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
|
|
Note the annotation `@OptIn(ExperimentalKeyInput::class)`. Keyboard-related event handlers are still an experimental feature of Compose, and later API changes are possible. So it requires the use of a special annotation to emphasize the experimental nature of the code.
|
|
|
|

|
|
|
|
## Window-scoped events
|
|
|
|
`AppWindow` instances have a `keyboard` property. It is possible to use it to define keyboard shortcuts that are always active in the current window. Here is an example:
|
|
|
|
``` kotlin
|
|
import androidx.compose.desktop.AppWindow
|
|
import androidx.compose.desktop.Window
|
|
import androidx.compose.foundation.Text
|
|
import androidx.compose.foundation.layout.Arrangement
|
|
import androidx.compose.foundation.layout.Column
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.material.Button
|
|
import androidx.compose.material.MaterialTheme
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.input.key.ExperimentalKeyInput
|
|
import androidx.compose.ui.input.key.Key
|
|
import androidx.compose.ui.unit.IntSize
|
|
import androidx.compose.ui.unit.dp
|
|
|
|
@OptIn(ExperimentalKeyInput::class)
|
|
fun main() = Window(title = "Compose for Desktop", size = IntSize(300, 300)) {
|
|
MaterialTheme {
|
|
Column(Modifier.fillMaxSize(), Arrangement.spacedBy(5.dp)) {
|
|
Button(
|
|
modifier = Modifier.padding(4.dp),
|
|
onClick = {
|
|
AppWindow(size = IntSize(200, 200)).also {
|
|
it.keyboard.setShortcut(Key.Escape) {
|
|
it.close()
|
|
}
|
|
}.show {
|
|
Text("I'm popup!")
|
|
}
|
|
}
|
|
) {
|
|
Text("Open popup")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|

|