mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 06:40:06 -04:00
Delegate handling of IME interruptions to integrations to fix virtual 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: https://github.com/emilk/egui/pull/8045#issuecomment-4193310616 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: https://github.com/emilk/egui/pull/8045#issuecomment-4193035008 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`).
This commit is contained in:
@@ -1049,7 +1049,8 @@ impl State {
|
||||
self.set_cursor_icon(window, cursor_icon);
|
||||
|
||||
let allow_ime = ime.is_some();
|
||||
if self.allow_ime != allow_ime {
|
||||
let is_toggling_ime = self.allow_ime != allow_ime;
|
||||
if is_toggling_ime {
|
||||
self.allow_ime = allow_ime;
|
||||
#[cfg(target_os = "windows")]
|
||||
if !self.allow_ime {
|
||||
@@ -1066,6 +1067,14 @@ impl State {
|
||||
}
|
||||
|
||||
if let Some(ime) = ime {
|
||||
if !is_toggling_ime && ime.should_interrupt_composition {
|
||||
// TODO(umajho): use a more proper way to interrupt composition
|
||||
// if `winit` provides one in the future.
|
||||
|
||||
window.set_ime_allowed(false);
|
||||
window.set_ime_allowed(true);
|
||||
}
|
||||
|
||||
let pixels_per_point = pixels_per_point(&self.egui_ctx, window);
|
||||
let ime_rect_px = pixels_per_point * ime.rect;
|
||||
if self.ime_rect_px != Some(ime_rect_px)
|
||||
|
||||
Reference in New Issue
Block a user