feat(viewport): RMB=Enter option + timed right-click

Adds a configurable right-mouse-button behavior without disturbing orbit
or the context menu.

- New persisted setting `rmb_enter` (command `RMBENTER [ON|OFF]`, default
  off): when on, a right-click while a command is active acts as Enter
  (commit/close); when idle it still opens the context menu. Right-drag
  always orbits, so nothing is lost.
- Right-click vs orbit is now time-based: orbit engages only after the
  button is held >=150ms and the pointer moves, so a quick right-click is
  no longer swallowed by slight pointer jitter (was an 8px distance gate).
- The right-click Repeat menu now lists commands from every source
  (command line, ribbon, context menu, shortcuts) via a unified
  recents list recorded at the dispatch choke point, instead of only
  typed commands.

Closes #185

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-27 16:16:08 +03:00
commit 098585bb2d
10 changed files with 157 additions and 53 deletions

View file

@ -1095,6 +1095,7 @@ impl OpenCADStudio {
sel.context_menu = None;
sel.right_down = true;
sel.right_press_pos = Some(p);
sel.right_press_time = Some(iced::time::Instant::now());
sel.right_last_pos = Some(p);
sel.right_dragging = false;
Task::none()
@ -1103,19 +1104,31 @@ impl OpenCADStudio {
Message::ViewportRightRelease => {
let i = self.active_tab;
let mut sel = self.tabs[i].scene.selection.borrow_mut();
let Some(_p) = sel.last_move_pos else {
let Some(click_pos) = sel.last_move_pos else {
return Task::none();
};
if sel.right_down {
if !sel.right_dragging {
sel.context_menu = sel.last_move_pos;
sel.draworder_submenu = false;
}
sel.right_down = false;
sel.right_press_pos = None;
sel.right_last_pos = None;
sel.right_dragging = false;
if !sel.right_down {
return Task::none();
}
let was_click = !sel.right_dragging;
sel.right_down = false;
sel.right_press_pos = None;
sel.right_press_time = None;
sel.right_last_pos = None;
sel.right_dragging = false;
if !was_click {
return Task::none();
}
// A right-click (no orbit). With "RMB = Enter" enabled, a click
// while a command is active fires Enter (commit/close) instead
// of the menu; when idle — or the option is off — it opens the
// context menu as before, so the menu is never lost.
if self.rmb_enter && self.tabs[i].active_cmd.is_some() {
drop(sel);
return self.update(Message::CommandFinalize);
}
sel.context_menu = Some(click_pos);
sel.draworder_submenu = false;
Task::none()
}