vispy / jupyter_rfb

Remote Frame Buffer for Jupyter
https://jupyter-rfb.readthedocs.io
MIT License
55 stars 10 forks source link

Make wheel deltas more similar #50

Closed almarklein closed 2 years ago

almarklein commented 2 years ago

It turns out that the value of dy on our wheel event differers per platform/browser. This can be as much as 96 vs 200.

I created a little html test that can be used to test the browsers behavior. Create a wheeltest.html with this code and open in your browser. Lets use this to collect some info.

<html>
<body>

<script>
var arr = [];
var modes = ["pixel", "line", "page"];
var square_y = 0;

function on_wheel(e) {
    e.preventDefault();
    e.stopPropagation();

    // Get line of event info and add to array
    let line = modes[e.deltaMode] + "  " + e.deltaY + "\n";
    arr.push(line);
    arr.splice(0, Math.max(0, arr.length - 16));  // limit to 16 items
    //show
    let el = document.getElementById("out");
    el.innerText = "dpr: " + window.devicePixelRatio + "\n\n...\n";
    for (line of arr) {
        el.innerText += line;
    }
    // Make it move the square
    let dy = 0;
    if (e.deltaMode == 1) {
        dy = 16 *  e.deltaY;  // line
    } else if (e.deltaMode == 2) {
        dy = 600 *  e.deltaY;  // page
    } else {  // e.deltaMode == 0 -> pixel
        dy = e.deltaY / window.devicePixelRatio;
    }
    dy = 0.4 * dy; // scale so that about one "scroll" brings the square to the other side
    square_y = Math.max(0, Math.min(350, square_y + dy));
    document.getElementById("square").style.top = square_y + "px";

}
document.addEventListener("wheel", on_wheel, {passive: false});
</script>

<div style='background:#aaf; position: fixed; left: 400px; width:100px; height: 400px;'>
    <div id='square' style='background:#0a0; position: absolute; left: 25px; width:50px; height: 50px;'></div>
</div>

<p id='out'>
Scroll using mouse-wheel, touch-scroll, and pinch.
</p>

</body>
</html>
almarklein commented 2 years ago

On Windows 10, dpr 1 screen, Firefox:

On Windows 10, dpr 1 screen, Chrome:

On Windows 10, dpr 1 screen, Edge: same as Chrome.

pijyoi commented 2 years ago

On Windows 10, dpr 2 screen, Firefox:

On Windows 10, dpr 2 screen, Chrome:

I listed the smallest values obtained

berendkleinhaneveld commented 2 years ago

On macOS, dpr 2 screen, Safari / Chromium:

Edit: On macOS, dpr 1 screen, Safari / Chromium actually the same results.

Also the smallest values obtained.

Pinch on Chromium gives me a list, on Safari it kind of stops after the first pinch event.

On MacOS, dpr 1 and 2 screen, Firefox:

pijyoi commented 2 years ago

On Fedora 34 Mate Desktop, dpr 1 screen, Firefox:

On Fedora 34 Mate Desktop, dpr 1 screen, Chrome:

almarklein commented 2 years ago

Apparently it's not new that these values are all over the place:

image

almarklein commented 2 years ago

On Windows 10, highres screen with dpr 1.75, Firefox:

Mouse-wheel: line 6
Touch-scroll: pixel e.g 3.197509765625
Touch-pinch: pixel e.g 1.510833740234375

On Windows 10, highres screen with dpr 1.75, Chrome:

Mouse-wheel: pixel 175
Touch-scroll: pixel e.g 3
Touch-pinch: pixel e.g 1.7126655578613281

Looks like that mousewheel value in Chrome scales directly with the native system's DPR (but not takes the browser scaling into account).

almarklein commented 2 years ago

I updated the HTML sample in the top post, so that scrolling moves a square up/down the page. I've found that the deltas when using the touchpad are also scaled with the dpr, so it looks like the deltaY is meant to represent a value in physical pixels. Weird.

Could you folks have another spin with the updated HTML sample? Here's my subjective findings (same for Chrome/FF, and dpr 1/1.75):

pijyoi commented 2 years ago

On Windows 10, highres screen with dpr 2, Firefox:

Mouse-wheel: line 6 Touch-scroll: pixel 1.1 Touch-pinch: pixel 0.5

On Windows 10, highres screen with dpr 2, Chrome:

Mouse-wheel: pixel 200 Touch-scroll: pixel 2 Touch-pinch: pixel 0.11

Touch-scroll seems to give the "best" control. Pinch-scroll takes too long. Mouse-wheel is too discrete.

almarklein commented 2 years ago

For the record, the numbers have not changed - I only added the logic to move that green square.

ivoflipse commented 2 years ago

On Windows 10, 34" screen with dpr 1, Chrome:

Mouse-wheel: pixel 100

On Windows 10, 28" 4k screen with dpr 1.5, Chrome:

Mouse-wheel: pixel 150

On Windows 10, 34" screen with dpr 1, Firefox:

Mouse-wheel: line 6

On Windows 10, 34" screen with dpr 1.5, Firefox:

Mouse-wheel: line 6

I do seem to get 200 or 300 pixels if I try to scroll "fast"

almarklein commented 2 years ago

On a Raspberry Pi 400, dpr1, Chromium:

mouse-wheel: 50

I do seem to get 200 or 300 pixels if I try to scroll "fast"

I had not seen this before, but it does this too on my Windows+Chrome. On Raspberry PI this acceleration effect seems to kick in faster. And this is also what @berendkleinhaneveld reports for MacOS: values around 4px when scrolling slowly, and values in the hundreds when scrolling fast.

I think we can settle on the solution that's in the current code sample. Refactored a bit:

    let scales = [ 1 / window.devicePixelRatio, 16, 600];  // pixel, line, page
    let dy = scales[e.deltaMode] * e.deltaY;