mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
[webdriver] Add synchronization for wheel action (#37260)
Implement action synchronization for wheel event. Previously only done for pointer here https://github.com/servo/servo/pull/36932. Testing: `tests/wpt/meta/webdriver/tests/classic/perform_actions/wheel.py` --------- Signed-off-by: PotatoCP <kenzieradityatirtarahardja18@gmail.com>
This commit is contained in:
parent
5114e24db1
commit
15eadb56a4
8 changed files with 89 additions and 34 deletions
|
@ -673,7 +673,7 @@ impl IOCompositor {
|
||||||
let point = dppx.transform_point(Point2D::new(x, y));
|
let point = dppx.transform_point(Point2D::new(x, y));
|
||||||
webview_renderer.dispatch_point_input_event(
|
webview_renderer.dispatch_point_input_event(
|
||||||
InputEvent::MouseButton(MouseButtonEvent::new(action, button, point))
|
InputEvent::MouseButton(MouseButtonEvent::new(action, button, point))
|
||||||
.with_webdriver_message_id(Some(message_id)),
|
.with_webdriver_message_id(message_id),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -686,11 +686,18 @@ impl IOCompositor {
|
||||||
let point = dppx.transform_point(Point2D::new(x, y));
|
let point = dppx.transform_point(Point2D::new(x, y));
|
||||||
webview_renderer.dispatch_point_input_event(
|
webview_renderer.dispatch_point_input_event(
|
||||||
InputEvent::MouseMove(MouseMoveEvent::new(point))
|
InputEvent::MouseMove(MouseMoveEvent::new(point))
|
||||||
.with_webdriver_message_id(Some(message_id)),
|
.with_webdriver_message_id(message_id),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
CompositorMsg::WebDriverWheelScrollEvent(webview_id, x, y, delta_x, delta_y) => {
|
CompositorMsg::WebDriverWheelScrollEvent(
|
||||||
|
webview_id,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
delta_x,
|
||||||
|
delta_y,
|
||||||
|
message_id,
|
||||||
|
) => {
|
||||||
let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
|
let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
|
||||||
warn!("Handling input event for unknown webview: {webview_id}");
|
warn!("Handling input event for unknown webview: {webview_id}");
|
||||||
return;
|
return;
|
||||||
|
@ -705,8 +712,10 @@ impl IOCompositor {
|
||||||
let point = dppx.transform_point(Point2D::new(x, y));
|
let point = dppx.transform_point(Point2D::new(x, y));
|
||||||
let scroll_delta =
|
let scroll_delta =
|
||||||
dppx.transform_vector(Vector2D::new(delta_x as f32, delta_y as f32));
|
dppx.transform_vector(Vector2D::new(delta_x as f32, delta_y as f32));
|
||||||
webview_renderer
|
webview_renderer.dispatch_point_input_event(
|
||||||
.dispatch_point_input_event(InputEvent::Wheel(WheelEvent { delta, point }));
|
InputEvent::Wheel(WheelEvent::new(delta, point))
|
||||||
|
.with_webdriver_message_id(message_id),
|
||||||
|
);
|
||||||
webview_renderer.on_webdriver_wheel_action(scroll_delta, point);
|
webview_renderer.on_webdriver_wheel_action(scroll_delta, point);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -4899,10 +4899,20 @@ where
|
||||||
webview_id, x, y, msg_id,
|
webview_id, x, y, msg_id,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
WebDriverCommandMsg::WheelScrollAction(webview, x, y, delta_x, delta_y) => {
|
WebDriverCommandMsg::WheelScrollAction(
|
||||||
|
webview_id,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
delta_x,
|
||||||
|
delta_y,
|
||||||
|
msg_id,
|
||||||
|
response_sender,
|
||||||
|
) => {
|
||||||
|
self.webdriver.input_command_response_sender = Some(response_sender);
|
||||||
|
|
||||||
self.compositor_proxy
|
self.compositor_proxy
|
||||||
.send(CompositorMsg::WebDriverWheelScrollEvent(
|
.send(CompositorMsg::WebDriverWheelScrollEvent(
|
||||||
webview, x, y, delta_x, delta_y,
|
webview_id, x, y, delta_x, delta_y, msg_id,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
WebDriverCommandMsg::TakeScreenshot(webview_id, rect, response_sender) => {
|
WebDriverCommandMsg::TakeScreenshot(webview_id, rect, response_sender) => {
|
||||||
|
|
|
@ -111,12 +111,12 @@ pub enum CompositorMsg {
|
||||||
MouseButton,
|
MouseButton,
|
||||||
f32,
|
f32,
|
||||||
f32,
|
f32,
|
||||||
WebDriverMessageId,
|
Option<WebDriverMessageId>,
|
||||||
),
|
),
|
||||||
/// WebDriver mouse move event
|
/// WebDriver mouse move event
|
||||||
WebDriverMouseMoveEvent(WebViewId, f32, f32, WebDriverMessageId),
|
WebDriverMouseMoveEvent(WebViewId, f32, f32, Option<WebDriverMessageId>),
|
||||||
// Webdriver wheel scroll event
|
// Webdriver wheel scroll event
|
||||||
WebDriverWheelScrollEvent(WebViewId, f32, f32, f64, f64),
|
WebDriverWheelScrollEvent(WebViewId, f32, f32, f64, f64, Option<WebDriverMessageId>),
|
||||||
|
|
||||||
/// Inform WebRender of the existence of this pipeline.
|
/// Inform WebRender of the existence of this pipeline.
|
||||||
SendInitialTransaction(WebRenderPipelineId),
|
SendInitialTransaction(WebRenderPipelineId),
|
||||||
|
|
|
@ -54,7 +54,7 @@ impl InputEvent {
|
||||||
InputEvent::MouseButton(event) => event.webdriver_id,
|
InputEvent::MouseButton(event) => event.webdriver_id,
|
||||||
InputEvent::MouseMove(event) => event.webdriver_id,
|
InputEvent::MouseMove(event) => event.webdriver_id,
|
||||||
InputEvent::Touch(..) => None,
|
InputEvent::Touch(..) => None,
|
||||||
InputEvent::Wheel(..) => None,
|
InputEvent::Wheel(event) => event.webdriver_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,9 @@ impl InputEvent {
|
||||||
event.webdriver_id = webdriver_id;
|
event.webdriver_id = webdriver_id;
|
||||||
},
|
},
|
||||||
InputEvent::Touch(..) => {},
|
InputEvent::Touch(..) => {},
|
||||||
InputEvent::Wheel(..) => {},
|
InputEvent::Wheel(ref mut event) => {
|
||||||
|
event.webdriver_id = webdriver_id;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
self
|
self
|
||||||
|
@ -275,6 +277,17 @@ pub struct WheelDelta {
|
||||||
pub struct WheelEvent {
|
pub struct WheelEvent {
|
||||||
pub delta: WheelDelta,
|
pub delta: WheelDelta,
|
||||||
pub point: DevicePoint,
|
pub point: DevicePoint,
|
||||||
|
webdriver_id: Option<WebDriverMessageId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WheelEvent {
|
||||||
|
pub fn new(delta: WheelDelta, point: DevicePoint) -> Self {
|
||||||
|
WheelEvent {
|
||||||
|
delta,
|
||||||
|
point,
|
||||||
|
webdriver_id: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
|
|
@ -50,7 +50,8 @@ pub enum WebDriverCommandMsg {
|
||||||
MouseButton,
|
MouseButton,
|
||||||
f32,
|
f32,
|
||||||
f32,
|
f32,
|
||||||
WebDriverMessageId,
|
// Should never be None.
|
||||||
|
Option<WebDriverMessageId>,
|
||||||
IpcSender<WebDriverCommandResponse>,
|
IpcSender<WebDriverCommandResponse>,
|
||||||
),
|
),
|
||||||
/// Act as if the mouse was moved in the browsing context with the given ID.
|
/// Act as if the mouse was moved in the browsing context with the given ID.
|
||||||
|
@ -58,11 +59,23 @@ pub enum WebDriverCommandMsg {
|
||||||
WebViewId,
|
WebViewId,
|
||||||
f32,
|
f32,
|
||||||
f32,
|
f32,
|
||||||
WebDriverMessageId,
|
// None if it's not the last `perform_pointer_move` since we only
|
||||||
|
// expect one response from constellation for each tick actions.
|
||||||
|
Option<WebDriverMessageId>,
|
||||||
IpcSender<WebDriverCommandResponse>,
|
IpcSender<WebDriverCommandResponse>,
|
||||||
),
|
),
|
||||||
/// Act as if the mouse wheel is scrolled in the browsing context given the given ID.
|
/// Act as if the mouse wheel is scrolled in the browsing context given the given ID.
|
||||||
WheelScrollAction(WebViewId, f32, f32, f64, f64),
|
WheelScrollAction(
|
||||||
|
WebViewId,
|
||||||
|
f32,
|
||||||
|
f32,
|
||||||
|
f64,
|
||||||
|
f64,
|
||||||
|
// None if it's not the last `perform_wheel_scroll` since we only
|
||||||
|
// expect one response from constellation for each tick actions.
|
||||||
|
Option<WebDriverMessageId>,
|
||||||
|
IpcSender<WebDriverCommandResponse>,
|
||||||
|
),
|
||||||
/// Set the window size.
|
/// Set the window size.
|
||||||
SetWindowSize(WebViewId, DeviceIntSize, IpcSender<Size2D<f32, CSSPixel>>),
|
SetWindowSize(WebViewId, DeviceIntSize, IpcSender<Size2D<f32, CSSPixel>>),
|
||||||
/// Take a screenshot of the window.
|
/// Take a screenshot of the window.
|
||||||
|
|
|
@ -156,12 +156,16 @@ impl Handler {
|
||||||
&self,
|
&self,
|
||||||
tick_actions: &TickActions,
|
tick_actions: &TickActions,
|
||||||
) -> Result<(), ErrorStatus> {
|
) -> Result<(), ErrorStatus> {
|
||||||
// TODO: Add matches! for wheel and key actions
|
// TODO: Add matches! for key actions
|
||||||
// after implmenting webdriver id for wheel and key events.
|
// after implmenting webdriver id for key events.
|
||||||
let count_non_null_actions_in_tick = tick_actions
|
let count_non_null_actions_in_tick = tick_actions
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, action)| {
|
.filter(|(_, action)| {
|
||||||
matches!(action, ActionItem::Pointer(PointerActionItem::Pointer(_)))
|
matches!(
|
||||||
|
action,
|
||||||
|
ActionItem::Pointer(PointerActionItem::Pointer(_)) |
|
||||||
|
ActionItem::Wheel(WheelActionItem::Wheel(_))
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
|
@ -176,7 +180,7 @@ impl Handler {
|
||||||
let current_waiting_id = self
|
let current_waiting_id = self
|
||||||
.current_action_id
|
.current_action_id
|
||||||
.get()
|
.get()
|
||||||
.expect("Current id should be set before dispat_actions_inner is called");
|
.expect("Current id should be set before dispatch_actions_inner is called");
|
||||||
|
|
||||||
if current_waiting_id != response.id {
|
if current_waiting_id != response.id {
|
||||||
dbg!("Dispatch actions completed with wrong id in response");
|
dbg!("Dispatch actions completed with wrong id in response");
|
||||||
|
@ -345,7 +349,7 @@ impl Handler {
|
||||||
}
|
}
|
||||||
pointer_input_state.pressed.insert(action.button);
|
pointer_input_state.pressed.insert(action.button);
|
||||||
|
|
||||||
let msg_id = self.current_action_id.get().unwrap();
|
let msg_id = self.current_action_id.get();
|
||||||
let cmd_msg = WebDriverCommandMsg::MouseButtonAction(
|
let cmd_msg = WebDriverCommandMsg::MouseButtonAction(
|
||||||
session.webview_id,
|
session.webview_id,
|
||||||
MouseButtonAction::Down,
|
MouseButtonAction::Down,
|
||||||
|
@ -375,7 +379,7 @@ impl Handler {
|
||||||
}
|
}
|
||||||
pointer_input_state.pressed.remove(&action.button);
|
pointer_input_state.pressed.remove(&action.button);
|
||||||
|
|
||||||
let msg_id = self.current_action_id.get().unwrap();
|
let msg_id = self.current_action_id.get();
|
||||||
let cmd_msg = WebDriverCommandMsg::MouseButtonAction(
|
let cmd_msg = WebDriverCommandMsg::MouseButtonAction(
|
||||||
session.webview_id,
|
session.webview_id,
|
||||||
MouseButtonAction::Up,
|
MouseButtonAction::Up,
|
||||||
|
@ -496,9 +500,15 @@ impl Handler {
|
||||||
let current_y = pointer_input_state.y;
|
let current_y = pointer_input_state.y;
|
||||||
|
|
||||||
// Step 7
|
// Step 7
|
||||||
if x != current_x || y != current_y {
|
// Actually "last" should not be checked here based on spec.
|
||||||
|
// However, we need to send the webdriver id at the final perform.
|
||||||
|
if x != current_x || y != current_y || last {
|
||||||
// Step 7.2
|
// Step 7.2
|
||||||
let msg_id = self.current_action_id.get().unwrap();
|
let msg_id = if last {
|
||||||
|
self.current_action_id.get()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
let cmd_msg = WebDriverCommandMsg::MouseMoveAction(
|
let cmd_msg = WebDriverCommandMsg::MouseMoveAction(
|
||||||
session.webview_id,
|
session.webview_id,
|
||||||
x as f32,
|
x as f32,
|
||||||
|
@ -627,14 +637,23 @@ impl Handler {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Step 5
|
// Step 5
|
||||||
if delta_x != 0 || delta_y != 0 {
|
// Actually "last" should not be checked here based on spec.
|
||||||
|
// However, we need to send the webdriver id at the final perform.
|
||||||
|
if delta_x != 0 || delta_y != 0 || last {
|
||||||
// Perform implementation-specific action dispatch steps
|
// Perform implementation-specific action dispatch steps
|
||||||
|
let msg_id = if last {
|
||||||
|
self.current_action_id.get()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
let cmd_msg = WebDriverCommandMsg::WheelScrollAction(
|
let cmd_msg = WebDriverCommandMsg::WheelScrollAction(
|
||||||
session.webview_id,
|
session.webview_id,
|
||||||
x as f32,
|
x as f32,
|
||||||
y as f32,
|
y as f32,
|
||||||
delta_x as f64,
|
delta_x as f64,
|
||||||
delta_y as f64,
|
delta_y as f64,
|
||||||
|
msg_id,
|
||||||
|
self.constellation_sender.clone(),
|
||||||
);
|
);
|
||||||
self.constellation_chan
|
self.constellation_chan
|
||||||
.send(EmbedderToConstellationMessage::WebDriverCommand(cmd_msg))
|
.send(EmbedderToConstellationMessage::WebDriverCommand(cmd_msg))
|
||||||
|
|
|
@ -603,7 +603,7 @@ impl WindowPortsMethods for Window {
|
||||||
let phase = winit_phase_to_touch_event_type(phase);
|
let phase = winit_phase_to_touch_event_type(phase);
|
||||||
|
|
||||||
// Send events
|
// Send events
|
||||||
webview.notify_input_event(InputEvent::Wheel(WheelEvent { delta, point }));
|
webview.notify_input_event(InputEvent::Wheel(WheelEvent::new(delta, point)));
|
||||||
webview.notify_scroll_event(
|
webview.notify_scroll_event(
|
||||||
scroll_location,
|
scroll_location,
|
||||||
self.webview_relative_mouse_point.get().to_i32(),
|
self.webview_relative_mouse_point.get().to_i32(),
|
||||||
|
|
|
@ -1,13 +1,4 @@
|
||||||
[wheel.py]
|
[wheel.py]
|
||||||
[test_scroll_not_scrollable]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test_scroll_scrollable_overflow]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test_scroll_iframe]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test_scroll_shadow_tree[outer-open\]]
|
[test_scroll_shadow_tree[outer-open\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue