Track pre-edits separately from focus in text inputs

This commit is contained in:
Héctor Ramón Jiménez 2025-02-03 00:51:57 +01:00
parent db990b77e4
commit d28af5739b
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
3 changed files with 17 additions and 23 deletions

View file

@ -332,14 +332,13 @@ where
) -> InputMethod<&'b str> { ) -> InputMethod<&'b str> {
let Some(Focus { let Some(Focus {
is_window_focused: true, is_window_focused: true,
is_ime_open,
.. ..
}) = &state.focus }) = &state.focus
else { else {
return InputMethod::Disabled; return InputMethod::Disabled;
}; };
let Some(preedit) = &is_ime_open else { let Some(preedit) = &state.preedit else {
return InputMethod::Allowed; return InputMethod::Allowed;
}; };
@ -497,6 +496,7 @@ where
#[derive(Debug)] #[derive(Debug)]
pub struct State<Highlighter: text::Highlighter> { pub struct State<Highlighter: text::Highlighter> {
focus: Option<Focus>, focus: Option<Focus>,
preedit: Option<String>,
last_click: Option<mouse::Click>, last_click: Option<mouse::Click>,
drag_click: Option<mouse::click::Kind>, drag_click: Option<mouse::click::Kind>,
partial_scroll: f32, partial_scroll: f32,
@ -510,7 +510,6 @@ struct Focus {
updated_at: Instant, updated_at: Instant,
now: Instant, now: Instant,
is_window_focused: bool, is_window_focused: bool,
is_ime_open: Option<String>,
} }
impl Focus { impl Focus {
@ -523,7 +522,6 @@ impl Focus {
updated_at: now, updated_at: now,
now, now,
is_window_focused: true, is_window_focused: true,
is_ime_open: None,
} }
} }
@ -573,6 +571,7 @@ where
fn state(&self) -> widget::tree::State { fn state(&self) -> widget::tree::State {
widget::tree::State::new(State { widget::tree::State::new(State {
focus: None, focus: None,
preedit: None,
last_click: None, last_click: None,
drag_click: None, drag_click: None,
partial_scroll: 0.0, partial_scroll: 0.0,
@ -752,13 +751,11 @@ where
} }
Update::InputMethod(update) => match update { Update::InputMethod(update) => match update {
Ime::Toggle(is_open) => { Ime::Toggle(is_open) => {
if let Some(focus) = &mut state.focus { state.preedit = is_open.then(String::new);
focus.is_ime_open = is_open.then(String::new);
}
} }
Ime::Preedit(text) => { Ime::Preedit(text) => {
if let Some(focus) = &mut state.focus { if state.focus.is_some() {
focus.is_ime_open = Some(text); state.preedit = Some(text);
} }
} }
Ime::Commit(text) => { Ime::Commit(text) => {

View file

@ -400,14 +400,13 @@ where
) -> InputMethod<&'b str> { ) -> InputMethod<&'b str> {
let Some(Focus { let Some(Focus {
is_window_focused: true, is_window_focused: true,
is_ime_open,
.. ..
}) = &state.is_focused }) = &state.is_focused
else { else {
return InputMethod::Disabled; return InputMethod::Disabled;
}; };
let Some(preedit) = is_ime_open else { let Some(preedit) = &state.is_ime_open else {
return InputMethod::Allowed; return InputMethod::Allowed;
}; };
@ -729,7 +728,6 @@ where
updated_at: now, updated_at: now,
now, now,
is_window_focused: true, is_window_focused: true,
is_ime_open: None,
}) })
} else { } else {
None None
@ -1257,17 +1255,15 @@ where
input_method::Event::Opened | input_method::Event::Closed => { input_method::Event::Opened | input_method::Event::Closed => {
let state = state::<Renderer>(tree); let state = state::<Renderer>(tree);
if let Some(focus) = &mut state.is_focused { state.is_ime_open =
focus.is_ime_open =
matches!(event, input_method::Event::Opened) matches!(event, input_method::Event::Opened)
.then(String::new); .then(String::new);
} }
}
input_method::Event::Preedit(content, _range) => { input_method::Event::Preedit(content, _range) => {
let state = state::<Renderer>(tree); let state = state::<Renderer>(tree);
if let Some(focus) = &mut state.is_focused { if state.is_focused.is_some() {
focus.is_ime_open = Some(content.to_owned()); state.is_ime_open = Some(content.to_owned());
} }
} }
input_method::Event::Commit(text) => { input_method::Event::Commit(text) => {
@ -1519,6 +1515,7 @@ pub struct State<P: text::Paragraph> {
placeholder: paragraph::Plain<P>, placeholder: paragraph::Plain<P>,
icon: paragraph::Plain<P>, icon: paragraph::Plain<P>,
is_focused: Option<Focus>, is_focused: Option<Focus>,
is_ime_open: Option<String>,
is_dragging: bool, is_dragging: bool,
is_pasting: Option<Value>, is_pasting: Option<Value>,
last_click: Option<mouse::Click>, last_click: Option<mouse::Click>,
@ -1538,7 +1535,6 @@ struct Focus {
updated_at: Instant, updated_at: Instant,
now: Instant, now: Instant,
is_window_focused: bool, is_window_focused: bool,
is_ime_open: Option<String>,
} }
impl<P: text::Paragraph> State<P> { impl<P: text::Paragraph> State<P> {
@ -1565,7 +1561,6 @@ impl<P: text::Paragraph> State<P> {
updated_at: now, updated_at: now,
now, now,
is_window_focused: true, is_window_focused: true,
is_ime_open: None,
}); });
self.move_cursor_to_end(); self.move_cursor_to_end();

View file

@ -205,9 +205,11 @@ where
pub fn request_input_method(&mut self, input_method: InputMethod) { pub fn request_input_method(&mut self, input_method: InputMethod) {
match input_method { match input_method {
InputMethod::None => {} InputMethod::None => {}
InputMethod::Disabled => self.raw.set_ime_allowed(false), InputMethod::Disabled => {
self.raw.set_ime_allowed(false);
}
InputMethod::Allowed | InputMethod::Open { .. } => { InputMethod::Allowed | InputMethod::Open { .. } => {
self.raw.set_ime_allowed(true) self.raw.set_ime_allowed(true);
} }
} }