Skip to content

Commit 113922d

Browse files
committed
ime: include ImePurpose in IME platform output
We want to include purpose hints in IME output, so that android keyboards know that they are inputting multiline or password. The softkeyboard behaves differently depending on the purpose. For example, on multiline the keyboards enter button changes from the done action to a newline. For passwords, suggestions are turned off, etc. Signed-off-by: William Casarin <[email protected]>
1 parent 603c212 commit 113922d

File tree

5 files changed

+34
-10
lines changed

5 files changed

+34
-10
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ web-sys = "0.3.70"
102102
web-time = "1.1.0" # Timekeeping for native and web
103103
wgpu = { version = "24.0.0", default-features = false }
104104
windows-sys = "0.59"
105-
winit = { default-features = false, git = "https://github.com/damus-io/winit", rev = "14d61a74bee0c9863abe7ef28efae2c4d8bd3743" }
105+
winit = { default-features = false, git = "https://github.com/damus-io/winit", rev = "eaff639ab0a14fccf595241f687be883154b267c" }
106106

107107
[workspace.lints.rust]
108108
unsafe_code = "deny"

crates/egui-winit/src/lib.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,11 @@ impl State {
907907
let text_input_this_frame = ime.is_some();
908908
if self.text_input_last_frame != text_input_this_frame {
909909
if text_input_this_frame {
910+
// Set ime purpose if we have it
911+
if let Some(ime) = ime {
912+
window.set_ime_purpose(to_winit_ime_purpose(ime.purpose))
913+
}
914+
910915
window.begin_ime_input();
911916
} else {
912917
window.end_ime_input();
@@ -1531,11 +1536,7 @@ fn process_viewport_command(
15311536
);
15321537
}
15331538
ViewportCommand::IMEAllowed(v) => window.set_ime_allowed(v),
1534-
ViewportCommand::IMEPurpose(p) => window.set_ime_purpose(match p {
1535-
egui::viewport::IMEPurpose::Password => winit::window::ImePurpose::Password,
1536-
egui::viewport::IMEPurpose::Terminal => winit::window::ImePurpose::Terminal,
1537-
egui::viewport::IMEPurpose::Normal => winit::window::ImePurpose::Normal,
1538-
}),
1539+
ViewportCommand::IMEPurpose(p) => window.set_ime_purpose(to_winit_ime_purpose(p)),
15391540
ViewportCommand::Focus => {
15401541
if !window.has_focus() {
15411542
window.focus_window();
@@ -1936,3 +1937,12 @@ pub fn short_window_event_description(event: &winit::event::WindowEvent) -> &'st
19361937
WindowEvent::PanGesture { .. } => "WindowEvent::PanGesture",
19371938
}
19381939
}
1940+
1941+
fn to_winit_ime_purpose(purpose: egui::viewport::IMEPurpose) -> winit::window::ImePurpose {
1942+
match purpose {
1943+
egui::viewport::IMEPurpose::Password => winit::window::ImePurpose::Password,
1944+
egui::viewport::IMEPurpose::Terminal => winit::window::ImePurpose::Terminal,
1945+
egui::viewport::IMEPurpose::Normal => winit::window::ImePurpose::Normal,
1946+
egui::viewport::IMEPurpose::Multiline => winit::window::ImePurpose::Multiline,
1947+
}
1948+
}

crates/egui/src/data/output.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! All the data egui returns to the backend at the end of each frame.
22
3-
use crate::{RepaintCause, TextInputState, ViewportIdMap, ViewportOutput, WidgetType};
3+
use crate::{IMEPurpose, RepaintCause, TextInputState, ViewportIdMap, ViewportOutput, WidgetType};
44

55
/// What egui emits each frame from [`crate::Context::run`].
66
///
@@ -70,6 +70,9 @@ impl FullOutput {
7070
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
7171
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
7272
pub struct IMEOutput {
73+
/// Multiline? Password?
74+
pub purpose: IMEPurpose,
75+
7376
/// Where the [`crate::TextEdit`] is located on screen.
7477
pub rect: crate::Rect,
7578

crates/egui/src/viewport.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ pub enum IMEPurpose {
901901
Normal,
902902
Password,
903903
Terminal,
904+
Multiline,
904905
}
905906

906907
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]

crates/egui/src/widgets/text_edit/builder.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ use crate::{
1414
text_selection::{
1515
text_cursor_state::cursor_rect, visuals::paint_text_selection, CCursorRange, CursorRange,
1616
},
17-
vec2, Align, Align2, Color32, Context, CursorIcon, Event, EventFilter, FontSelection, Id,
18-
ImeEvent, Key, KeyboardShortcut, Margin, Modifiers, NumExt, Response, Sense, Shape, TextBuffer,
19-
TextStyle, TextWrapMode, Ui, Vec2, Widget, WidgetInfo, WidgetText, WidgetWithState,
17+
vec2, Align, Align2, Color32, Context, CursorIcon, Event, EventFilter, FontSelection,
18+
IMEPurpose, Id, ImeEvent, Key, KeyboardShortcut, Margin, Modifiers, NumExt, Response, Sense,
19+
Shape, TextBuffer, TextStyle, TextWrapMode, Ui, Vec2, Widget, WidgetInfo, WidgetText,
20+
WidgetWithState,
2021
};
2122

2223
use super::{TextEditOutput, TextEditState};
@@ -808,7 +809,16 @@ impl TextEdit<'_> {
808809
.unwrap_or_default();
809810

810811
ui.ctx().output_mut(|o| {
812+
let purpose = if self.multiline {
813+
IMEPurpose::Multiline
814+
} else if self.password {
815+
IMEPurpose::Password
816+
} else {
817+
IMEPurpose::Normal
818+
};
819+
811820
o.ime = Some(crate::output::IMEOutput {
821+
purpose,
812822
rect: to_global * rect,
813823
cursor_rect: to_global * primary_cursor_rect,
814824
});

0 commit comments

Comments
 (0)