mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-01 05:57:09 -06:00
Gesture numbers are checked when the request is admitted, before it waits for a layout
This commit is contained in:
@@ -53,6 +53,8 @@ impl LightcraftApp {
|
||||
if self.pending_gestures.len() >= MAX_PENDING_GESTURES {
|
||||
return Err(format!("{}: {MAX_PENDING_GESTURES} control gestures are already pending", method));
|
||||
}
|
||||
// refused at once, without waiting for a layout or taking a pending slot
|
||||
crate::control::check_gesture_numbers(&method, ¶ms)?;
|
||||
let now = self.tick_now_ms();
|
||||
self.pending_gestures.push(PendingGesture {
|
||||
method,
|
||||
|
||||
@@ -607,8 +607,9 @@ const MAX_GESTURE_NUMBER: f64 = 1e6;
|
||||
/// ±[`MAX_GESTURE_NUMBER`]. A larger one turns into an infinite or NaN `f32` position or scroll
|
||||
/// delta: egui asserts on NaN positions, and a release build would hand them to every widget.
|
||||
/// `count` and `steps` are clamped where they are read instead, and `ui.zoom`'s `factor` (a
|
||||
/// multiplier, not a position) is checked and clamped by its own branch.
|
||||
fn check_gesture_numbers(method: &str, p: &Value) -> Result<(), String> {
|
||||
/// multiplier, not a position) is checked and clamped by its own branch. Checked when a request
|
||||
/// is admitted and again here, for callers that resolve a gesture directly.
|
||||
pub(crate) fn check_gesture_numbers(method: &str, p: &Value) -> Result<(), String> {
|
||||
fn check(method: &str, key: &str, v: &Value) -> Result<(), String> {
|
||||
match v {
|
||||
Value::Number(n) if !matches!(key, "count" | "steps" | "factor") => match n.as_f64() {
|
||||
|
||||
@@ -930,6 +930,13 @@ fn gestures_refuse_numbers_that_are_not_screen_positions() {
|
||||
crate::control::gesture_events(&mut app, &ctx, "ui.drag", &serde_json::json!({"x": 1.0, "toX": 999_999.0, "steps": 1e12})).unwrap();
|
||||
assert!(!app.synthetic.is_empty());
|
||||
|
||||
// refused when the request is admitted: no pending slot, no wait for a layout
|
||||
let (tx, rx) = reply_channel();
|
||||
let e = app.admit_gesture(&ctx, "ui.click".into(), serde_json::json!({"x": 1e308}), tx).expect_err("refused at admission");
|
||||
assert!(e.contains("between"), "{e}");
|
||||
assert!(app.pending_gestures.is_empty());
|
||||
drop(rx);
|
||||
|
||||
// through the whole control channel, as an agent sends it: an error, not a panic
|
||||
let mut h = Headless::new(self::app(), [800.0, 600.0], 1.0);
|
||||
h.step();
|
||||
|
||||
Reference in New Issue
Block a user