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

Trying to delete a word via Ctrl+Backspace in an empty TextField causes an exception #2466

Closed
silenium-dev opened this issue Nov 11, 2022 · 5 comments
Assignees
Labels
crash input Touch, mouse, keyboard input related p:high High priority regression wait for build

Comments

@silenium-dev
Copy link

I've built a minimal example: https://github.com/silenium-dev/bug-report-example

I'll try to fix it myself and submit a pull request.

Stacktrace:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: offset(-1) is out of bounds [0, 0]
	at androidx.compose.ui.text.MultiParagraph.requireIndexInRangeInclusiveEnd(MultiParagraph.kt:755)
	at androidx.compose.ui.text.MultiParagraph.getWordBoundary--jx7JFs(MultiParagraph.kt:589)
	at androidx.compose.ui.text.TextLayoutResult.getWordBoundary--jx7JFs(TextLayoutResult.kt:518)
	at androidx.compose.foundation.text.selection.BaseTextPreparedSelection.getPrevWordOffset(TextPreparedSelection.kt:278)
	at androidx.compose.foundation.text.selection.BaseTextPreparedSelection.getPrevWordOffset$default(TextPreparedSelection.kt:272)
	at androidx.compose.foundation.text.selection.BaseTextPreparedSelection.getPreviousWordOffset(TextPreparedSelection.kt:198)
	at androidx.compose.foundation.text.TextFieldKeyInput$process$2$5.invoke(TextFieldKeyInput.kt:148)
	at androidx.compose.foundation.text.TextFieldKeyInput$process$2$5.invoke(TextFieldKeyInput.kt:147)
	at androidx.compose.foundation.text.selection.TextFieldPreparedSelection.deleteIfSelectedOr(TextPreparedSelection.kt:397)
	at androidx.compose.foundation.text.TextFieldKeyInput$process$2.invoke(TextFieldKeyInput.kt:147)
	at androidx.compose.foundation.text.TextFieldKeyInput$process$2.invoke(TextFieldKeyInput.kt:103)
	at androidx.compose.foundation.text.TextFieldKeyInput.commandExecutionContext(TextFieldKeyInput.kt:223)
	at androidx.compose.foundation.text.TextFieldKeyInput.process-ZmokQxo(TextFieldKeyInput.kt:103)
	at androidx.compose.foundation.text.TextFieldKeyInputKt$textFieldKeyInput$2$1.invoke-ZmokQxo(TextFieldKeyInput.kt:255)
	at androidx.compose.foundation.text.TextFieldKeyInputKt$textFieldKeyInput$2$1.invoke(TextFieldKeyInput.kt:255)
	at androidx.compose.ui.input.key.KeyInputModifier.propagateKeyEvent-ZmokQxo(KeyInputModifier.kt:124)
	at androidx.compose.ui.input.key.KeyInputModifier.processKeyInput-ZmokQxo(KeyInputModifier.kt:103)
	at androidx.compose.ui.platform.SkiaBasedOwner.sendKeyEvent-ZmokQxo(SkiaBasedOwner.skiko.kt:231)
	at androidx.compose.ui.ComposeScene.sendKeyEvent-ZmokQxo(ComposeScene.skiko.kt:572)
	at androidx.compose.ui.awt.ComposeLayer$onKeyEvent$1.invoke(ComposeLayer.desktop.kt:410)
	at androidx.compose.ui.awt.ComposeLayer$onKeyEvent$1.invoke(ComposeLayer.desktop.kt:406)
	at androidx.compose.ui.awt.ComposeLayer.catchExceptions(ComposeLayer.desktop.kt:109)
	at androidx.compose.ui.awt.ComposeLayer.onKeyEvent(ComposeLayer.desktop.kt:406)
	at androidx.compose.ui.awt.ComposeLayer.access$onKeyEvent(ComposeLayer.desktop.kt:87)
	at androidx.compose.ui.awt.ComposeLayer$7.keyPressed(ComposeLayer.desktop.kt:385)
	at java.desktop/java.awt.Component.processKeyEvent(Component.java:6584)
	at java.desktop/java.awt.Component.processEvent(Component.java:6403)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
	at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1952)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:883)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1150)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:1020)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:848)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4882)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
@igordmn
Copy link
Collaborator

igordmn commented Nov 11, 2022

Thanks!

Reproduced in Compose 1.2.1, doesn't reproduce in 1.1.1, Windows/macOS

