From 6483566c5d8a8dbedd0f4fb75ee46cbe5d0ac1b5 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Wed, 27 May 2026 17:36:06 +0300 Subject: [PATCH] fix(dyn-input): capture numpad 8/2 as digits, not history nav MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NumLock açıkken Numpad8 / Numpad2 logical key olarak ArrowUp / ArrowDown geliyor ama text "8" / "2" taşıyor. Klavye aboneliğinde ok/geçmiş arm'ları bu tuşları yakaladığı için dinamik girişte 8 ve 2 yazılamıyordu. Printable glyph üreten her tuş artık navigation arm'larından önce, text alanı üzerinden yakalanıyor; whitespace/control üreten tuşlar (Space, Enter, Tab) named handler'lara düşmeye devam ediyor. Gerçek ok tuşları (text üretmez) geçmiş gezinmesini korur. Co-Authored-By: Claude Opus 4.7 --- src/app/view.rs | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/app/view.rs b/src/app/view.rs index 980be536e..974aff97c 100644 --- a/src/app/view.rs +++ b/src/app/view.rs @@ -782,6 +782,23 @@ impl OpenCADStudio { }) => { let ctrl = modifiers.control(); let shift = modifiers.shift(); + // Any key that produces a printable glyph types it, + // even when its logical key resolves to navigation + // (NumLock-on Numpad8 / Numpad2 arrive as + // ArrowUp / ArrowDown but still carry text "8" / + // "2"). Checked before the Arrow / history arms so + // those numpad digits aren't swallowed as history + // navigation. Whitespace / control text (Space, + // Enter, Tab) falls through to the named handlers. + if !ctrl && status == Status::Ignored { + if let Some(t) = text.as_deref() { + if !t.is_empty() + && t.chars().all(|c| !c.is_control() && !c.is_whitespace()) + { + return Some(Message::CommandAppendChar(t.to_string())); + } + } + } match key { keyboard::Key::Named(keyboard::key::Named::Enter) | keyboard::Key::Named(keyboard::key::Named::Space) @@ -847,20 +864,9 @@ impl OpenCADStudio { "v" => Some(Message::Command("PASTECLIP".to_string())), _ => None, }, - // Plain character keys (no ctrl) that nothing - // else consumed — route them into the command - // line input so typing always reaches it even - // when focus is parked on a button / viewport. - // Use the event's `text` (not the logical key) - // so numpad digits and other keypad glyphs — - // which don't arrive as `Key::Character` — are - // captured too. - _ if !ctrl && status == Status::Ignored => { - let glyph = text - .as_deref() - .filter(|t| !t.is_empty() && t.chars().all(|c| !c.is_control())); - glyph.map(|t| Message::CommandAppendChar(t.to_string())) - } + // Printable glyphs are already handled by the + // text guard above the match; anything reaching + // here is a non-typing key we don't bind. _ => None, } }