Skip to content

Commit

Permalink
Fix continuous repaint on Wayland when TextEdit is focused or IME out…
Browse files Browse the repository at this point in the history
…put is not None (#4269)

* Closes #4254

Changes egui-winit so that it calls `window.set_ime_cursor_area` when
the IME rect changes or the user interacts with the application instead
of calling it every time the app is rendered. This works around a winit
bug that causes the app to continuously repaint under certain
circumstances on Wayland.

Tested on Wayland and on X11 using the text edit in the egui_demo_app -
no changes in IME functionality as far as I can tell. Untested on
non-Linux platforms.

---------

Co-authored-by: Emil Ernerfeldt <[email protected]>
  • Loading branch information
white-axe and emilk committed Apr 2, 2024
1 parent 648c5d6 commit 46dd8a8
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions crates/egui-winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ pub struct State {
accesskit: Option<accesskit_winit::Adapter>,

allow_ime: bool,
ime_rect_px: Option<egui::Rect>,
}

impl State {
Expand Down Expand Up @@ -139,6 +140,7 @@ impl State {
accesskit: None,

allow_ime: false,
ime_rect_px: None,
};

slf.egui_input
Expand Down Expand Up @@ -817,19 +819,26 @@ impl State {
}

if let Some(ime) = ime {
let rect = ime.rect;
let pixels_per_point = pixels_per_point(&self.egui_ctx, window);
crate::profile_scope!("set_ime_cursor_area");
window.set_ime_cursor_area(
winit::dpi::PhysicalPosition {
x: pixels_per_point * rect.min.x,
y: pixels_per_point * rect.min.y,
},
winit::dpi::PhysicalSize {
width: pixels_per_point * rect.width(),
height: pixels_per_point * rect.height(),
},
);
let ime_rect_px = pixels_per_point * ime.rect;
if self.ime_rect_px != Some(ime_rect_px)
|| self.egui_ctx.input(|i| !i.events.is_empty())
{
self.ime_rect_px = Some(ime_rect_px);
crate::profile_scope!("set_ime_cursor_area");
window.set_ime_cursor_area(
winit::dpi::PhysicalPosition {
x: ime_rect_px.min.x,
y: ime_rect_px.min.y,
},
winit::dpi::PhysicalSize {
width: ime_rect_px.width(),
height: ime_rect_px.height(),
},
);
}
} else {
self.ime_rect_px = None;
}

#[cfg(feature = "accesskit")]
Expand Down

0 comments on commit 46dd8a8

Please sign in to comment.