From acd8a5765c91edd038430749bbf677a67cb05f33 Mon Sep 17 00:00:00 2001 From: Eric Kaden <608341+EricKaden@users.noreply.github.com> Date: Mon, 19 Oct 2026 19:45:29 -0400 Subject: [PATCH] M6: an open form field keeps the arrow keys, Home and End from moving the page --- crates/ui-egui/src/canvas.rs | 5 +++++ crates/ui-egui/tests/forms.rs | 42 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index eb9244a284..0e90b81f5b 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -2294,6 +2294,11 @@ pub fn shortcuts(view: &mut DocView, ctx: &egui::Context, speed: crate::scroll_s view.find = None; } } + // An open form field takes the arrows, Page Up / Page Down, Home and End (a drop-down's or a + // list box's items), so the page under it stays put. + if view.forms.focus.is_some() { + return; + } if key(Key::Home) { view.go_to_page(0); } diff --git a/crates/ui-egui/tests/forms.rs b/crates/ui-egui/tests/forms.rs index e02cc2c537..94822e50d0 100644 --- a/crates/ui-egui/tests/forms.rs +++ b/crates/ui-egui/tests/forms.rs @@ -1245,3 +1245,45 @@ fn the_mouse_wheel_scrolls_a_long_drop_down_list_and_not_the_page() { assert!(egui_kittest::kittest::Queryable::query_by_label(&h, "0000").is_none(), "the list scrolled down"); assert_eq!(h.state().views[0].page_screen_rect(0), page, "the page stayed where it was"); } + +#[test] +fn each_arrow_key_press_moves_a_drop_downs_list_one_item() { + let mut h = harness(); + long_country(&mut h); + click_field(&mut h, "country", 0); + h.key_press(egui::Key::Home); + h.run_steps(2); + h.key_press(egui::Key::ArrowDown); + h.run_steps(2); + h.key_press(egui::Key::Enter); + h.run_steps(3); + assert_eq!(value(&h, "country"), ["0100"], "one item down from the first"); +} + +#[test] +fn an_open_drop_down_keeps_the_arrow_keys_and_home_from_moving_the_page() { + let mut h = harness(); + long_country(&mut h); + // A page taller than the window, so the keys would scroll it. + h.state_mut().set_option("zoom", "300").unwrap(); + for _ in 0..30 { + h.run_steps(2); + if !h.state().render_pending() { + break; + } + } + click_field(&mut h, "country", 0); + // The pointer rests on the list, as it does after reaching for it. + let row = egui_kittest::kittest::Queryable::get_by_label(&h, "0300").rect(); + h.hover_at(row.center()); + h.run_steps(2); + let page = h.state().views[0].page_screen_rect(0); + h.key_press(egui::Key::Home); + h.run_steps(2); + h.key_press(egui::Key::ArrowDown); + h.run_steps(4); + assert_eq!(h.state().views[0].page_screen_rect(0), page, "the page stayed where it was"); + h.key_press(egui::Key::Enter); + h.run_steps(3); + assert_eq!(value(&h, "country"), ["0100"], "one item down from the first"); +}