Are there known issues with `movableContentOf()` a...
# compose
r
Are there known issues with
movableContentOf()
and keyboard events? When I move a "movable content" composable, keyboard events via
onPreviewKeyEvent
are no longer received, even though the composable remains focused.
Test case: 1. Observe that key events are received when the content hasn't moved (green background) 2. After the content moves (red background), key events are no longer received, but the component still remains focused.
Copy code
@Composable
private fun TestCase() {
    val movableContent = remember { movableContentOf { MyContent() } }
    var sentinel by remember { mutableStateOf(false) }

    LaunchedEffect(Unit) {
        delay(5000)
        sentinel = true
    }

    if (!sentinel) {
        Box(Modifier.background(Color.Green)) { movableContent() }
    } else {
        Box(Modifier.background(Color.Red)) { movableContent() }
    }
}

@Composable
private fun MyContent() {
    val focusRequester = remember { FocusRequester() }
    val interactionSource = remember { MutableInteractionSource() }
    val isFocused by interactionSource.collectIsFocusedAsState()

    LaunchedEffect(Unit) {
        focusRequester.requestFocus()
    }

    Box(Modifier
        .focusRequester(focusRequester)
        .focusable(true, interactionSource)
        .onPreviewKeyEvent {
            println("[${Instant.now()}] got key event: ${it.key}")
            false
        }
    ) {
        BasicText("Focused? $isFocused")
    }
}
l
The ‘still remains focused’ part is a bug that has been fixed - the component is actually not focused (at the system level) when moved.
r
Ah. How can I maintain the focus in this situation?
since the content composable isn't rebuilt, the LaunchedEffect(Unit) won't get invoked again
l
There isn’t an easy way to do this currently, I would recommend filing a bug with your use case. Instead of using focusRequester() you could build your own focus requesting node, that requests focus https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]tlin/androidx/compose/ui/focus/FocusRequesterModifier.kt;l=67 And just call requestFocus() inside onAttach instead, or maybe better to do: onAttach() { sideEffect { requestFocus() } }
r
Oh interesting, I wasn't aware of that kind of approach. Thank you!