servo icon indicating copy to clipboard operation
servo copied to clipboard

Scrolling in focused JavaScript embeds will still scroll the entire page

Open muzikbike opened this issue 3 weeks ago • 3 comments

Describe the bug: If an embedded JS/HTML5 program has focus, and it uses the scroll wheel, the scroll wheel input will be passed to it, but the page it's embedded in will still scroll anyway.

To Reproduce: ./servo https://lazyslug.com/lifeview/plugin/viewer.html click on embed, use scroll wheel

Platform: see #41153

muzikbike avatar Dec 09 '25 12:12 muzikbike

This may be related to how servo handles touch-action: none, or it may be related to the way we dispatch wheel events.

jdm avatar Dec 10 '25 10:12 jdm

Minimized testcase:

<div style="width: 10vw; height: 40px; background-color: red;" id="e"></div>
<script>
const e = document.querySelector('#e');
e.onwheel = (ev) => ev.preventDefault();
</script>
<div style="width: 10vw; height: 200vh; background-color: green"></div>

In Firefox attempting to scroll over the red box will do nothing. In Servo the page will scroll.

jdm avatar Dec 10 '25 10:12 jdm

I'm pretty sure the problem is this: https://github.com/servo/servo/blob/b7263e7fda4e10ae9d86a501c22d74f45138c60b/components/compositing/webview_renderer.rs#L393-L405

We dispatch the input event, but we immediately push a pending scroll event (in https://github.com/servo/servo/blob/b7263e7fda4e10ae9d86a501c22d74f45138c60b/components/compositing/webview_renderer.rs#L684-L696) without waiting to see if content called preventDefault.

https://github.com/servo/servo/blob/b7263e7fda4e10ae9d86a501c22d74f45138c60b/components/compositing/webview_renderer.rs#L1047 is the code that is called when content finishes processing an input event (such as a wheel event), so we could move the code that pushes the scrolling event into that method instead if the input result is not DefaultPrevented.

jdm avatar Dec 10 '25 10:12 jdm