kotlincompose-desktop

Compose Desktop JVM Cursor is jumping one position to the left while typing in OutlinedTextField in a Dialog window


Hello as described in title, I have this problem only if I use Data Class for information exchange. Simplified code is as follows (in original code I have 3 OutlinedTextField):

data class ToolsStates(
    val isDialog: Boolean = false,
    val repair: String = "",
    val repairErrText: String = "You need to enter at least 3 characters",
    val isError: Boolean = false
)
sealed class DataExchange {
    data class IsDialogChanged(val isDialog: Boolean): DataExchange()
    data class RepairChanged(val repair: String): DataExchange()
}

class ViewModel {
    private val _state = MutableStateFlow(ToolsStates())
    val state: StateFlow<ToolsStates> = _state
    
    fun onEvent(event: DataExchange) {
        when (event) {
            is DataExchange.IsDialogChanged -> { _state.value = _state.value.copy(isDialog = event.isDialog) }
            is DataExchange.RepairChanged -> { _state.value = _state.value.copy(repair = event.repair) }
        }
    }
}

@Composable
fun MainView() {
    // some long code
    val viewModel by remember { ViewModel() }
    val state by viewModel.state.collectAsState()
    val dialogState = rememberDialogState(size = DpSize(550.dp, 500.dp))
    
    DialogWindow(
        onCloseRequest = { viewModel.onEvent(DataExchange.IsDialogChanged(false)) },
        visible = state.isDialog,
        state = dialogState,
        title = "Tool repair"
    ) {
        OutlinedTextField(
            value = state.repair,
            onValueChange = { viewModel.onEvent(DataExchange.RepairChanged(it)) },
            label = { Text("New tool entry") },
            supportingText = { Text(state.repairErrText) },
            isError = state.isError
        )
    }
}

If i don't use Data Class, and use variables like this inside viewmodel:

class ViewModel {
    val _repair = MutableStateFlow("")
    val repair: StateFlow<String> = _repair
}

Everything works like it should, but it gets really messy if i would need 5-10 variables.

But it only returns cursor one position to the left when in a Dialog Window, I have 7 OutlinedTextField also in main window and data class backed, and there is no problem. Thanks for reply.


Solution

  • Ok, I found my answer, it's the problem of Flow.

    If I want to synchronously update UI textfield, I cannot use Flow, because Flow is asynchronous and sometimes it returns previously typed character after the current character, and it looks like the cursor jumped one position to the left.

    I can only use mutableStateOf.