I'm having an issue in my code where the Ctrl+A ke...
# compose-desktop
g
I'm having an issue in my code where the Ctrl+A keyboard shortcut is not being detected. I've used a breakpoint to test if the function passed to
onPreviewKeyEvent
is being run but it is not. The row has been selected and focused on so I'm not sure what exactly is going wrong. Here is a link to the exact line of code. Why are the keyboard presses not being detected? https://github.com/recursivelftr/Grim-Locations/blob/d675a9a5859e320e833e8aa0fcb85[…]lin/io/grimlocations/ui/view/component/LocationListComponent.kt
i
There is no default modifier to request focus on click, you should write your own modifier. Example (order of focusRequester/focusable is matter):
Copy code
import androidx.compose.desktop.Window
import androidx.compose.foundation.background
import androidx.compose.foundation.focusable
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.forEachGesture
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.material.TextField
import androidx.compose.runtime.remember
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.isCtrlPressed
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.key.type
import androidx.compose.ui.input.pointer.consumeDownChange
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.dp

@OptIn(ExperimentalComposeUiApi::class)
fun main() = Window {
    Column {
        TextField("", {})

        Row(
            modifier = Modifier
                .requestFocusOnClick()
                .size(300.dp)
                .background(Color.LightGray)
                .onPreviewKeyEvent {
                    if(it.isCtrlPressed && it.key == Key.A && it.type == KeyEventType.KeyDown){
                        println("Ctrl+A")
                    }
                    true
                }
        ) {
            Column {
                Box(Modifier.size(50.dp).background(Color.Red).requestFocusOnClick())
                Box(Modifier.size(50.dp).background(Color.Green).requestFocusOnClick())
                Box(Modifier.size(50.dp).background(Color.Blue).requestFocusOnClick())
            }
        }
    }
}

private fun Modifier.requestFocusOnClick(): Modifier = composed {
    val focusRequester = remember(::FocusRequester)
    focusRequester(focusRequester).focusable().pointerInput(Unit) {
        forEachGesture {
            awaitPointerEventScope {
                val down = awaitFirstDown()
                focusRequester.requestFocus()
                down.consumeDownChange()
            }
        }
    }
}
g
very nice, I did try using a focus requester so that on the onClick even the item got focus. That did not work however, I eventually used the onPreviewKeyEvent of the
Window
composable and implemented an enum to indicate which item had focus
The way modifiers are set up is also quite confusing. The order matters but in most cases its not apparent what should go first. In my opinion, this was a bad design decision. I brought it up back in compose android alpha but I appear to be in the minority.