Timeline marker, undo and redo compute off the window thread (#1675)

Thanks @phanoob.
This commit is contained in:
phanoob authored and GitHub committed 2026-10-16 06:26:10 -04:00
1 parent 9b2a40781c
commit d5640b5efb
7 files changed
+285 -11

No files matched your search

+18 -1
View File
@@ -20,6 +20,7 @@ mod colour_vision_tests;
pub mod context_menu;
pub mod control;
pub mod crash_ui;
pub mod deferred;
pub mod delete;
pub mod design_properties;
pub mod dialogs;
@@ -97,6 +98,8 @@ mod expression_complete;
mod extrude_edit_tests;
mod file_load;
mod file_picker;
#[cfg(test)]
mod history_off_thread_tests;
pub use file_picker::FilePickerFuture;
#[cfg(test)]
mod blend_arrow_tests;
@@ -321,6 +324,10 @@ pub struct SolveApp {
pub preview: preview::PreviewState,
/// OK pressed on a feature that takes a while: its evaluation runs off the window thread.
pub applying: Option<dialogs::Applying>,
/// A command recomputing the history (the marker moved, undo) computing off the window
/// thread, and those asked for meanwhile ([`deferred`]).
pub deferred: Option<deferred::Deferred>,
pub deferred_queue: Vec<(String, Value)>,
/// How long OK waits for a feature before computing it off the window thread, saying so;
/// `None`: it waits as long as it takes (headless use, tests). The desktop app sets it.
pub apply_off_thread: Option<std::time::Duration>,
@@ -435,6 +442,8 @@ impl SolveApp {
slicer_menu: dialogs_save_mesh::SlicerMenu::default(),
preview: preview::PreviewState::default(),
applying: None,
deferred: None,
deferred_queue: Vec::new(),
apply_off_thread: None,
last_command: None,
esc_handled: false,
@@ -843,6 +852,11 @@ impl SolveApp {
self.dialog = Some(d);
return;
}
// Undo and redo can recompute much of the history: off the window thread when slow.
if matches!(id, "edit.undo" | "edit.redo") {
let _ = self.run_heavy(id, json!({}));
return;
}
let _ = self.run(id, json!({}));
}
@@ -928,7 +942,9 @@ impl SolveApp {
}
fn restore_marker(&mut self, marker: Option<usize>) {
let _ = self.run("timeline.roll_to", marker.map(|m| json!({ "position": m })).unwrap_or_else(|| json!({})));
// Rolling forward past the features after the sketch recomputes them (an edited sketch
// under a text cut): off the window thread when it takes a while.
let _ = self.run_heavy("timeline.roll_to", marker.map(|m| json!({ "position": m })).unwrap_or_else(|| json!({})));
}
/// Everything shown as selected: the selection plus the open dialog's inputs.
@@ -1320,6 +1336,7 @@ impl SolveApp {
fn cad_ui(&mut self, ui: &mut egui::Ui, report_input: &mut Option<issue_report::CadInput>) {
scenario::clear_handles();
self.poll_deferred(ui.ctx());
toolbar::app_bar(self, ui);
issue_report::CadInput::block(self, ui, report_input);
file_load::show(self, ui.ctx());