yewstack / yew

Rust / Wasm framework for creating reliable and efficient web applications

Home Page:https://yew.rs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

onwheel handler panics at installation with BorrowError on mobile

Madoshakalaka opened this issue · comments

Problem
onwheel handler panics at installation when used together with certain onpointermove callbacks on mobile after a certain amount of pointermove events. Also reproducible if ontouchmove is used instead of onpointermove event.

Steps To Reproduce
this handler seems to be the culprit

let onwheel = Callback::default();

let onpointermove = use_callback(panning_origin.clone(), {
    let view_box = view_box.dispatcher();
    move |e: PointerEvent, panning_origin| {
        if let Some(o) = **panning_origin {
            let c = calc_pointer_coords(&e.target_dyn_into::<SvgsvgElement>().unwrap(), &e);
            view_box.dispatch((o.0 - c.0, o.1 - c.1));
        }
    }
});

// comment out the {onwheel} line, and the panic disappears.
html!{
  <svg 
     {onwheel} 
     {onpointermove}>
  </svg> 
}

I have boiled my code down to a minimal producing example, here is the repo.

Screenshots
this is the expected behavior. It works on the PC.
expected
However, it panics on the phone after some events.

IMG_0544.mov

(me when I shake my dot too much that it panics)

You can try move in several times, little by little, or you can move a lot at one go, but eventually it will panic (after a fixed amount of events I think)

Noticeably, in my real project, the panic appears much much quickly. Only after less than half second of touch moving. I assume it maybe has to do with the actual onwheel handler.

This is reproduced both on an iPhone and an Android phone.

I tried some workarounds, including converting onpointermove handler to a manual event listener using web_sys; using Callback::from instead of the use_callback hook. Nothing worked.

Here are the panic messages, there are two of them. And they repeat if you keep moving after it panics:

image

image

(debug tips: if you use iPhone, turn on web inspector in the settings, and connect it to a Mac to see the console messages)

Environment:

  • Yew version: 0.21
  • Rust version: nightly and 1.73 both reproduced, likely irrelevant

Also, the content of onpointermove matters. If the onpointermove callback was empty, for example, the panic wouldn't happen

I tested line by line and it seems that the view_box.dispatch((o.0 - c.0, o.1 - c.1)); line causes the panic

For now, a workaround is to manually register the onwheel handler as shown here . You need an extra let e = e.dyn_ref::<WheelEvent>().unwrap(); in the actual callback.

update: onpointerup also panics at installation if used together with onpointermove

update: This panic seems to goes away if opt-level is set to either 1 or 'z'. So in most cases, building in release mode would fix the panic.

Or as a workaroud, use opt-level='z' in dev profile by adding this to the Cargo.toml:

[profile.dev]
opt-level = 'z'