Merge pull request #2918 from dcz-self/master

Report cursor size to input method
This commit is contained in:
Héctor 2025-11-25 22:51:48 +01:00 • committed by GitHub
commit b89c412496
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 36 additions and 25 deletions

View file

@ -1,5 +1,5 @@
//! Listen to input method events. //! Listen to input method events.
use crate::{Pixels, Point}; use crate::{Pixels, Rectangle};
use std::ops::Range; use std::ops::Range;
@ -10,8 +10,10 @@ pub enum InputMethod<T = String> {
Disabled, Disabled,
/// Input method is enabled. /// Input method is enabled.
Enabled { Enabled {
/// The position at which the input method dialog should be placed. /// The area of the cursor of the input method.
position: Point, ///
/// This area should not be covered.
cursor: Rectangle,
/// The [`Purpose`] of the input method. /// The [`Purpose`] of the input method.
purpose: Purpose, purpose: Purpose,
/// The preedit to overlay on top of the input method dialog, if needed. /// The preedit to overlay on top of the input method dialog, if needed.
@ -85,16 +87,16 @@ impl InputMethod {
/// Merges two [`InputMethod`] strategies, prioritizing the first one when both open: /// Merges two [`InputMethod`] strategies, prioritizing the first one when both open:
/// ``` /// ```
/// # use iced_core::input_method::{InputMethod, Purpose, Preedit}; /// # use iced_core::input_method::{InputMethod, Purpose, Preedit};
/// # use iced_core::Point; /// # use iced_core::{Point, Rectangle, Size};
/// ///
/// let open = InputMethod::Enabled { /// let open = InputMethod::Enabled {
/// position: Point::ORIGIN, /// cursor: Rectangle::new(Point::ORIGIN, Size::UNIT),
/// purpose: Purpose::Normal, /// purpose: Purpose::Normal,
/// preedit: Some(Preedit { content: "1".to_owned(), selection: None, text_size: None }), /// preedit: Some(Preedit { content: "1".to_owned(), selection: None, text_size: None }),
/// }; /// };
/// ///
/// let open_2 = InputMethod::Enabled { /// let open_2 = InputMethod::Enabled {
/// position: Point::ORIGIN, /// cursor: Rectangle::new(Point::ORIGIN, Size::UNIT),
/// purpose: Purpose::Secure, /// purpose: Purpose::Secure,
/// preedit: Some(Preedit { content: "2".to_owned(), selection: None, text_size: None }), /// preedit: Some(Preedit { content: "2".to_owned(), selection: None, text_size: None }),
/// }; /// };
@ -130,11 +132,11 @@ impl<T> InputMethod<T> {
match self { match self {
Self::Disabled => InputMethod::Disabled, Self::Disabled => InputMethod::Disabled,
Self::Enabled { Self::Enabled {
position, cursor,
purpose, purpose,
preedit, preedit,
} => InputMethod::Enabled { } => InputMethod::Enabled {
position: *position, cursor: *cursor,
purpose: *purpose, purpose: *purpose,
preedit: preedit.as_ref().map(Preedit::to_owned), preedit: preedit.as_ref().map(Preedit::to_owned),
}, },

View file

@ -785,10 +785,10 @@ where
); );
if !had_input_method if !had_input_method
&& let InputMethod::Enabled { position, .. } = && let InputMethod::Enabled { cursor, .. } =
shell.input_method_mut() shell.input_method_mut()
{ {
*position = *position - translation; *cursor = *cursor - translation;
} }
}; };

View file

@ -365,11 +365,13 @@ where
self.text_size.unwrap_or_else(|| renderer.default_size()), self.text_size.unwrap_or_else(|| renderer.default_size()),
); );
let position = let position = cursor + translation;
cursor + translation + Vector::new(0.0, f32::from(line_height));
InputMethod::Enabled { InputMethod::Enabled {
position, cursor: Rectangle::new(
position,
Size::new(1.0, f32::from(line_height)),
),
purpose: input_method::Purpose::Normal, purpose: input_method::Purpose::Normal,
preedit: state.preedit.as_ref().map(input_method::Preedit::as_ref), preedit: state.preedit.as_ref().map(input_method::Preedit::as_ref),
} }

View file

@ -428,7 +428,10 @@ where
+ alignment_offset; + alignment_offset;
InputMethod::Enabled { InputMethod::Enabled {
position: Point::new(x, text_bounds.y + text_bounds.height), cursor: Rectangle::new(
Point::new(x, text_bounds.y),
Size::new(1.0, text_bounds.height),
),
purpose: if self.is_secure { purpose: if self.is_secure {
input_method::Purpose::Secure input_method::Purpose::Secure
} else { } else {

View file

@ -172,7 +172,7 @@ where
pub renderer: P::Renderer, pub renderer: P::Renderer,
pub redraw_at: Option<Instant>, pub redraw_at: Option<Instant>,
preedit: Option<Preedit<P::Renderer>>, preedit: Option<Preedit<P::Renderer>>,
ime_state: Option<(Point, input_method::Purpose)>, ime_state: Option<(Rectangle, input_method::Purpose)>,
} }
impl<P, C> Window<P, C> impl<P, C> Window<P, C>
@ -215,11 +215,11 @@ where
self.disable_ime(); self.disable_ime();
} }
InputMethod::Enabled { InputMethod::Enabled {
position, cursor,
purpose, purpose,
preedit, preedit,
} => { } => {
self.enable_ime(position, purpose); self.enable_ime(cursor, purpose);
if let Some(preedit) = preedit { if let Some(preedit) = preedit {
if preedit.content.is_empty() { if preedit.content.is_empty() {
@ -229,7 +229,7 @@ where
self.preedit.take().unwrap_or_else(Preedit::new); self.preedit.take().unwrap_or_else(Preedit::new);
overlay.update( overlay.update(
position, cursor,
&preedit, &preedit,
self.state.background_color(), self.state.background_color(),
&self.renderer, &self.renderer,
@ -274,19 +274,23 @@ where
} }
} }
fn enable_ime(&mut self, position: Point, purpose: input_method::Purpose) { fn enable_ime(
&mut self,
cursor: Rectangle,
purpose: input_method::Purpose,
) {
if self.ime_state.is_none() { if self.ime_state.is_none() {
self.raw.set_ime_allowed(true); self.raw.set_ime_allowed(true);
} }
if self.ime_state != Some((position, purpose)) { if self.ime_state != Some((cursor, purpose)) {
self.raw.set_ime_cursor_area( self.raw.set_ime_cursor_area(
LogicalPosition::new(position.x, position.y), LogicalPosition::new(cursor.x, cursor.y),
LogicalSize::new(10, 10), // TODO? LogicalSize::new(cursor.width, cursor.height),
); );
self.raw.set_ime_purpose(conversion::ime_purpose(purpose)); self.raw.set_ime_purpose(conversion::ime_purpose(purpose));
self.ime_state = Some((position, purpose)); self.ime_state = Some((cursor, purpose));
} }
} }
@ -353,12 +357,12 @@ where
fn update( fn update(
&mut self, &mut self,
position: Point, cursor: Rectangle,
preedit: &input_method::Preedit, preedit: &input_method::Preedit,
background: Color, background: Color,
renderer: &Renderer, renderer: &Renderer,
) { ) {
self.position = position; self.position = cursor.position() + Vector::new(0.0, cursor.height);
let background = Color { let background = Color {
a: 1.0, a: 1.0,