From 9b0182a3e0af0cad054451d47913d2e510f21aff Mon Sep 17 00:00:00 2001 From: aiongg Date: Tue, 20 Oct 2026 04:18:35 +0000 Subject: [PATCH] keymap: a held web clipboard key with repeats off leaves its clipboard events in place --- crates/keymap/src/egui.rs | 6 ++++++ crates/keymap/tests/egui.rs | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/crates/keymap/src/egui.rs b/crates/keymap/src/egui.rs index fd5d2794..c89447d8 100644 --- a/crates/keymap/src/egui.rs +++ b/crates/keymap/src/egui.rs @@ -306,6 +306,12 @@ impl Dispatcher { } } } + // A repeat that does not run leaves its clipboard event in place with it. + Event::Key { pressed: true, repeat: true, .. } => { + if let Some((j, _)) = causes[i] { + caused_taken[j] = Some(false); + } + } Event::Text(_) if drop_text => { drop_text = false; continue; diff --git a/crates/keymap/tests/egui.rs b/crates/keymap/tests/egui.rs index 04a4ee51..b91e380f 100644 --- a/crates/keymap/tests/egui.rs +++ b/crates/keymap/tests/egui.rs @@ -218,6 +218,18 @@ fn a_web_paste_carries_its_text_and_takes_its_event() { assert_eq!(input.events, events[..2]); } +#[test] +fn a_held_web_paste_runs_once_when_repeats_are_off() { + let km = dispatch_keymap(); + let mut d = Dispatcher::new().with_clipboard_events(true); + let repeat = Event::Key { key: EguiKey::V, physical_key: Some(EguiKey::V), pressed: true, repeat: true, modifiers: CTRL }; + let paste = || Event::Paste("text".into()); + let events = vec![press(EguiKey::V, CTRL), paste(), repeat.clone(), paste()]; + let (ran, left) = run(&mut d, &km, &Active::NONE, frame(1.0, CTRL, events)); + assert_eq!(ran, ["edit.paste"]); + assert_eq!(left, [repeat, paste()], "the repeat and its event stay in egui's input"); +} + #[test] fn declined_hits_leave_their_events_in_order() { let km = dispatch_keymap();