Improve robustness of TextAgent in eframe/web#8045
Improve robustness of TextAgent in eframe/web#8045umajho wants to merge 12 commits intoemilk:mainfrom
TextAgent in eframe/web#8045Conversation
|
Preview available at https://egui-pr-preview.github.io/pr/8045-fix-cheonjiin View snapshot changes at kitdiff |
|
@rustbasic Hello. I'd appreciate it if you could test whether this solution works with the Cheonjiin IME you are using. It would also be very helpful if you could try this in other web setups to check for any regressions. Thanks in advance. |
| /// | ||
| /// `before_chars` and `after_chars` are the number of characters (not | ||
| /// bytes) to delete before and after the cursor, respectively. | ||
| DeleteSurrounding { |
There was a problem hiding this comment.
This is actually not an ad hoc variant introduced just for this PR. A variant with the same name was added to winit in 0.31 (though in this implementation, the fields are defined as *_chars rather than *_bytes).
https://docs.rs/winit/0.31.0-beta.2/winit/event/enum.Ime.html#variant.DeleteSurrounding
|
I can confirm this PR fixes the 2 issues mentioned in #8046, at least on my device. |
|
@umajho rustbasic-2026-03-31.mp4 |
|
Wow, that's bad. If you go Could you also check https://stackblitz.com/edit/egui-text-agent-experiment and record what it looks like when you input text? For reference, here is how GBoard behaves on the demo: |
|
Are you asking for the keyboard settings screen first? Here it is. 삼성키보드 = SAMSUNG Keyboard image blured. |
rustbasic-2026-03-31-21-16-53.mp4 |
|
With the changes mentioned in the comment, I get the best result when I modify However, there is still an issue: when ImeEvent::Commit(commit_text) => {
if commit_text == "\n" || commit_text == "\r" {
None
} else {
let mut ccursor = cursor_range.primary;
state.ime_enabled = false;
if !commit_text.is_empty()
&& cursor_range.secondary.index
== state.ime_cursor_range.secondary.index
{
ccursor = clear_preedit_text(text, &cursor_range);
text.insert_text_at(&mut ccursor, commit_text, char_limit);
}
Some(CCursorRange::one(ccursor))
}
}rustbasic-2026-03-31-21-48-00.mp4 |
Yes, thanks for the information. Sorry, my instructions were not clear. You need to go to the “preview” tab.
Thanks for the suggested changes. I will check them tomorrow. |
rustbasic-2026-03-31-23-32-37.mp4 |
|
@rustbasic I have made some changes. does this improve things? The stackblitz page has also been updated to reflect the changes. |
|
It appears to be fixable, since the issue does not occur when "않았다" is entered consecutively without any problems.
rustbasic-2026-04-01-18-46-25.mp4
rustbasic-2026-04-01-18-49-07.mp4 |
|
It appears to be fixable, since it works correctly when "않았다" is entered continuously. However, if you enter "않", wait briefly for a commit to occur, and then enter the next character, "않" gets duplicated. Result 1-1) "않않았다" rustbasic-2026-04-01-19-01-15.mp4If you enter "안", wait briefly for a commit to occur, and then enter the next character, "안" gets duplicated. Result 2-1) "안않았다" rustbasic-2026-04-01-19-11-08.mp4 |
|
Is this auto-committing behavior expected? I will try to figure out how to fix the problem tomorrow. |
|
Sorry for the delayed response. Update: |
# Conflicts: # crates/eframe/src/web/text_agent.rs # crates/egui/src/widgets/text_edit/builder.rs
|
@rustbasic Glad to hear that! Could you also try #8068? It also looks promising for addressing the Cheonjiin issue you encountered. |
Oops. This is actually the result of an intentional action. However, I didn't expect that this would cause problems with virtual keyboards. A better approach might be to introduce something like For example, on web, we could reuse this trick to reset the IME without causing flickering: input.blur().ok();
input.focus().ok();(It is late here, so my next reply may take a few hours.) |
|
It's likely that either set_value or set_selection_range on the |
|
@cjgriscom The flickering issue should be fixed by #8078. |
… keyboard flickering on web (#8078) * Closes N/A * Partially replaces #7983 * Related: #8045 * [x] I have followed the instructions in the PR template ## Details In #7983, I modified `Memory::request_focus` to interrupt any ongoing IME composition. This fixed a bug where clicking inside an already focused `TextEdit` failed to cancel the active composition, resulting in duplicated text: #8045 (comment) To avoid introducing API changes in that PR, I ensured the IME state was reset by forcing `PlatformOutput::ime` to `None` for at least one frame. While this works well on desktop platforms, it causes virtual keyboard flickering on the web: #8045 (comment) In this PR, I delegate the responsibility for handling IME composition interruptions to integrations, allowing each integration to decide how to interrupt compositions in a flexible manner. ### The new field `should_interrupt_composition` on `IMEOutput`. Instead of introducing a new `OutputCommand` variant, this PR adds a new field `should_interrupt_composition` to `IMEOutput`. Interrupting an active composition is only meaningful when IME remains allowed. If IME should be disabled altogether, `PlatformOutput::ime` can simply be set to `None`. Given this, IMO, it is more appropriate to attach the interrupt signal to `IMEOutput` (i.e., the type of `PlatformOutput::ime`).
# Conflicts: # crates/eframe/src/web/text_agent.rs




owns_ime_eventsonMemory#7983This PR primarily aims to address an issue with the Samsung Keyboard Korean Cheonjiin layout found by @rustbasic.
Since I don't have access to the same environment, I'll need to rely on their feedback for validation.
Additionally, I need to gather feedback on whether these changes introduce regressions in other setups, so this PR is not ready.
See also: https://stackblitz.com/edit/egui-text-agent-experiment?file=src%2FApp.tsx