Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compose(DESKTOP,JVM) 1.2.2 textfield Korean duplication #2600

Closed
June6-android opened this issue Jan 5, 2023 · 6 comments · Fixed by JetBrains/compose-multiplatform-core#406
Assignees
Labels
bug Something isn't working desktop input Touch, mouse, keyboard input related p:high High priority

Comments

@June6-android
Copy link

I'm implementing a simple search input field on Compose desktop.

My code looks as below.

        BasicTextField(
            modifier = Modifier.align(Alignment.CenterVertically).onPreviewKeyEvent {
                 if(it.key == Key.Enter && it.type == KeyEventType.KeyDown){
                    println("enter down: $textFieldState")
                    true
                }else {
                     false
                }
            },
            value = textFieldState,
            onValueChange = { input ->
                textFieldState = input
            },
            textStyle = TextStyle(
                fontSize = 14.sp,
                textAlign = TextAlign.Start,
                fontWeight = FontWeight.Normal,
                fontFamily = NotoSans,
                color = Color.Black
            ),
            maxLines = 1,
            decorationBox = { innerTextField ->
                Row(modifier = Modifier.fillMaxWidth()) {
                    if (textFieldState.isEmpty()) {
                        Text(
                            text = "Search with user name.",
                            fontSize = 14.sp,
                            color = Color(0xFF909ba9),
                            textAlign = TextAlign.Start,
                            fontWeight = FontWeight.Normal,
                            fontFamily = NotoSans,
                            modifier = Modifier.fillMaxWidth()
                                .align(Alignment.CenterVertically),
                        )
                    }
                }
                innerTextField()
            }
        )

This code will create a textfield which has 1 max lines. It works without any problem on english inputs. But when I type in Korean inputs, keys such as space, enter, or even numbers will duplicate the last Korean character. For example, in english, if I type in H, I, !, it will be HII!.

Is there some locale settings that can be done to the textField?

@June6-android
Copy link
Author

June6-android commented Jan 7, 2023

Answering my own workaround for this after some struggles.
I found no working solution for compose jvm itself neither in here nor in stackoverflow.
My workaround is to use SwingPanel and JTextField, which doesn't have the same bug as compose does. Weird, since I thought compose works over swing after all.

SwingPanel(background = Color(0xFFf5f6f6), modifier = Modifier.fillMaxSize(), factory = {
                //Some JTextfield I've obtaines from stackoverflow to show place holder text.
                //Can be replaced to JTextField(columnCount:Int)
                HintTextField("Enter in name",1).apply {
                    background = java.awt.Color(0xf5, 0xf6, 0xf6)
                    border = null
                }
            }, update = {
                //SimpleDocumentListener is an implementation of DocumentListener.
                //Which means it can be replaced by it.
                it.document.addDocumentListener(object : SimpleDocumentListener{
                    override fun update(e: DocumentEvent) {
                        try{
                            val text = it.text
                            textFieldState = text
                        } catch(e : Exception) {
                            e.printStackTrace()
                        }
                    }
                })
                //I need an enter key to trigger some search logics.
                //textFieldState seems to print the value as I intended
                it.addKeyListener(object : KeyAdapter(){
                    override fun keyPressed(e: KeyEvent?) {
                        if(e?.keyCode == KeyEvent.VK_ENTER){
                            println("ENTER : $textFieldState")
                        }
                    }
                })
            })

I've tested this workaround, and seems to work ok. But, I hope there's a better support on compose's own TextField components.

@AlexeyTsvetkov
Copy link
Collaborator

@June6-android what operating system, JDK distribution & system keyboard input setting do you use?
So far I was not able to reproduce the issue with macOS 13 and OpenJDK 17.0.5

@June6-android
Copy link
Author

June6-android commented Jan 13, 2023

AlexeyTsvetkov>

