mirror of
https://github.com/emilk/egui.git
synced 2026-08-30 13:20:05 -04:00
Fix backspacing leaving last character in IME prediction not removed on macOS native and Safari (#7810)
<!-- Please read the "Making a PR" section of [`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md) before opening a Pull Request! * Keep your PR:s small and focused. * The PR title is what ends up in the changelog, so make it descriptive! * If applicable, add a screenshot or gif. * If it is a non-trivial addition, consider adding a demo for it to `egui_demo_lib`, or a new example. * Do NOT open PR:s from your `master` branch, as that makes it hard for maintainers to test and add commits to your PR. * Remember to run `cargo fmt` and `cargo clippy`. * Open the PR as a draft until you have self-reviewed it and run `./scripts/check.sh`. * When you have addressed a PR comment, mark it as resolved. Please be patient! I will review your PR, but my time is limited! --> * Closes N/A * [x] I have followed the instructions in the PR template ## Before the fix | Platform | Screenshot | | - | - | | macOS native |  | | Safari |  | ## After the fix | Platform | Screenshot | | - | - | | macOS native |  | | Safari |  | (The font used in the screenshots is [GNU Unifont](https://unifoundry.com/unifont/index.html), licensed under [OFL-1.1.txt](https://unifoundry.com/OFL-1.1.txt).)
This commit is contained in:
@@ -1065,51 +1065,73 @@ fn events(
|
||||
..
|
||||
} => check_for_mutating_key_press(os, &cursor_range, text, galley, modifiers, *key),
|
||||
|
||||
Event::Ime(ime_event) => match ime_event {
|
||||
ImeEvent::Enabled => {
|
||||
state.ime_enabled = true;
|
||||
state.ime_cursor_range = cursor_range;
|
||||
None
|
||||
Event::Ime(ime_event) => {
|
||||
/// Empty prediction can be produced with [`ImeEvent::Preedit`]
|
||||
/// or [`ImeEvent::Commit`] when user press backspace or escape
|
||||
/// during IME, so this function should be called in both cases
|
||||
/// to clear current text.
|
||||
///
|
||||
/// Example platforms where only `ImeEvent::Preedit("")` of
|
||||
/// those two events is emitted when the last character in the
|
||||
/// prediction is deleted:
|
||||
/// - macOS 15.7.3.
|
||||
/// - Debian13 with gnome48 and wayland.
|
||||
///
|
||||
/// An example platform where only `ImeEvent::Commit("")` of
|
||||
/// those two events is emitted when the last character in the
|
||||
/// prediction is deleted:
|
||||
/// - Safari 26.2 (on macOS 15.7.3).
|
||||
fn clear_prediction(
|
||||
text: &mut dyn TextBuffer,
|
||||
cursor_range: &CCursorRange,
|
||||
) -> CCursor {
|
||||
text.delete_selected(cursor_range)
|
||||
}
|
||||
ImeEvent::Preedit(text_mark) => {
|
||||
if text_mark == "\n" || text_mark == "\r" {
|
||||
None
|
||||
} else {
|
||||
// Empty prediction can be produced when user press backspace
|
||||
// or escape during IME, so we clear current text.
|
||||
let mut ccursor = text.delete_selected(&cursor_range);
|
||||
let start_cursor = ccursor;
|
||||
if !text_mark.is_empty() {
|
||||
text.insert_text_at(&mut ccursor, text_mark, char_limit);
|
||||
}
|
||||
state.ime_cursor_range = cursor_range;
|
||||
Some(CCursorRange::two(start_cursor, ccursor))
|
||||
}
|
||||
}
|
||||
ImeEvent::Commit(prediction) => {
|
||||
if prediction == "\n" || prediction == "\r" {
|
||||
None
|
||||
} else {
|
||||
state.ime_enabled = false;
|
||||
|
||||
if !prediction.is_empty()
|
||||
&& cursor_range.secondary.index
|
||||
== state.ime_cursor_range.secondary.index
|
||||
{
|
||||
let mut ccursor = text.delete_selected(&cursor_range);
|
||||
text.insert_text_at(&mut ccursor, prediction, char_limit);
|
||||
Some(CCursorRange::one(ccursor))
|
||||
match ime_event {
|
||||
ImeEvent::Enabled => {
|
||||
state.ime_enabled = true;
|
||||
state.ime_cursor_range = cursor_range;
|
||||
None
|
||||
}
|
||||
ImeEvent::Preedit(text_mark) => {
|
||||
if text_mark == "\n" || text_mark == "\r" {
|
||||
None
|
||||
} else {
|
||||
let ccursor = cursor_range.primary;
|
||||
let mut ccursor = clear_prediction(text, &cursor_range);
|
||||
|
||||
let start_cursor = ccursor;
|
||||
if !text_mark.is_empty() {
|
||||
text.insert_text_at(&mut ccursor, text_mark, char_limit);
|
||||
}
|
||||
state.ime_cursor_range = cursor_range;
|
||||
Some(CCursorRange::two(start_cursor, ccursor))
|
||||
}
|
||||
}
|
||||
ImeEvent::Commit(prediction) => {
|
||||
if prediction == "\n" || prediction == "\r" {
|
||||
None
|
||||
} else {
|
||||
state.ime_enabled = false;
|
||||
|
||||
let mut ccursor = clear_prediction(text, &cursor_range);
|
||||
|
||||
if !prediction.is_empty()
|
||||
&& cursor_range.secondary.index
|
||||
== state.ime_cursor_range.secondary.index
|
||||
{
|
||||
text.insert_text_at(&mut ccursor, prediction, char_limit);
|
||||
}
|
||||
|
||||
Some(CCursorRange::one(ccursor))
|
||||
}
|
||||
}
|
||||
ImeEvent::Disabled => {
|
||||
state.ime_enabled = false;
|
||||
None
|
||||
}
|
||||
}
|
||||
ImeEvent::Disabled => {
|
||||
state.ime_enabled = false;
|
||||
None
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_ => None,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user