From 89085cfd12780e58fcfbff553e3ba3b7d7457c6f Mon Sep 17 00:00:00 2001 From: Tom Churchman Date: Tue, 3 Dec 2024 17:37:59 +0100 Subject: [PATCH] Clear compose in TextArea::reset_text (#768) The user may be composing when the `TextArea` text is programmatically changed. This change clears the compose state in order to adhere to the `PlainEditor` requirements. It is disruptive, but we already warn about disruption (and about IME in particular) in the documentation of `TextArea::reset_text`. This doesn't reset the platform's IME state, we could do, but that's potentially even more disruptive, and looks like it's a bit harder to wire up. We could also re-insert the preedit text. That'd be nicest to do if we can query `PlainEditor` for the current preedit text, which requires an API change there. --- masonry/src/widget/text_area.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/masonry/src/widget/text_area.rs b/masonry/src/widget/text_area.rs index 399f0cf83..eb3675c81 100644 --- a/masonry/src/widget/text_area.rs +++ b/masonry/src/widget/text_area.rs @@ -356,6 +356,15 @@ impl TextArea { /// This is likely to be disruptive if the user is focused on this widget, /// as it does not retain selections, and may cause undesirable interactions with IME. pub fn reset_text(this: &mut WidgetMut<'_, Self>, new_text: &str) { + // If the IME is currently composing, we need to clear the compose first. This is quite + // disruptive, but we've warned about that. The platform's state is not reset, and the + // preedit will show up again when the platform updates it. + if this.widget.editor.is_composing() { + let (fctx, lctx) = this.ctx.text_contexts(); + this.widget + .editor + .transact(fctx, lctx, |txn| txn.clear_compose()); + } this.widget.editor.set_text(new_text); this.ctx.request_layout();