diff --git a/src/app/commands/mod.rs b/src/app/commands/mod.rs index 555a58107..094cea430 100644 --- a/src/app/commands/mod.rs +++ b/src/app/commands/mod.rs @@ -65,6 +65,16 @@ impl OpenCADStudio { // the first space are left untouched. A non-alias passes through as-is. let resolved = self.resolve_alias(cmd); let cmd = resolved.as_deref().unwrap_or(cmd); + // A drafting aid only flips a flag, so it must not disturb whatever is + // already running: pressing F8 partway through a LINE means "constrain + // the rest of this line", not "abandon it". Everything below tears the + // running command down, so a transparent one skips straight past it. + // (#677) + if is_transparent(cmd) { + return self + .dispatch_families(cmd, i) + .unwrap_or_else(Task::none); + } // Starting a command closes any open ribbon dropdown (e.g. a style // combo left open) so it does not stay stuck behind the new tool. self.ribbon.close_dropdown(); @@ -232,6 +242,21 @@ impl OpenCADStudio { } } +/// Commands that toggle a drafting aid and nothing else. +/// +/// They are reachable from a function key, and a function key gets pressed +/// mid-command — that is the point of it. Running them through the ordinary +/// path cancelled the active command, cleared its preview and dropped its base +/// point, so F8 during a MOVE both ended the move and made the dragged ghost +/// vanish. Nothing here starts a command, opens a document or reads geometry, +/// so there is nothing for the teardown to protect. (#677) +pub fn is_transparent(cmd: &str) -> bool { + matches!( + cmd, + "ORTHO" | "GRID" | "SNAP" | "POLAR" | "OSNAP" | "DSETTINGS" + ) +} + /// Whether `cmd` makes sense on the Start (welcome) tab — document lifecycle, /// links, and app-wide configuration; nothing that reads the scene. Single /// source of truth: the dispatch gate refuses everything else, and the ribbon