From 84d782c85b43477c3db7b4904e0fa7bfbd4fa53c Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sun, 25 Oct 2026 14:19:01 -0700 Subject: [PATCH] M5: controller buttons wait while the link notice shows A controller button pressed while the notice before a website link shows no longer plays the prototype's gamepad triggers, as keys do not. Buttons play again once the notice closes. --- crates/ui-egui/src/present.rs | 2 ++ crates/ui-egui/src/present_links_tests.rs | 28 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/crates/ui-egui/src/present.rs b/crates/ui-egui/src/present.rs index bbaae4b6..b5c7eb0f 100644 --- a/crates/ui-egui/src/present.rs +++ b/crates/ui-egui/src/present.rs @@ -2506,7 +2506,9 @@ fn input(p: &mut Presenter, ctx: &egui::Context, l: &Layout, over_area: bool, ke ) }); let keys = if keys_on { keys } else { Vec::new() }; + // Controller buttons pressed while a link notice shows are dropped, as keys are. let pads = std::mem::take(&mut p.pads); + let pads = if p.link_notice.is_none() { pads } else { Vec::new() }; // A transition a drag started follows the pointer while it stays down, then plays on from there. if let Some(a) = p.anim.as_mut() && let Some((from, dir, len)) = a.follow diff --git a/crates/ui-egui/src/present_links_tests.rs b/crates/ui-egui/src/present_links_tests.rs index 31a6b2bc..a2b571af 100644 --- a/crates/ui-egui/src/present_links_tests.rs +++ b/crates/ui-egui/src/present_links_tests.rs @@ -162,6 +162,34 @@ fn the_presenter_keys_wait_while_the_notice_shows() { assert_eq!(notice(&u), "https://example.com/a"); } +#[test] +fn the_prototype_takes_no_controller_buttons_while_the_notice_shows() { + let mut s = Session::new(); + let a = id(&ex(&mut s, "frame.create", json!({"x": 0, "y": 0, "width": 300, "height": 400, "name": "A"}))); + let b = id(&ex(&mut s, "frame.create", json!({"x": 400, "y": 0, "width": 300, "height": 400, "name": "B"}))); + let layer = id(&ex(&mut s, "shape.rectangle", json!({"x": 10, "y": 10, "width": 30, "height": 30, "parent": a}))); + let link = json!({"type": "openUrl", "url": "https://example.com/a"}); + ex(&mut s, "proto.interaction.add", json!({"id": layer, "trigger": {"type": "afterDelay", "ms": 100}, "action": link})); + let to_b = json!({"type": "navigate", "dest": b}); + ex(&mut s, "proto.interaction.add", json!({"id": a, "trigger": {"type": "keyPress", "key": "Gamepad A"}, "action": to_b})); + let mut u = Harness::new(s); + u.app.services = Box::new(Opened::default()); + u.ctx.enable_accesskit(); + u.run("proto.present", json!({"start": a})); + u.frames(40, Vec::new); + assert_eq!(notice(&u), "https://example.com/a"); + let ctx = u.ctx.clone(); + crate::control::handle(&mut u.app, &ctx, "ui.input", &json!({"events": [{"gamepad": "A"}]})).unwrap(); + u.frames(2, Vec::new); + assert_eq!(u.app.inspect()["presenter"]["current"], json!(a), "the Gamepad A trigger did not run"); + assert_eq!(notice(&u), "https://example.com/a"); + click(&mut u, "Cancel"); + assert!(notice(&u).is_null()); + crate::control::handle(&mut u.app, &ctx, "ui.input", &json!({"events": [{"gamepad": "A"}]})).unwrap(); + u.frames(2, Vec::new); + assert_eq!(u.app.inspect()["presenter"]["current"], json!(b), "the button plays once the notice closes"); +} + #[test] fn dont_show_this_again_is_saved_with_the_preferences() { let (mut u, seen) = presented("https://example.com/a", false);