Status Update
Comments
kl...@google.com <kl...@google.com>
jo...@langlive.com <jo...@langlive.com> #2
This is probably happening because there are multiple instances of DataStore active. You should consider managing the DataStore as a singleton. See the attached bug for more info.
jo...@langlive.com <jo...@langlive.com> #3
de...@gmail.com <de...@gmail.com> #4
ha...@google.com <ha...@google.com> #5
This is a race condition between focus and input service system. The important detail, as outlined in the original report, is the fact that text content changes.
BasicTextField calls restartInput
whenever the state is changed from somewhere other than IME, in this case by the button's onClick lambda. If text remains the same, this restart call is never made.
Restarting the input instructs the software keyboard to update itself. However, in this case focus is also cleared immediately after, which tells the text input service to stop. TextInputService reacts to this by scheduling two calls to run at the end of the frame; 1) hide the keyboard, 2) actually request restart input from InputMethodManager.
So, the timeline of events look like this;
- As the composition phase ends, state change triggers
IMM.restartInput()
- At the end of the frame, first hide keyboard is called
- Then
IMM.restartInput
is called again. This doesn't necessarily start the input, it just notifies the IMM that input service state has changed.
I'm not exactly sure about the solution here, or if this is working as intended.
de...@gmail.com <de...@gmail.com> #6
ha...@google.com <ha...@google.com> #7
I think the simplest workaround for this issue is just delaying the change of value until the desired focus call is made. This would be the end of LaunchedEffect
var text by rememberSaveable { mutableStateOf("") }
var active by rememberSaveable { mutableStateOf(true) }
val focusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
Column {
Button(onClick = {
active = !active
}) {
Text("toggle active")
}
TextField(
value = text,
onValueChange = { text = it },
label = { Text("Label") },
singleLine = true,
modifier = Modifier
.focusRequester(focusRequester)
.onFocusChanged { active = it.isFocused }
)
}
LaunchedEffect(active) {
if (active) {
focusRequester.requestFocus()
} else {
// delay(50)
focusManager.clearFocus()
}
text = "abc"
}
Description
Produced on Pixel 5 with Gboard.
Code is the following:
When clearing focus on the text field by pressing the button, the keyboard will jitter as it dismisses if the text field value has changed. If the text is already
"abc"
and does not change, then the keyboard dismisses properly.Adding a delay before clearing focus (~50ms on my device) also causes the jitter to disappear.