Skip to content

Commit

Permalink
Fix issue with repeated updates
Browse files Browse the repository at this point in the history
  • Loading branch information
DJMcNab committed Dec 3, 2024
1 parent 0ce99cf commit e82dabb
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 24 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
56 changes: 36 additions & 20 deletions masonry/src/widget/text_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,22 @@ impl<const EDITABLE: bool> TextArea<EDITABLE> {
/// 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),
Expand Down Expand Up @@ -685,7 +697,9 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
.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(),
));
}
}

Expand Down Expand Up @@ -714,7 +728,9 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
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();
Expand All @@ -727,9 +743,10 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
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());
Expand All @@ -738,33 +755,25 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
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();
Expand Down Expand Up @@ -929,7 +938,14 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
}

fn get_debug_text(&self) -> Option<String> {
Some(self.editor.text().chars().take(100).collect())
Some(
self.editor
.text()
.into_iter()
.flat_map(str::chars)
.take(100)
.collect(),
)
}
}

Expand Down
2 changes: 1 addition & 1 deletion xilem/src/view/textbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ impl<State: 'static, Action: 'static> View<State, Action, ViewCtx> for Textbox<S
// without calling `set_text`.

// This is probably not the right behaviour, but determining what is the right behaviour is hard
if self.contents != text_area.widget.text() {
if !text_area.widget.text_is(&self.contents) {
widget::TextArea::reset_text(&mut text_area, &self.contents);
}

Expand Down

0 comments on commit e82dabb

Please sign in to comment.