bevyengine / bevyengine/bevy

IME underline is sometimes wrong

Open
#23,915 0 comments 0 reactions 0 assignees View on GitHub
A-Input A-UI C-Bug D-Modest S-Needs-Investigation X-Uncontroversial
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

After doing some debugging regarding some strange behavior while typing in Japanese and Korean where an underline can appear later in the text field if appended after committed text, I found that there are *two* glyph runs in a text input box in that case, one starting at x = 0 and one starting at the index where the new IME pre commit string is starting, and they both contain the same `visual_clusters`. This results in an extra underline being drawn later in the text field under future empty space.

Note: This doesn’t seem to affect Chinese IME. in Chinese, it seems that there’s only one glyph run after every commit, where the index is placed at where the new IME pre commit string is starting, but it seems to calculate the underline correctly.

I have print statements like this in this code:

```rust
{
let mut x: f32 = glyph_run.offset();
let mut underline_start_x = None;
let mut underline_end_x = x;

println!("starting underline rect at {x}");

for cluster in run.visual_clusters() {
let ct = cluster.text_range();
println!("x: {x}, ranges: {run_text_range:?} {cr:?} {ct:?}");
if ct.start < cr.end && ct.end > cr.start {
underline_start_x.get_or_insert(x);
underline_end_x = x + cluster.advance();
}
x += cluster.advance();
}

if let Some(start_x) = underline_start_x {

println!("{start_x} {underline_end_x}");
info.preedit_underline_rects.push(Rect {
min: Vec2::new(start_x, underline_y),
max: Vec2::new(
underline_end_x,
underline_y + underline_thickness,
),
});
}
}
```

and it results in console input like this:
```
starting underline rect at 0
x: 0, ranges: 0..21 15..21 0..3
x: 64, ranges: 0..21 15..21 3..6
x: 128, ranges: 0..21 15..21 6..9
x: 192, ranges: 0..21 15..21 9..12
x: 256, ranges: 0..21 15..21 12..15
x: 320, ranges: 0..21 15..21 15..18
x: 384, ranges: 0..21 15..21 18..21
320 448
starting underline rect at 320
x: 320, ranges: 0..21 15..21 0..3
x: 384, ranges: 0..21 15..21 3..6
x: 448, ranges: 0..21 15..21 6..9
x: 512, ranges: 0..21 15..21 9..12
x: 576, ranges: 0..21 15..21 12..15
x: 640, ranges: 0..21 15..21 15..18
x: 704, ranges: 0..21 15..21 18..21
640 768
```

For text that looks like this (I had already checked out the branch and applied my suggestion above regarding the duplicate line inserted):
Screenshot 2026-04-20 at 11 21 07 PM

To reproduce:
1) type in “arigatou” but in jp first, then press enter to commit that phrase
2) type in “ari” afterwards

_Originally posted by @kfc35 in https://github.com/bevyengine/bevy/pull/23841#discussion_r3114831077_

Contributor guide

Open the contributing guide

Research direction

Start with the IME underline and glyph-run code shown in the issue, then reproduce the Japanese and Korean sequence: type “arigatou” in Japanese, commit it, and type “ari”. Inspect why duplicate glyph runs produce duplicate underline rectangles; done means the preedit text has one correctly positioned underline without affecting Chinese IME behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.