Thanks for your support. I use
os : Windows 10,
jvm : Project SDK 16,
system keyboard input : Microsoft Korean input (not so sure about it's english name)

@AlexeyTsvetkov AlexeyTsvetkov added bug Something isn't working input Touch, mouse, keyboard input related desktop labels Jan 16, 2023
@AlexeyTsvetkov
Copy link
Collaborator

Reproduced on Windows 10 with the Korean input keyboard.
The reproducible example can be found here https://github.com/AlexeyTsvetkov/compose-jb-issue-2600/
Steps to reproduce:

  1. Add Korean keyboard in Language settings.
  2. Clone the example repository.
  3. Run the app by running ./gradlew run in terminal.
  4. Switch to Korean.
  5. Enter some text + Enter/Space/0-9.

Expected result: only typed text is shown.
Actual result: the last character is duplicated.

The issue is not present on macOS, but present on Windows.

@AlexeyTsvetkov
Copy link
Collaborator

A simplified example that can be copy pasted:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application

fun main() = application {
    Window(onCloseRequest = ::exitApplication) {
        var textFieldState by remember { mutableStateOf("") }
        Row {
            BasicTextField(
                modifier = Modifier.padding(10.dp).border(1.dp, Color.Gray).fillMaxSize(),
                value = textFieldState,
                onValueChange = { input -> textFieldState = input },
                textStyle = TextStyle(fontSize = 14.sp,),
                maxLines = 1,
            )
        }
    }
}

@igordmn igordmn added the p:high High priority label Jan 19, 2023
igordmn added a commit to JetBrains/compose-multiplatform-core that referenced this issue Feb 14, 2023
Fixes JetBrains/compose-multiplatform#2600

1. We shouldn't skip input events with empty text, they will clear the current uncommitted text. In case of Korean, Swing will send a clear event of the previous char when we press Space, and send a separate "KEY_TYPED" event for the last character:
- press q -> q uncommitted
- press w -> commit q, w uncommitted
- press Space -> discard committed text (event with empty text), send KEY_TYPED event with w and KEY_TYPED event with Space

2. Add tests for test input. I traced Swing events on each OS to mimic integration tests (It is difficult to write real input tests)
igordmn added a commit to JetBrains/compose-multiplatform-core that referenced this issue Feb 23, 2023
Fixes JetBrains/compose-multiplatform#2600

1. We shouldn't skip input events with empty text, they will clear the current uncommitted text. In case of Korean, Swing will send a clear event of the previous char when we press Space, and send a separate "KEY_TYPED" event for the last character:
- press q -> q uncommitted
- press w -> commit q, w uncommitted
- press Space -> discard committed text (event with empty text), send KEY_TYPED event with w and KEY_TYPED event with Space

2. Add tests for test input. I traced Swing events on each OS to mimic integration tests (It is difficult to write real input tests)
eymar pushed a commit to JetBrains/compose-multiplatform-core that referenced this issue Feb 24, 2023
Fixes JetBrains/compose-multiplatform#2600

1. We shouldn't skip input events with empty text, they will clear the current uncommitted text. In case of Korean, Swing will send a clear event of the previous char when we press Space, and send a separate "KEY_TYPED" event for the last character:
- press q -> q uncommitted
- press w -> commit q, w uncommitted
- press Space -> discard committed text (event with empty text), send KEY_TYPED event with w and KEY_TYPED event with Space

2. Add tests for test input. I traced Swing events on each OS to mimic integration tests (It is difficult to write real input tests)
MatkovIvan pushed a commit to MatkovIvan/compose-multiplatform that referenced this issue May 10, 2023
Fixes JetBrains#2600

1. We shouldn't skip input events with empty text, they will clear the current uncommitted text. In case of Korean, Swing will send a clear event of the previous char when we press Space, and send a separate "KEY_TYPED" event for the last character:
- press q -> q uncommitted
- press w -> commit q, w uncommitted
- press Space -> discard committed text (event with empty text), send KEY_TYPED event with w and KEY_TYPED event with Space

2. Add tests for test input. I traced Swing events on each OS to mimic integration tests (It is difficult to write real input tests)
@okushnikov
Copy link
Collaborator

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

@JetBrains JetBrains locked and limited conversation to collaborators Dec 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working desktop input Touch, mouse, keyboard input related p:high High priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants