Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: On windows, Strange IME display #4652

Closed
wants to merge 13 commits into from
4 changes: 2 additions & 2 deletions crates/eframe/src/native/glow_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -652,8 +652,6 @@ impl GlowWinitRunning {
let gl_surface = viewport.gl_surface.as_ref().unwrap();
let egui_winit = viewport.egui_winit.as_mut().unwrap();

egui_winit.handle_platform_output(&window, platform_output);

let clipped_primitives = integration.egui_ctx.tessellate(shapes, pixels_per_point);

{
Expand Down Expand Up @@ -734,6 +732,8 @@ impl GlowWinitRunning {
}
}

egui_winit.handle_platform_output(&window, platform_output);

glutin.handle_viewport_output(event_loop, &integration.egui_ctx, &viewport_output);

integration.report_frame_time(frame_timer.total_time_sec()); // don't count auto-save time as part of regular frame time
Expand Down
4 changes: 2 additions & 2 deletions crates/eframe/src/native/wgpu_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,8 +663,6 @@ impl WgpuWinitRunning {
return EventResult::Wait;
};

egui_winit.handle_platform_output(window, platform_output);

let clipped_primitives = egui_ctx.tessellate(shapes, pixels_per_point);

let screenshot_requested = viewport
Expand Down Expand Up @@ -718,6 +716,8 @@ impl WgpuWinitRunning {

let active_viewports_ids: ViewportIdSet = viewport_output.keys().copied().collect();

egui_winit.handle_platform_output(window, platform_output);

handle_viewport_output(
&integration.egui_ctx,
&viewport_output,
Expand Down
64 changes: 33 additions & 31 deletions crates/egui-winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -828,34 +828,38 @@ impl State {
self.clipboard.set(copied_text);
}

let allow_ime = ime.is_some();
if self.allow_ime != allow_ime {
self.allow_ime = allow_ime;
crate::profile_scope!("set_ime_allowed");
window.set_ime_allowed(allow_ime);
}

if let Some(ime) = ime {
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)
|| 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(),
},
if self.allow_ime != ime.allowed_ime {
self.allow_ime = ime.allowed_ime;
crate::profile_scope!("set_ime_allowed");
self.egui_ctx.send_viewport_cmd_to(
self.viewport_id,
ViewportCommand::IMEAllowed(self.allow_ime),
);
}
} else {
self.ime_rect_px = None;

if ime.ime_enabled && ime.visible {
let pixels_per_point = pixels_per_point(&self.egui_ctx, window);
let ime_rect_px = ime.cursor_rect * pixels_per_point;

let is_need_cursor_area = self.ime_rect_px != Some(ime_rect_px)
&& self
.egui_ctx
.input_for(self.viewport_id, |i| !i.events.is_empty());

if is_need_cursor_area {
self.ime_rect_px = Some(ime_rect_px);
crate::profile_scope!("set_ime_cursor_area");
self.egui_ctx.send_viewport_cmd_to(
self.viewport_id,
ViewportCommand::IMERect(ime.cursor_rect),
);
} else {
self.ime_rect_px = None;
}
} else {
self.ime_rect_px = None;
}
}

#[cfg(feature = "accesskit")]
Expand Down Expand Up @@ -1429,13 +1433,11 @@ fn process_viewport_command(
let winit_icon = icon.and_then(|icon| to_winit_icon(&icon));
window.set_window_icon(winit_icon);
}
ViewportCommand::IMERect(rect) => {
ViewportCommand::IMERect(ime_rect) => {
let ime_rect_px = ime_rect * pixels_per_point;
window.set_ime_cursor_area(
PhysicalPosition::new(pixels_per_point * rect.min.x, pixels_per_point * rect.min.y),
PhysicalSize::new(
pixels_per_point * rect.size().x,
pixels_per_point * rect.size().y,
),
PhysicalPosition::new(ime_rect_px.min.x, ime_rect_px.min.y),
PhysicalSize::new(ime_rect_px.width(), ime_rect_px.height()),
);
}
ViewportCommand::IMEAllowed(v) => window.set_ime_allowed(v),
Expand Down
9 changes: 9 additions & 0 deletions crates/egui/src/data/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ impl FullOutput {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct IMEOutput {
/// is visible IME?
pub visible: bool,

/// is allowed IME?
pub allowed_ime: bool,

/// Indicates whether the IME is currently active.
pub ime_enabled: bool,

/// Where the [`crate::TextEdit`] is located on screen.
pub rect: crate::Rect,

Expand Down
14 changes: 14 additions & 0 deletions crates/egui/src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,12 @@ pub struct TextCursorStyle {

/// When blinking, this is how long the cursor is invisible.
pub off_duration: f32,

/// Whether the IME (Input Method Editor) is allowed.
pub ime_allowed: bool,

/// Whether the IME should be visible.
pub ime_visible: bool,
}

impl Default for TextCursorStyle {
Expand All @@ -761,6 +767,8 @@ impl Default for TextCursorStyle {
blink: true,
on_duration: 0.5,
off_duration: 0.5,
ime_allowed: true,
ime_visible: false,
}
}
}
Expand Down Expand Up @@ -2038,6 +2046,8 @@ impl TextCursorStyle {
blink,
on_duration,
off_duration,
ime_allowed,
ime_visible,
} = self;

ui.horizontal(|ui| {
Expand Down Expand Up @@ -2070,6 +2080,10 @@ impl TextCursorStyle {
ui.end_row();
});
}

ui.checkbox(ime_allowed, "Whether the IME is allowed");

ui.checkbox(ime_visible, "Whether the IME should be visible");
}
}

Expand Down
7 changes: 6 additions & 1 deletion crates/egui/src/widgets/text_edit/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,9 +732,14 @@ impl<'t> TextEdit<'t> {
.unwrap_or_default();

ui.ctx().output_mut(|o| {
let mut ime_cursor_rect = primary_cursor_rect;
ime_cursor_rect.max.x += primary_cursor_rect.height();
o.ime = Some(crate::output::IMEOutput {
visible: ui.visuals().text_cursor.ime_visible,
allowed_ime: ui.visuals().text_cursor.ime_allowed,
ime_enabled: state.ime_enabled,
rect: transform * rect,
cursor_rect: transform * primary_cursor_rect,
cursor_rect: transform * ime_cursor_rect,
});
});
}
Expand Down
Loading