Fix backspacing leaving last character in IME prediction not removed on macOS native and Safari#7810
Merged
emilk merged 4 commits intoemilk:mainfrom Jan 5, 2026
Conversation
|
Preview available at https://egui-pr-preview.github.io/pr/7810-fix-ime-backspacing-simpler-approach View snapshot changes at kitdiff |
emilk
approved these changes
Jan 5, 2026
1 task
1 task
emilk
pushed a commit
that referenced
this pull request
Mar 16, 2026
<!-- 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 My PR that fixes the macOS backspacing issue (#7810) unfortunately breaks text selection on Wayland (Fedora KDE Plasma Desktop 43 [Wayland, with or without IBus]). I had actually tested on a Wayland setup but failed to notice that :( Windows and Linux+X11 (Debian 13 [Cinnamon 6.4.10 + X11 + fcitx5 5.1.2]) are not affected. This PR fixes the issue by restricting the macOS fix to macOS-only. <details><summary>Here is the correct behavior on Wayland after this PR (and before #7810 is applied)</summary>  </details> <details><summary>Here is the buggy behavior on Wayland before this PR</summary>  </details> ## Cause of the Wayland issue On Wayland, `winit` constantly emits `winit::event::Ime::Preedit("", None)` events. PR #7810 added these lines for handling `winit::event::Ime::Preedit(_, None)` in `egui-winit` without considering the `target_os`: https://github.com/emilk/egui/blob/14afefa2521d1baaf4fd02105eec2d3727a7ac36/crates/egui-winit/src/lib.rs#L619-L621 As a result, while text is being selected, `egui-winit` receives these `winit::event::Ime::Preedit("", None)` events from `winit` and forwards them to `egui` as `egui::ImeEvent::Preedit("")`. `egui` then clears the current text selection, because it currently does not distinguish between IME pre-edit text and selected text. --------- Co-authored-by: lucasmerlin <[email protected]>
emilk
pushed a commit
that referenced
this pull request
Mar 24, 2026
<!-- 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 #7809 * Closes #7876 * Closes #7908 * Supersedes #7877 * Supersedes #7898 * The author of the PR above replaced it with #7914, which additionally fixes another IME issue. I believe that fix deserves a separate PR. * Reverts #4794 * [x] I have followed the instructions in the PR template This approach is better than #7898 (#7914) because it correctly handles all three major IME types (Chinese, Japanese, and Korean) without requiring a predefined “IME mode”. ## Environments I haved tested this PR in <details><summary>macOS 15.7.3 (AArch64, Host of other virtual machines)</summary> Run command: `cargo run -p egui_demo_app --release` Tested IMEs: - builtin Chinese IME (Shuangpin - Simplified) - builtin Japanese IME (Romaji) - builtin Korean IME (2-Set) </details> <details><summary>Windows 11 25H2 (AArch64, Virtual Machine)</summary> Build command: `cargo build --release -p egui_demo_app --target=x86_64-pc-windows-gnu --features=glow --no-default-features` (I cannot use `wgpu` due to [this bug](#4381), which prevents debugging inside the VM. Anyways, the rendering backend should be irrelevant here.) Tested IMEs: - builtin Chinese IME (Shuangpin) - Sogou IME (Chinese Shuangpin) - WeType IME (Chinese Shuangpin) - builtin Japanese IME (Hiragana) - builtin Korean IME (2 Beolsik) </details> <details><summary>Linux [Wayland + IBus] (AArch64, Virtual Machine)</summary> Fedora KDE Plasma Desktop 43 [Wayland + IBus 1.5.33-rc2] (Not working at the moment because of [another issue](#7485) that will be fixed by #7983. It is [a complicated story](#7973 (comment)). ) > [!NOTE] > > IBus is partially broken in this system. The Input Method Selector refuses to select IBus. As a workaround, I have to open System Settings -> Virtual Keyboard and select “IBus Wayland” to start an IBus instance that works in egui. > > The funny thing is: the Chinese Intelligent Pinyin IME is broken in native Apps like System Settings and KWrite, but works correctly in egui! > > <details><summary>Screencast: What</summary> > >  > </details> Build command: `cross build --release -p egui_demo_app --target=aarch64-unknown-linux-gnu --features=wayland,wgpu --no-default-features` (The Linux toolchain on my mac is somehow broken, so I used `cross` instead.) Tested IMEs: - Chinese Intelligent Pinyin IME (Shuangpin) - Japanese Anthy IME (Hiragana) - Korean Hangul IME </details> <details><summary>Linux [X11 + Fcitx5] (AArch64, Virtual Machine)</summary> Debian 13 [Cinnamon 6.4.10 + X11 + Fcitx5 5.1.2] Build command: `cross build --release -p egui_demo_app --target=aarch64-unknown-linux-gnu --features=x11,wgpu --no-default-features` Tested IMEs: - Chinese Shuangpin IME - Chinese Rime IME with `luna-pinyin` - Japanese Mozc IME (Hiragana) - Korean Hangul IME Unlike macOS and Linux + Wayland, key-release events for keys processed by the IME are still forwarded to `egui`. These appear to be harmless in practice. Unlike on Windows, however, they cannot be filtered reliably because there are no corresponding key-press events marked as “processed by IME”. </details> --- There are too many possible combinations to test (Operating Systems × [Desktop Environment](https://en.wikipedia.org/wiki/Desktop_environment)s × [Windowing System](https://en.wikipedia.org/wiki/Windowing_system)s × [IMF](https://wiki.archlinux.org/title/Input_method#Input_method_framework)s × [IME](https://en.wikipedia.org/wiki/Input_method)s × …), and I only have access to a limited subset. For example, Google Japanese Input refused to install on my Windows VM, and some paid Japanese IMEs are not accessible to me. Therefore, I would appreciate feedback from people other than me using all kinds of environments. ## Details There are two possible approaches to removing keyboard events that have already been processed by an IME: * Approach 1: Filter out events inside `egui` that appear to have been received during IME composition. * Approach 2: Filter out such events in the platform backend (terminology [borrowed from imgui](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md#using-standard-backends), e.g. the `egui-winit` crate or the code under `web/` in the `eframe` crate.). Both approaches already exist in `egui`: * #4794 uses the first approach, filtering these events in the `TextEdit`-related code. * `eframe` uses the second approach in its web integration. See: <https://github.com/emilk/egui/blob/14afefa2521d1baaf4fd02105eec2d3727a7ac36/crates/eframe/src/web/events.rs#L173-L176> Compared to the first approach, the second has a clear advantage: when events are passed from the platform backends into `egui`, they are simplified and lose information. In contrast, events in the platform backends are the original events, which allows them to be handled more flexibly. This is also why #7898 (#7914), which attempts to address the issue from within the `egui` crate, struggles to make all IMEs work correctly at the same time and requires manually selecting an “IME mode”: the events received by `egui` have already been reduced and therefore lack necessary information. A more appropriate solution is to consistently follow the second approach, explicitly requiring platform backends not to forward events that have already been processed by the IME to `egui`. This is the method used in this PR. Specifically, this PR works within the `egui-winit` crate, where the original `KeyboardInput` events can be accessed. At least for key press events, these can be used directly to determine whether the event has already been processed by the IME on Windows (by checking whether `logical_key` equals `winit::keyboard::NamedKey::Process`). This makes it straightforward to ensure that all IMEs work correctly at the same time. This PR also reverts #4794, which took the first approach. It filters out some events that merely look like they were received during IME composition but actually are not. It also messes up the order of those events along the way. As a result, it caused several IME-related issues. One of the sections in the Demonstrations below will illustrate these problems. ## Demonstrations <details><summary>Changes not included in this PR for displaying Unicode characters in demonstrations</summary> Download `unifont-17.0.03.otf` from <https://unifoundry.com/pub/unifont/unifont-17.0.03/font-builds/>, and place it at `crates/egui_demo_app/src/unifont-17.0.03.otf`. In `crates/egui_demo_app/src/wrap_app.rs`, add these lines at the beginning of `impl WrapApp`'s `pub fn new`: ```rust { const MAIN_FONT: &'static [u8] = include_bytes!("./unifont-17.0.03.otf"); let mut fonts = egui::FontDefinitions::default(); fonts.font_data.insert( "main-font".to_owned(), std::sync::Arc::new(egui::FontData::from_static(MAIN_FONT)), ); let proportional = fonts .families .entry(egui::FontFamily::Proportional) .or_default(); proportional.insert(0, "main-font".to_owned()); cc.egui_ctx.set_fonts(fonts); } ``` (I took this from somewhere, but I forgot where it is. Sorry…) </details> [GNU Unifont](https://unifoundry.com/unifont/index.html) is licensed under [OFL-1.1](https://unifoundry.com/OFL-1.1.txt). ### This PR Fixes: Focus on a single-line `TextEdit` is lost after completing candidate selection with Japanese IME on Windows (#7809) <details><summary>Screencast: ✅ Japanese IME now behaves correctly while Korean IME behaves as before</summary>  </details> ### This PR Fixes: Committing Japanese IME text with <kbd>Enter</kbd> inserts an unintended newline in multiline `TextEdit` on Windows (#7876) <details><summary>Screencast: ✅ Japanese IME now behaves correctly while Korean IME behaves as before</summary>  </details> ### This PR Fixes: Backspacing deletes characters during composition in certain Chinese IMEs (e.g., Sogou) on Windows (#7908) <details><summary>Screencast: ✅ Sogou IME now behaves correctly</summary>  </details> ### This PR Obsoletes #4794, because `egui` receives only IME events during composition from now on On Windows, “incompatible” events are filtered in `egui-winit`, aligning the behavior with other systems. <details><summary>Screencasts</summary> Some Chinese IMEs on Windows:  The default Japanese IMEs on Windows:  </details> The 2-set Korean IMEs handle arrow keys differently. It will be discussed in the next section. ### This PR Reverts #4794, because it introduced several bugs Some of its bugs have already been worked around in the past, but those workarounds might also be problematic. For example, #4912 is a workaround for a bug (#4908) introduced by #4794, and that workaround is in fact the root cause of the macOS backspacing bug I have worked around with #7810. (The reversion of #4912 is out of the scope of this PR, I will do that in #7983.) #### It Caused: Arrow keys are incorrectly blocked during typical Korean IME composition When composing Korean text using 2-Set IMEs, users should still be able to move the cursor with arrow keys regardless if the composition is committed. ##### Correct behavior <details><summary>Screencasts</summary> macOS TextEdit:  Windows Notepad:  With #4794 reverted, `egui` also behaves correctly (tested on Linux + Wayland, macOS, and Windows):  </details> ##### Incorrect behavior caused by #4794 `remove_ime_incompatible_events` removed arrow-key events in such cases. As a result, the first arrow key press only commits the composition, and users need to press the arrow key again to move the cursor: <details><summary>Screencast</summary>  </details> This is essentially the same issue described here: #7877 (comment) #### It Caused: Backspacing leaves the last character in Korean IME pre-edit text not removed on macOS <details><summary>Screencasts</summary> Before this PR:  After this PR:  </details> ### Korean IMEs also use <kbd>Enter</kbd> to confirm Hanja selections, and will not work properly in the Korean “IME mode” proposed by #7898 (#7914) <details><summary>Screencast: Korean IME using <kbd>Enter</kbd> and <kbd>Space</kbd> for confirmation (IBus Korean Hangul IME)</summary> The screencast below demonstrates that some Korean IMEs handle Hanja selection in a way similar to Japanese IMEs: the <kbd>Up</kbd>/<kbd>Down</kbd> arrow keys are used to navigate candidates, and <kbd>Enter</kbd> confirms the selected candidate.  </details> <details><summary>Screencasts: Another example</summary> Using the built-in Korean IME on Windows, I type two lines: the first line in Hangul, and the second line as the same word converted to Hanja. Correct behavior in Notepad (reference):  Behavior after applying this PR, which matches the Notepad behavior:  Behavior after applying #7914 with the “IME mode” set to Korean (which is also the behavior before this PR being applied):  On the second line, each time a Hanja character is confirmed, an unintended newline is inserted. This mirrors the Japanese IME issues that are supposed to be fixed by setting the “IME mode” to Japanese. (These Japanese IME issues are fixed in this PR as mentioned before.) </details>
1 task
Masterchef365
pushed a commit
to Masterchef365/egui
that referenced
this pull request
Apr 3, 2026
…on macOS native and Safari (emilk#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).)
Masterchef365
pushed a commit
to Masterchef365/egui
that referenced
this pull request
Apr 3, 2026
<!-- 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 My PR that fixes the macOS backspacing issue (emilk#7810) unfortunately breaks text selection on Wayland (Fedora KDE Plasma Desktop 43 [Wayland, with or without IBus]). I had actually tested on a Wayland setup but failed to notice that :( Windows and Linux+X11 (Debian 13 [Cinnamon 6.4.10 + X11 + fcitx5 5.1.2]) are not affected. This PR fixes the issue by restricting the macOS fix to macOS-only. <details><summary>Here is the correct behavior on Wayland after this PR (and before emilk#7810 is applied)</summary>  </details> <details><summary>Here is the buggy behavior on Wayland before this PR</summary>  </details> ## Cause of the Wayland issue On Wayland, `winit` constantly emits `winit::event::Ime::Preedit("", None)` events. PR emilk#7810 added these lines for handling `winit::event::Ime::Preedit(_, None)` in `egui-winit` without considering the `target_os`: https://github.com/emilk/egui/blob/14afefa2521d1baaf4fd02105eec2d3727a7ac36/crates/egui-winit/src/lib.rs#L619-L621 As a result, while text is being selected, `egui-winit` receives these `winit::event::Ime::Preedit("", None)` events from `winit` and forwards them to `egui` as `egui::ImeEvent::Preedit("")`. `egui` then clears the current text selection, because it currently does not distinguish between IME pre-edit text and selected text. --------- Co-authored-by: lucasmerlin <[email protected]>
Masterchef365
pushed a commit
to Masterchef365/egui
that referenced
this pull request
Apr 3, 2026
<!-- 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 emilk#7809 * Closes emilk#7876 * Closes emilk#7908 * Supersedes emilk#7877 * Supersedes emilk#7898 * The author of the PR above replaced it with emilk#7914, which additionally fixes another IME issue. I believe that fix deserves a separate PR. * Reverts emilk#4794 * [x] I have followed the instructions in the PR template This approach is better than emilk#7898 (emilk#7914) because it correctly handles all three major IME types (Chinese, Japanese, and Korean) without requiring a predefined “IME mode”. ## Environments I haved tested this PR in <details><summary>macOS 15.7.3 (AArch64, Host of other virtual machines)</summary> Run command: `cargo run -p egui_demo_app --release` Tested IMEs: - builtin Chinese IME (Shuangpin - Simplified) - builtin Japanese IME (Romaji) - builtin Korean IME (2-Set) </details> <details><summary>Windows 11 25H2 (AArch64, Virtual Machine)</summary> Build command: `cargo build --release -p egui_demo_app --target=x86_64-pc-windows-gnu --features=glow --no-default-features` (I cannot use `wgpu` due to [this bug](emilk#4381), which prevents debugging inside the VM. Anyways, the rendering backend should be irrelevant here.) Tested IMEs: - builtin Chinese IME (Shuangpin) - Sogou IME (Chinese Shuangpin) - WeType IME (Chinese Shuangpin) - builtin Japanese IME (Hiragana) - builtin Korean IME (2 Beolsik) </details> <details><summary>Linux [Wayland + IBus] (AArch64, Virtual Machine)</summary> Fedora KDE Plasma Desktop 43 [Wayland + IBus 1.5.33-rc2] (Not working at the moment because of [another issue](emilk#7485) that will be fixed by emilk#7983. It is [a complicated story](emilk#7973 (comment)). ) > [!NOTE] > > IBus is partially broken in this system. The Input Method Selector refuses to select IBus. As a workaround, I have to open System Settings -> Virtual Keyboard and select “IBus Wayland” to start an IBus instance that works in egui. > > The funny thing is: the Chinese Intelligent Pinyin IME is broken in native Apps like System Settings and KWrite, but works correctly in egui! > > <details><summary>Screencast: What</summary> > >  > </details> Build command: `cross build --release -p egui_demo_app --target=aarch64-unknown-linux-gnu --features=wayland,wgpu --no-default-features` (The Linux toolchain on my mac is somehow broken, so I used `cross` instead.) Tested IMEs: - Chinese Intelligent Pinyin IME (Shuangpin) - Japanese Anthy IME (Hiragana) - Korean Hangul IME </details> <details><summary>Linux [X11 + Fcitx5] (AArch64, Virtual Machine)</summary> Debian 13 [Cinnamon 6.4.10 + X11 + Fcitx5 5.1.2] Build command: `cross build --release -p egui_demo_app --target=aarch64-unknown-linux-gnu --features=x11,wgpu --no-default-features` Tested IMEs: - Chinese Shuangpin IME - Chinese Rime IME with `luna-pinyin` - Japanese Mozc IME (Hiragana) - Korean Hangul IME Unlike macOS and Linux + Wayland, key-release events for keys processed by the IME are still forwarded to `egui`. These appear to be harmless in practice. Unlike on Windows, however, they cannot be filtered reliably because there are no corresponding key-press events marked as “processed by IME”. </details> --- There are too many possible combinations to test (Operating Systems × [Desktop Environment](https://en.wikipedia.org/wiki/Desktop_environment)s × [Windowing System](https://en.wikipedia.org/wiki/Windowing_system)s × [IMF](https://wiki.archlinux.org/title/Input_method#Input_method_framework)s × [IME](https://en.wikipedia.org/wiki/Input_method)s × …), and I only have access to a limited subset. For example, Google Japanese Input refused to install on my Windows VM, and some paid Japanese IMEs are not accessible to me. Therefore, I would appreciate feedback from people other than me using all kinds of environments. ## Details There are two possible approaches to removing keyboard events that have already been processed by an IME: * Approach 1: Filter out events inside `egui` that appear to have been received during IME composition. * Approach 2: Filter out such events in the platform backend (terminology [borrowed from imgui](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md#using-standard-backends), e.g. the `egui-winit` crate or the code under `web/` in the `eframe` crate.). Both approaches already exist in `egui`: * emilk#4794 uses the first approach, filtering these events in the `TextEdit`-related code. * `eframe` uses the second approach in its web integration. See: <https://github.com/emilk/egui/blob/14afefa2521d1baaf4fd02105eec2d3727a7ac36/crates/eframe/src/web/events.rs#L173-L176> Compared to the first approach, the second has a clear advantage: when events are passed from the platform backends into `egui`, they are simplified and lose information. In contrast, events in the platform backends are the original events, which allows them to be handled more flexibly. This is also why emilk#7898 (emilk#7914), which attempts to address the issue from within the `egui` crate, struggles to make all IMEs work correctly at the same time and requires manually selecting an “IME mode”: the events received by `egui` have already been reduced and therefore lack necessary information. A more appropriate solution is to consistently follow the second approach, explicitly requiring platform backends not to forward events that have already been processed by the IME to `egui`. This is the method used in this PR. Specifically, this PR works within the `egui-winit` crate, where the original `KeyboardInput` events can be accessed. At least for key press events, these can be used directly to determine whether the event has already been processed by the IME on Windows (by checking whether `logical_key` equals `winit::keyboard::NamedKey::Process`). This makes it straightforward to ensure that all IMEs work correctly at the same time. This PR also reverts emilk#4794, which took the first approach. It filters out some events that merely look like they were received during IME composition but actually are not. It also messes up the order of those events along the way. As a result, it caused several IME-related issues. One of the sections in the Demonstrations below will illustrate these problems. ## Demonstrations <details><summary>Changes not included in this PR for displaying Unicode characters in demonstrations</summary> Download `unifont-17.0.03.otf` from <https://unifoundry.com/pub/unifont/unifont-17.0.03/font-builds/>, and place it at `crates/egui_demo_app/src/unifont-17.0.03.otf`. In `crates/egui_demo_app/src/wrap_app.rs`, add these lines at the beginning of `impl WrapApp`'s `pub fn new`: ```rust { const MAIN_FONT: &'static [u8] = include_bytes!("./unifont-17.0.03.otf"); let mut fonts = egui::FontDefinitions::default(); fonts.font_data.insert( "main-font".to_owned(), std::sync::Arc::new(egui::FontData::from_static(MAIN_FONT)), ); let proportional = fonts .families .entry(egui::FontFamily::Proportional) .or_default(); proportional.insert(0, "main-font".to_owned()); cc.egui_ctx.set_fonts(fonts); } ``` (I took this from somewhere, but I forgot where it is. Sorry…) </details> [GNU Unifont](https://unifoundry.com/unifont/index.html) is licensed under [OFL-1.1](https://unifoundry.com/OFL-1.1.txt). ### This PR Fixes: Focus on a single-line `TextEdit` is lost after completing candidate selection with Japanese IME on Windows (emilk#7809) <details><summary>Screencast: ✅ Japanese IME now behaves correctly while Korean IME behaves as before</summary>  </details> ### This PR Fixes: Committing Japanese IME text with <kbd>Enter</kbd> inserts an unintended newline in multiline `TextEdit` on Windows (emilk#7876) <details><summary>Screencast: ✅ Japanese IME now behaves correctly while Korean IME behaves as before</summary>  </details> ### This PR Fixes: Backspacing deletes characters during composition in certain Chinese IMEs (e.g., Sogou) on Windows (emilk#7908) <details><summary>Screencast: ✅ Sogou IME now behaves correctly</summary>  </details> ### This PR Obsoletes emilk#4794, because `egui` receives only IME events during composition from now on On Windows, “incompatible” events are filtered in `egui-winit`, aligning the behavior with other systems. <details><summary>Screencasts</summary> Some Chinese IMEs on Windows:  The default Japanese IMEs on Windows:  </details> The 2-set Korean IMEs handle arrow keys differently. It will be discussed in the next section. ### This PR Reverts emilk#4794, because it introduced several bugs Some of its bugs have already been worked around in the past, but those workarounds might also be problematic. For example, emilk#4912 is a workaround for a bug (emilk#4908) introduced by emilk#4794, and that workaround is in fact the root cause of the macOS backspacing bug I have worked around with emilk#7810. (The reversion of emilk#4912 is out of the scope of this PR, I will do that in emilk#7983.) #### It Caused: Arrow keys are incorrectly blocked during typical Korean IME composition When composing Korean text using 2-Set IMEs, users should still be able to move the cursor with arrow keys regardless if the composition is committed. ##### Correct behavior <details><summary>Screencasts</summary> macOS TextEdit:  Windows Notepad:  With emilk#4794 reverted, `egui` also behaves correctly (tested on Linux + Wayland, macOS, and Windows):  </details> ##### Incorrect behavior caused by emilk#4794 `remove_ime_incompatible_events` removed arrow-key events in such cases. As a result, the first arrow key press only commits the composition, and users need to press the arrow key again to move the cursor: <details><summary>Screencast</summary>  </details> This is essentially the same issue described here: emilk#7877 (comment) #### It Caused: Backspacing leaves the last character in Korean IME pre-edit text not removed on macOS <details><summary>Screencasts</summary> Before this PR:  After this PR:  </details> ### Korean IMEs also use <kbd>Enter</kbd> to confirm Hanja selections, and will not work properly in the Korean “IME mode” proposed by emilk#7898 (emilk#7914) <details><summary>Screencast: Korean IME using <kbd>Enter</kbd> and <kbd>Space</kbd> for confirmation (IBus Korean Hangul IME)</summary> The screencast below demonstrates that some Korean IMEs handle Hanja selection in a way similar to Japanese IMEs: the <kbd>Up</kbd>/<kbd>Down</kbd> arrow keys are used to navigate candidates, and <kbd>Enter</kbd> confirms the selected candidate.  </details> <details><summary>Screencasts: Another example</summary> Using the built-in Korean IME on Windows, I type two lines: the first line in Hangul, and the second line as the same word converted to Hanja. Correct behavior in Notepad (reference):  Behavior after applying this PR, which matches the Notepad behavior:  Behavior after applying emilk#7914 with the “IME mode” set to Korean (which is also the behavior before this PR being applied):  On the second line, each time a Hanja character is confirmed, an unintended newline is inserted. This mirrors the Japanese IME issues that are supposed to be fixed by setting the “IME mode” to Japanese. (These Japanese IME issues are fixed in this PR as mentioned before.) </details>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Before the fix
After the fix
(The font used in the screenshots is GNU Unifont, licensed under OFL-1.1.txt.)