script: Pass more information to the MouseEvent constructor (#37672)

- Instead of eagerly computing `pageX` and `pageY`, collect the offset
  from the content's initial containing block in the compositor and pass
  that information through to `MouseEvent`. This prevents a layout flush
  that was happening when eagerly trying to fetch `Document` scroll
  offsets.
- Pass keyboard modifiers properly to `MouseEvent`.
- Now all this information is stored and passed as `Point2D` (typed) and
  `Modifiers` which greatly reduces the amount of arguments that need to
  be passed around.

Testing: It is difficult to test input events as they require WebDriver
which
isn't completely working yet. I have manually run Speedometer 2.1 and I
have
verified that this fixes the regression from #37601.
Fixes: #37601.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-06-25 14:29:27 +02:00 committed by GitHub
parent 50cf01cf3d
commit 0346a62214
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 374 additions and 369 deletions

View file

@ -5,8 +5,11 @@
use std::cell::Cell;
use dom_struct::dom_struct;
use euclid::default::Point2D;
use euclid::Point2D;
use js::rust::HandleObject;
use keyboard_types::Modifiers;
use script_bindings::codegen::GenericBindings::WindowBinding::WindowMethods;
use style_traits::CSSPixel;
use super::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods;
use crate::dom::bindings::cell::DomRefCell;
@ -95,18 +98,14 @@ impl PointerEvent {
cancelable: EventCancelable,
view: Option<&Window>,
detail: i32,
screen_x: i32,
screen_y: i32,
client_x: i32,
client_y: i32,
ctrl_key: bool,
alt_key: bool,
shift_key: bool,
meta_key: bool,
screen_point: Point2D<i32, CSSPixel>,
client_point: Point2D<i32, CSSPixel>,
page_point: Point2D<i32, CSSPixel>,
modifiers: Modifiers,
button: i16,
buttons: u16,
related_target: Option<&EventTarget>,
point_in_target: Option<Point2D<f32>>,
point_in_target: Option<Point2D<f32, CSSPixel>>,
pointer_id: i32,
width: i32,
height: i32,
@ -131,14 +130,10 @@ impl PointerEvent {
cancelable,
view,
detail,
screen_x,
screen_y,
client_x,
client_y,
ctrl_key,
alt_key,
shift_key,
meta_key,
screen_point,
client_point,
page_point,
modifiers,
button,
buttons,
related_target,
@ -170,18 +165,14 @@ impl PointerEvent {
cancelable: EventCancelable,
view: Option<&Window>,
detail: i32,
screen_x: i32,
screen_y: i32,
client_x: i32,
client_y: i32,
ctrl_key: bool,
alt_key: bool,
shift_key: bool,
meta_key: bool,
screen_point: Point2D<i32, CSSPixel>,
client_point: Point2D<i32, CSSPixel>,
page_point: Point2D<i32, CSSPixel>,
modifiers: Modifiers,
button: i16,
buttons: u16,
related_target: Option<&EventTarget>,
point_in_target: Option<Point2D<f32>>,
point_in_target: Option<Point2D<f32, CSSPixel>>,
pointer_id: i32,
width: i32,
height: i32,
@ -205,14 +196,10 @@ impl PointerEvent {
cancelable,
view,
detail,
screen_x,
screen_y,
client_x,
client_y,
ctrl_key,
alt_key,
shift_key,
meta_key,
screen_point,
client_point,
page_point,
modifiers,
button,
buttons,
related_target,
@ -247,6 +234,10 @@ impl PointerEventMethods<crate::DomTypeHolder> for PointerEvent {
) -> DomRoot<PointerEvent> {
let bubbles = EventBubbles::from(init.parent.parent.parent.parent.bubbles);
let cancelable = EventCancelable::from(init.parent.parent.parent.parent.cancelable);
let page_point = Point2D::new(
window.ScrollX() + init.parent.clientX,
window.ScrollY() + init.parent.clientY,
);
PointerEvent::new_with_proto(
window,
proto,
@ -255,14 +246,10 @@ impl PointerEventMethods<crate::DomTypeHolder> for PointerEvent {
cancelable,
init.parent.parent.parent.view.as_deref(),
init.parent.parent.parent.detail,
init.parent.screenX,
init.parent.screenY,
init.parent.clientX,
init.parent.clientY,
init.parent.parent.ctrlKey,
init.parent.parent.altKey,
init.parent.parent.shiftKey,
init.parent.parent.metaKey,
Point2D::new(init.parent.screenX, init.parent.screenY),
Point2D::new(init.parent.clientX, init.parent.clientY),
page_point,
init.parent.parent.modifiers(),
init.parent.button,
init.parent.buttons,
init.parent.relatedTarget.as_deref(),