From c1c8453140c754a51e013ff5cfb19449b19a2e1b Mon Sep 17 00:00:00 2001 From: NgoQuocViet2001 Date: Wed, 19 Aug 2026 21:12:35 +0700 Subject: [PATCH] fix(mtext): stop Up/Down walking command history under the editor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MText editor paints its own caret and is not a focusable widget, so the command input keeps widget focus behind the dialog. It captures the arrow itself, which routes the key through CommandLineArrowProbe instead of ArrowKeyPressed — and that path only asked whether the command input was focused, never whether an editor was open. Up and Down therefore walked command history while the user was typing in MText. Give the probe the same rule ArrowKeyPressed already applies: while the editor is open the arrow moves its caret. The probe now carries the shift state so a held Shift still extends the selection on this path. Fixes #655 --- src/app/mod.rs | 4 ++-- src/app/update/mod.rs | 26 ++++++++++++++++++++++++-- src/app/view/mod.rs | 1 + 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/app/mod.rs b/src/app/mod.rs index 604d8e656..68ea4cf93 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1970,9 +1970,9 @@ pub enum Message { }, /// A widget captured Up/Down; resolve it only if the command input owns /// keyboard focus. - CommandLineArrowProbe { direction: ArrowKey }, + CommandLineArrowProbe { direction: ArrowKey, extend_selection: bool }, /// Result of the command-input focus query for a captured Up/Down key. - CommandLineArrowResolved { direction: ArrowKey, focused: bool }, + CommandLineArrowResolved { direction: ArrowKey, focused: bool, extend_selection: bool }, /// Toggle the dropdown listing the full command-line history. CommandHistoryToggle, /// Grab/move/release the expanded history panel's top resize edge. diff --git a/src/app/update/mod.rs b/src/app/update/mod.rs index 1957288d6..cb2c6a057 100644 --- a/src/app/update/mod.rs +++ b/src/app/update/mod.rs @@ -1559,17 +1559,39 @@ impl OpenCADStudio { )) } - Message::CommandLineArrowProbe { direction } => { + Message::CommandLineArrowProbe { + direction, + extend_selection, + } => { iced::widget::operation::is_focused(iced::widget::Id::new( crate::ui::command_line::CMD_INPUT_ID, )) .map(move |focused| Message::CommandLineArrowResolved { direction, focused, + extend_selection, }) } - Message::CommandLineArrowResolved { direction, focused } => { + Message::CommandLineArrowResolved { + direction, + focused, + extend_selection, + } => { + // The MText editor paints its own caret and is not a focusable + // widget, so the command input keeps widget focus behind the + // dialog and captures Up / Down itself. Walking command history + // from under an open editor is never what the key meant: while the + // editor is up the arrow belongs to its caret, exactly as it does + // on the ArrowKeyPressed path. + if self.mtext_editor.is_some() { + match direction { + ArrowKey::Up => self.mtext_caret_move_vertical(1, extend_selection), + ArrowKey::Down => self.mtext_caret_move_vertical(-1, extend_selection), + ArrowKey::Left | ArrowKey::Right => {} + } + return Task::none(); + } if !focused { return Task::none(); } diff --git a/src/app/view/mod.rs b/src/app/view/mod.rs index 078577713..a9973d560 100644 --- a/src/app/view/mod.rs +++ b/src/app/view/mod.rs @@ -2241,6 +2241,7 @@ impl OpenCADStudio { { return Some(Message::CommandLineArrowProbe { direction: arrow?, + extend_selection: modifiers.shift(), }); } // A focused web text field needs the browser clipboard;