Form controls: holding Enter or Space presses a focused button once

The focused control took every pressed key event, the system's key
repeats included, so holding Enter or Space on a focused button ran its
macro or command again for each repeat. A repeat now still belongs to
the button (it doesn't reach the grid) but doesn't press it; arrows,
Page Up and Page Down held on a slider or spin button keep stepping.
This commit is contained in:
prxnvt committed 2026-10-31 16:37:49 -04:00
1 parent b8f04d7af9
commit e1fbee8ebc
3 files changed
+32 -4

No files matched your search

+6 -3
View File
@@ -357,8 +357,9 @@ fn step_part(app: &mut SheetApp, c: &FormControl, part: Part) {
}
/// Keys for the focused control: arrows move by a step, Page Up and Page Down by a page, Home and
/// End to the ends; Space or Enter presses a button. True when the key was used.
pub fn key(app: &mut SheetApp, sh: &Sheet, key: egui::Key) -> bool {
/// End to the ends; Space or Enter presses a button. True when the key was used. `repeat` is a key
/// held down: it steps a slider or spin button again, but a button runs once per press.
pub fn key(app: &mut SheetApp, sh: &Sheet, key: egui::Key, repeat: bool) -> bool {
use egui::Key;
let Some(c) = app.grid.focused_control.and_then(|id| find(sh, id)).cloned() else { return false };
if app.selected_object.is_some() {
@@ -370,7 +371,9 @@ pub fn key(app: &mut SheetApp, sh: &Sheet, key: egui::Key) -> bool {
true
}
(ControlKind::Button, Key::Space | Key::Enter) => {
app.press_button(c.id);
if !repeat {
app.press_button(c.id);
}
true
}
(ControlKind::Button, _) => false,
+3 -1
View File
@@ -170,7 +170,9 @@ fn grid_events(app: &mut SheetApp, ctx: &egui::Context, sh: &Sheet) -> Vec<egui:
fn form_control_event(app: &mut SheetApp, sh: &Sheet, ev: &egui::Event) -> bool {
match ev {
egui::Event::Text(text) => text == " " && app.grid.focused_control.is_some() && app.selected_object.is_none(),
egui::Event::Key { key, pressed: true, modifiers: m, .. } => !m.command && !m.ctrl && !m.alt && crate::form_controls::key(app, sh, *key),
egui::Event::Key { key, pressed: true, repeat, modifiers: m, .. } => {
!m.command && !m.ctrl && !m.alt && crate::form_controls::key(app, sh, *key, *repeat)
}
_ => false,
}
}
+23
View File
@@ -241,6 +241,29 @@ fn a_button_runs_its_macro_and_cmd_or_right_click_only_selects() {
assert_eq!(cell(&h, "H1"), Value::Empty);
}
#[test]
fn holding_enter_or_space_presses_a_focused_button_once() {
let (mut h, ids) = fixture();
let r = rect(&h, ids.button);
click(&mut h, r.center());
assert_eq!(h.state().grid.focused_control, Some(ids.button));
for k in [Key::Enter, Key::Space] {
let before = undo_len(&h);
// A held key: one press, then the system's repeats, then the release.
h.input_mut().events.push(Event::Key { key: k, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE });
h.run_steps(1);
for _ in 0..5 {
h.input_mut().events.push(Event::Key { key: k, physical_key: None, pressed: true, repeat: true, modifiers: Modifiers::NONE });
h.run_steps(1);
}
h.input_mut().events.push(Event::Key { key: k, physical_key: None, pressed: false, repeat: false, modifiers: Modifiers::NONE });
h.run_steps(2);
assert_eq!(undo_len(&h), before + 1, "{k:?} ran the macro once");
assert_eq!(cell(&h, "H1"), Value::text("pressed"));
assert_eq!(cell(&h, "A20"), Value::Empty, "{k:?} typed nothing into the cell");
}
}
#[test]
fn a_button_from_a_file_asks_before_it_runs() {
use egui_kittest::kittest::Queryable as _;