fix(commandline): empty Space/Enter repeats the last command

Two follow-ups to the always-on keyboard work:

1. **Repeat last command on empty Submit.** Pressing Space (or Enter)
   after a command ended did nothing — the trailing-space submit path
   reached `CommandSubmit`, found no active command and no buffered
   text, and bailed. `CommandFinalize` already had the repeat-last
   shortcut via `tab.last_cmd`; mirror it inside `CommandSubmit` so
   the space-as-submit path picks it up too.

2. **Drop the per-event focus_cmd_input calls** added in the previous
   commit for `ViewportLeftPress`, `ViewportClick`, `TabNew`,
   `TabSwitch`, `RibbonSelectTab` and `RibbonToolClick`. The global
   keyboard subscription routes unhandled character / backspace
   events into the buffer regardless of focus, so the only places
   that still need an explicit refocus are `cmd_result.rs` (command
   lifecycle), `boot()` (initial caret), and the per-char append
   handlers (caret feedback while typing).

Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.7 committed 2026-05-26 19:10:01 +03:00
1 parent 39150d617f
commit 979ca28632
1 file changed
+16 -13
+16 -13
View File
@@ -691,7 +691,7 @@ impl OpenCADStudio {
Message::RibbonSelectTab(idx) => {
self.ribbon.select(idx);
self.focus_cmd_input()
Task::none()
}
Message::RibbonToolClick { tool_id, event } => {
@@ -727,7 +727,7 @@ impl OpenCADStudio {
return Task::done(Message::ToggleLayers);
}
}
self.focus_cmd_input()
Task::none()
}
// ── Application menu ──────────────────────────────────────────
@@ -759,7 +759,7 @@ impl OpenCADStudio {
// fresh tab's defaults (ByLayer) instead of inheriting the
// previous tab's last selection.
self.sync_ribbon_from_selection();
self.focus_cmd_input()
Task::none()
}
Message::TabSwitch(idx) => {
@@ -772,7 +772,7 @@ impl OpenCADStudio {
// if there is one), not the prior tab's choice.
self.sync_ribbon_from_selection();
}
self.focus_cmd_input()
Task::none()
}
Message::TabClose(idx) => {
@@ -922,6 +922,13 @@ impl OpenCADStudio {
if let Some(cmd) = self.command_line.submit() {
return self.dispatch_command(&cmd);
}
// Empty Enter / Space with no active command repeats the
// last dispatched command — same shortcut `CommandFinalize`
// already implements, mirrored here so the trailing-space
// submit path goes through it too.
if let Some(cmd) = self.tabs[i].last_cmd.clone() {
return self.dispatch_command(&cmd);
}
Task::none()
}
@@ -1752,15 +1759,11 @@ impl OpenCADStudio {
Message::ViewportLeftPress => {
let i = self.active_tab;
// Clicking inside the viewport must not park focus on the
// viewport widget — typed characters need to keep flowing
// into the command-line input. Refocus on every exit path.
let refocus = self.focus_cmd_input();
let (p, vp_size) = {
let sel = self.tabs[i].scene.selection.borrow();
let p = match sel.last_move_pos {
Some(p) => p,
None => return refocus,
None => return Task::none(),
};
(p, sel.vp_size)
};
@@ -1777,7 +1780,7 @@ impl OpenCADStudio {
if scene::hit_test(p.x, p.y, vw, vh, cam.view_rotation_mat(), VIEWCUBE_PX)
.is_some()
{
return refocus;
return Task::none();
}
}
@@ -1813,7 +1816,7 @@ impl OpenCADStudio {
origin_world: world,
last_world: world,
});
return refocus;
return Task::none();
}
}
}
@@ -1824,7 +1827,7 @@ impl OpenCADStudio {
sel.left_press_pos = Some(p);
sel.left_press_time = Some(Instant::now());
sel.left_dragging = false;
refocus
Task::none()
}
Message::ViewportLeftRelease => {
@@ -2476,7 +2479,7 @@ impl OpenCADStudio {
) {
return Task::done(Message::ViewCubeSnap(region));
}
self.focus_cmd_input()
Task::none()
}
Message::WindowResized(w, h) => {