diff --git a/Cargo.lock b/Cargo.lock index 1993c991a..f92ba5c54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1081,7 +1081,7 @@ dependencies = [ [[package]] name = "fontique" version = "0.2.0" -source = "git+https://github.com/linebender/parley?rev=dd778df2c4fcb984cd618dd0a46cc0d17970573c#dd778df2c4fcb984cd618dd0a46cc0d17970573c" +source = "git+https://github.com/linebender/parley?rev=feb2a46cc893c21673e0718182b197eb0d38b184#feb2a46cc893c21673e0718182b197eb0d38b184" dependencies = [ "core-foundation", "core-text", @@ -2510,7 +2510,7 @@ dependencies = [ [[package]] name = "parley" version = "0.2.0" -source = "git+https://github.com/linebender/parley?rev=dd778df2c4fcb984cd618dd0a46cc0d17970573c#dd778df2c4fcb984cd618dd0a46cc0d17970573c" +source = "git+https://github.com/linebender/parley?rev=feb2a46cc893c21673e0718182b197eb0d38b184#feb2a46cc893c21673e0718182b197eb0d38b184" dependencies = [ "accesskit", "fontique", diff --git a/Cargo.toml b/Cargo.toml index 527e06abe..067ccf00e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -109,7 +109,7 @@ vello = "0.3" wgpu = "22.1.0" kurbo = "0.11.1" # https://github.com/linebender/parley/pull/192 -parley = { git = "https://github.com/linebender/parley", rev = "dd778df2c4fcb984cd618dd0a46cc0d17970573c", features = [ +parley = { git = "https://github.com/linebender/parley", rev = "feb2a46cc893c21673e0718182b197eb0d38b184", features = [ "accesskit", ] } peniko = "0.2.0" diff --git a/masonry/src/widget/text_area.rs b/masonry/src/widget/text_area.rs index 3d23e0646..378fb5abb 100644 --- a/masonry/src/widget/text_area.rs +++ b/masonry/src/widget/text_area.rs @@ -156,10 +156,22 @@ impl TextArea { /// Get the current text of this text area. /// /// To update the text of an active text area, use [`reset_text`](Self::reset_text). - pub fn text(&self) -> &str { + /// + /// The return values concatenated is the full text content. + /// This split is used when composing. + pub fn text(&self) -> [&str; 2] { self.editor.text() } + /// Determines whether the current text is `to_test` + pub fn text_is(&self, to_test: &str) -> bool { + let [a, b] = self.editor.text(); + let Some((a_1, b_1)) = to_test.split_at_checked(a.len()) else { + return false; + }; + a_1 == a && b_1 == b + } + /// Set a style property for the new text area. /// /// Style properties set by this method include [text size](parley::StyleProperty::FontSize), @@ -685,7 +697,9 @@ impl Widget for TextArea { .drive(fctx, lctx, |drv| drv.insert_or_replace_selection("\n")); edited = true; } else { - ctx.submit_action(crate::Action::TextEntered(self.text().to_string())); + ctx.submit_action(crate::Action::TextEntered( + self.text().into_iter().collect(), + )); } } @@ -714,7 +728,9 @@ impl Widget for TextArea { let new_generation = self.editor.generation(); if new_generation != self.rendered_generation { if edited { - ctx.submit_action(crate::Action::TextChanged(self.text().to_string())); + ctx.submit_action(crate::Action::TextChanged( + self.text().into_iter().collect(), + )); ctx.request_layout(); } else { ctx.request_render(); @@ -727,9 +743,10 @@ impl Widget for TextArea { TextEvent::Ime(e) => { // TODO: Handle the cursor movement things from https://github.com/rust-windowing/winit/pull/3824 let (fctx, lctx) = ctx.text_contexts(); - // The text to submit as the TextChanged action. We do not send a TextChange action - // for the "virtual" preedit text. - let mut submit_text = None; + + // Whether the returned text has changed. + // We don't send a TextChanged when the preedit changes + let mut edited = false; match e { winit::event::Ime::Disabled => { self.editor.drive(fctx, lctx, |drv| drv.clear_compose()); @@ -738,33 +755,25 @@ impl Widget for TextArea { if text.is_empty() { self.editor.drive(fctx, lctx, |drv| drv.clear_compose()); } else { - if !self.editor.is_composing() && self.editor.selected_text().is_some() - { - // The IME has started composing. Delete the current selection and - // send a TextChange event with the selection removed, but without - // the composing preedit text. - self.editor.drive(fctx, lctx, |drv| { - drv.delete_selection(); - }); - submit_text = Some(self.text().to_string()); - } - self.editor .drive(fctx, lctx, |drv| drv.set_compose(text, *cursor)); + edited = true; } } winit::event::Ime::Commit(text) => { self.editor .drive(fctx, lctx, |drv| drv.insert_or_replace_selection(text)); - submit_text = Some(self.text().to_string()); + edited = true; } winit::event::Ime::Enabled => {} } ctx.set_handled(); - if let Some(text) = submit_text { + if edited { + let text = self.text().into_iter().collect(); ctx.submit_action(crate::Action::TextChanged(text)); } + let new_generation = self.editor.generation(); if new_generation != self.rendered_generation { ctx.request_layout(); @@ -929,7 +938,14 @@ impl Widget for TextArea { } fn get_debug_text(&self) -> Option { - Some(self.editor.text().chars().take(100).collect()) + Some( + self.editor + .text() + .into_iter() + .flat_map(str::chars) + .take(100) + .collect(), + ) } } diff --git a/xilem/src/view/textbox.rs b/xilem/src/view/textbox.rs index 535ee52f5..f7331bab5 100644 --- a/xilem/src/view/textbox.rs +++ b/xilem/src/view/textbox.rs @@ -94,7 +94,7 @@ impl View for Textbox