A minimal reproducer:

import androidx.compose.material.TextField
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.window.singleWindowApplication

fun main() = singleWindowApplication {
    var text by remember { mutableStateOf("") }
    TextField(text, onValueChange = { text = it })
}
  1. Focus on the text field
  2. Press Ctrl+Backspace (this combination removes whole words)

After the fix we should write tests for word removal behavior

@igordmn igordmn added input Touch, mouse, keyboard input related crash p:high High priority regression labels Nov 11, 2022
@silenium-dev
Copy link
Author

silenium-dev commented Nov 11, 2022

I've looked into this issue, and it seems to be a small fix.
The method BaseTextPreparedSelection.charOffset() limits the offset upwards by the text length, but not downwards.

Current code:

// frameworks/support/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/TextPreparedSelection.kt:345
private fun charOffset(offset: Int) =
    offset.coerceAtMost(text.length - 1)

I'm not able to test this as I don't have the necessary development environment setup (Any link or guide would be appreciated, I'd like to contribute more), but the fix should be:

private fun charOffset(offset: Int) =
        offset.coerceIn(0, text.length - 1)

@eymar
Copy link
Collaborator

eymar commented Nov 16, 2022

@silenium-dev We don't have a full-fledged Contribution guide yet, but you here's how we setup the project: https://github.com/JetBrains/compose-jb/blob/master/compose/README.md (note: it differs from the upstream aosp repo setup)

For contributions to common code (either to the fork https://github.com/Jetbrains/androidx, or aosp) it's required to sign the CLA https://android-review.googlesource.com/settings/new-agreement so your contribution can be further upstreamed, or you may want to submit it directly to the upstream repo right away (skipping the JB fork repo - different project setup) - https://source.android.com/docs/setup/contribute/submit-patches.

eymar added a commit to JetBrains/compose-multiplatform-core that referenced this issue Nov 16, 2022
Issue JetBrains/compose-multiplatform#2466

Co-Authored-By: Silas <s.develop@4-dc.de>
@asapha
Copy link

asapha commented Nov 16, 2022

There's an existing issue on Google's issue tracker by the way.

eymar added a commit to JetBrains/compose-multiplatform-core that referenced this issue Nov 17, 2022
Issue JetBrains/compose-multiplatform#2466

Co-Authored-By: Silas <s.develop@4-dc.de>
eymar added a commit to JetBrains/compose-multiplatform-core that referenced this issue Nov 17, 2022
Issue JetBrains/compose-multiplatform#2466

Co-Authored-By: Silas <s.develop@4-dc.de>

Co-authored-by: Silas <s.develop@4-dc.de>
@eymar
Copy link
Collaborator

eymar commented Nov 17, 2022

merged the fixed into JB fork for now. It has to be upstreamed.

igordmn pushed a commit to JetBrains/compose-multiplatform-core that referenced this issue Dec 13, 2022
Issue JetBrains/compose-multiplatform#2466

Co-Authored-By: Silas <s.develop@4-dc.de>

Co-authored-by: Silas <s.develop@4-dc.de>
eymar added a commit to JetBrains/compose-multiplatform-core that referenced this issue Jan 13, 2023
Issue JetBrains/compose-multiplatform#2466

Co-Authored-By: Silas <s.develop@4-dc.de>

Co-authored-by: Silas <s.develop@4-dc.de>
@eymar eymar closed this as completed Apr 24, 2023
MatkovIvan pushed a commit to MatkovIvan/compose-multiplatform that referenced this issue May 10, 2023
Issue JetBrains#2466

Co-Authored-By: Silas <s.develop@4-dc.de>

Co-authored-by: Silas <s.develop@4-dc.de>
igordmn pushed a commit to JetBrains/compose-multiplatform-core that referenced this issue Nov 15, 2023
Issue JetBrains/compose-multiplatform#2466

Co-Authored-By: Silas <s.develop@4-dc.de>

Co-authored-by: Silas <s.develop@4-dc.de>
igordmn pushed a commit to JetBrains/compose-multiplatform-core that referenced this issue Nov 16, 2023
…in TextField (#329)

Issue JetBrains/compose-multiplatform#2466

Co-Authored-By: Silas <s.develop@4-dc.de>

Co-authored-by: Silas <s.develop@4-dc.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crash input Touch, mouse, keyboard input related p:high High priority regression wait for build
Projects
None yet
Development

No branches or pull requests

4 participants