fix(automation): cancel ends a request that never settles

A request settles once the work it started reports back, and waits for
any open or save in progress. When that never happens the bridge stayed
busy: every later request, `cancel` included, was refused until the app
was killed. `cancel` now ends the active command and closes any pending
request as cancelled, not only interactive picks. (#1801)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 5.5 committed 2026-10-15 16:04:18 +03:00
1 parent 6f2388796e
commit 859070403c
1 file changed
+37 -2
+37 -2
View File
@@ -777,6 +777,30 @@ impl OpenCADStudio {
Task::none(),
);
}
// Any other request settles once the work it started reports
// back. When that never happens (a save or open whose result
// never arrives) the bridge would stay busy until the app is
// killed, so `cancel` ends the active command and closes the
// request as cancelled. (#1801)
if op == "cancel" {
let task = self.update(Message::CommandEscape);
if let Some(p) = self.control.pending.as_mut() {
p.cancelled = true;
p.pending = 0;
}
self.control_settle_inner(true);
let response = self
.control
.completed
.iter()
.find(|(i, _, _)| *i == pending_id)
.map(|(_, _, r)| r.clone());
return (
response
.unwrap_or_else(|| failure("busy", "Wait for the running operation")),
task,
);
}
return (
failure("busy", "Wait for the running operation"),
Task::none(),
@@ -1440,11 +1464,22 @@ impl OpenCADStudio {
}
}
pub(super) fn control_settle(&mut self) {
if self.control.pending.as_ref().is_none_or(|p| p.pending != 0) || self.opening.is_some() {
self.control_settle_inner(false);
}
/// `force` closes the request even while an open or a save it may have
/// started is still running.
fn control_settle_inner(&mut self, force: bool) {
if self.control.pending.as_ref().is_none_or(|p| p.pending != 0) {
return;
}
if !force && self.opening.is_some() {
return;
}
#[cfg(not(target_arch = "wasm32"))]
if !self.active_save_jobs.is_empty() || self.pending_native_thumbnail_save.is_some() {
if !force
&& (!self.active_save_jobs.is_empty() || self.pending_native_thumbnail_save.is_some())
{
return;
}
let p = self.control.pending.take().unwrap();