mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-07 08:39:22 +00:00
LibWeb: Use paintables when calculating mouse event offset
This commit is contained in:
parent
c9105955f6
commit
bdd6729d78
Notes:
github-actions[bot]
2024-12-20 14:51:39 +00:00
Author: https://github.com/Gingeh
Commit: bdd6729d78
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2986
Reviewed-by: https://github.com/gmta ✅
3 changed files with 40 additions and 18 deletions
|
@ -148,7 +148,7 @@ static Gfx::StandardCursor cursor_css_to_gfx(Optional<CSS::Cursor> cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx
|
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx
|
||||||
static CSSPixelPoint compute_mouse_event_offset(CSSPixelPoint position, Layout::Node const& layout_node)
|
static CSSPixelPoint compute_mouse_event_offset(CSSPixelPoint position, Painting::Paintable const& paintable)
|
||||||
{
|
{
|
||||||
// If the event’s dispatch flag is set,
|
// If the event’s dispatch flag is set,
|
||||||
// FIXME: Is this guaranteed to be dispatched?
|
// FIXME: Is this guaranteed to be dispatched?
|
||||||
|
@ -160,11 +160,11 @@ static CSSPixelPoint compute_mouse_event_offset(CSSPixelPoint position, Layout::
|
||||||
};
|
};
|
||||||
|
|
||||||
// ignoring the transforms that apply to the element and its ancestors,
|
// ignoring the transforms that apply to the element and its ancestors,
|
||||||
if (layout_node.has_css_transform()) {
|
if (paintable.layout_node().has_css_transform()) {
|
||||||
auto const& paintable_box = layout_node.dom_node()->paintable_box();
|
auto const& paintable_box = static_cast<Painting::PaintableBox const&>(paintable);
|
||||||
auto const affine_transform = Gfx::extract_2d_affine_transform(paintable_box->transform().inverse());
|
auto const affine_transform = Gfx::extract_2d_affine_transform(paintable_box.transform().inverse());
|
||||||
|
|
||||||
auto const& origin = paintable_box->transform_origin();
|
auto const& origin = paintable_box.transform_origin();
|
||||||
Gfx::Point<float> const precision_origin = {
|
Gfx::Point<float> const precision_origin = {
|
||||||
origin.x().to_double(),
|
origin.x().to_double(),
|
||||||
origin.y().to_double()
|
origin.y().to_double()
|
||||||
|
@ -176,7 +176,7 @@ static CSSPixelPoint compute_mouse_event_offset(CSSPixelPoint position, Layout::
|
||||||
}
|
}
|
||||||
|
|
||||||
// relative to the origin of the padding edge of the target node
|
// relative to the origin of the padding edge of the target node
|
||||||
auto const top_left_of_layout_node = layout_node.first_paintable()->box_type_agnostic_position();
|
auto const top_left_of_layout_node = paintable.box_type_agnostic_position();
|
||||||
CSSPixelPoint offset = {
|
CSSPixelPoint offset = {
|
||||||
CSSPixels(precision_offset.x()),
|
CSSPixels(precision_offset.x()),
|
||||||
CSSPixels(precision_offset.y())
|
CSSPixels(precision_offset.y())
|
||||||
|
@ -252,7 +252,7 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
|
||||||
// FIXME: Support wheel events in nested browsing contexts.
|
// FIXME: Support wheel events in nested browsing contexts.
|
||||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||||
auto& iframe = static_cast<HTML::HTMLIFrameElement&>(*node);
|
auto& iframe = static_cast<HTML::HTMLIFrameElement&>(*node);
|
||||||
auto position_in_iframe = viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node()));
|
auto position_in_iframe = viewport_position.translated(compute_mouse_event_offset({}, *paintable));
|
||||||
iframe.content_navigable()->event_handler().handle_mousewheel(position_in_iframe, screen_position, button, buttons, modifiers, wheel_delta_x, wheel_delta_y);
|
iframe.content_navigable()->event_handler().handle_mousewheel(position_in_iframe, screen_position, button, buttons, modifiers, wheel_delta_x, wheel_delta_y);
|
||||||
return EventResult::Dropped;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
|
||||||
return EventResult::Dropped;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
auto offset = compute_mouse_event_offset(page_offset, *layout_node->first_paintable());
|
||||||
if (node->dispatch_event(UIEvents::WheelEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::wheel, screen_position, page_offset, viewport_position, offset, wheel_delta_x, wheel_delta_y, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors())) {
|
if (node->dispatch_event(UIEvents::WheelEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::wheel, screen_position, page_offset, viewport_position, offset, wheel_delta_x, wheel_delta_y, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors())) {
|
||||||
m_navigable->active_window()->scroll_by(wheel_delta_x, wheel_delta_y);
|
m_navigable->active_window()->scroll_by(wheel_delta_x, wheel_delta_y);
|
||||||
}
|
}
|
||||||
|
@ -314,7 +314,7 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
|
||||||
if (node) {
|
if (node) {
|
||||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||||
return content_navigable->event_handler().handle_mouseup(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
return content_navigable->event_handler().handle_mouseup(viewport_position.translated(compute_mouse_event_offset({}, *paintable)), screen_position, button, buttons, modifiers);
|
||||||
return EventResult::Dropped;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
|
||||||
}
|
}
|
||||||
|
|
||||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
auto offset = compute_mouse_event_offset(page_offset, *layout_node->first_paintable());
|
||||||
node->dispatch_event(UIEvents::PointerEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::pointerup, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
node->dispatch_event(UIEvents::PointerEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::pointerup, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||||
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mouseup, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mouseup, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||||
handled_event = EventResult::Handled;
|
handled_event = EventResult::Handled;
|
||||||
|
@ -453,7 +453,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
|
||||||
|
|
||||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||||
return content_navigable->event_handler().handle_mousedown(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
return content_navigable->event_handler().handle_mousedown(viewport_position.translated(compute_mouse_event_offset({}, *paintable)), screen_position, button, buttons, modifiers);
|
||||||
return EventResult::Dropped;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,7 +468,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
|
||||||
|
|
||||||
m_mousedown_target = node.ptr();
|
m_mousedown_target = node.ptr();
|
||||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
auto offset = compute_mouse_event_offset(page_offset, *layout_node->first_paintable());
|
||||||
node->dispatch_event(UIEvents::PointerEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::pointerdown, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
node->dispatch_event(UIEvents::PointerEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::pointerdown, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||||
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousedown, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousedown, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||||
}
|
}
|
||||||
|
@ -573,7 +573,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
|
||||||
|
|
||||||
if (node && is<HTML::HTMLIFrameElement>(*node)) {
|
if (node && is<HTML::HTMLIFrameElement>(*node)) {
|
||||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||||
return content_navigable->event_handler().handle_mousemove(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, buttons, modifiers);
|
return content_navigable->event_handler().handle_mousemove(viewport_position.translated(compute_mouse_event_offset({}, *paintable)), screen_position, buttons, modifiers);
|
||||||
return EventResult::Dropped;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,7 +607,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
|
||||||
}
|
}
|
||||||
|
|
||||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
auto offset = compute_mouse_event_offset(page_offset, *layout_node->first_paintable());
|
||||||
auto movement = compute_mouse_event_movement(screen_position);
|
auto movement = compute_mouse_event_movement(screen_position);
|
||||||
|
|
||||||
m_mousemove_previous_screen_position = screen_position;
|
m_mousemove_previous_screen_position = screen_position;
|
||||||
|
@ -716,7 +716,7 @@ EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CS
|
||||||
|
|
||||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||||
return content_navigable->event_handler().handle_doubleclick(viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers);
|
return content_navigable->event_handler().handle_doubleclick(viewport_position.translated(compute_mouse_event_offset({}, *paintable)), screen_position, button, buttons, modifiers);
|
||||||
return EventResult::Dropped;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,7 +727,7 @@ EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CS
|
||||||
return EventResult::Dropped;
|
return EventResult::Dropped;
|
||||||
|
|
||||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
auto offset = compute_mouse_event_offset(page_offset, *layout_node->first_paintable());
|
||||||
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::dblclick, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::dblclick, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
|
||||||
|
|
||||||
// NOTE: Dispatching an event may have disturbed the world.
|
// NOTE: Dispatching an event may have disturbed the world.
|
||||||
|
@ -784,12 +784,12 @@ EventResult EventHandler::handle_drag_and_drop_event(DragEvent::Type type, CSSPi
|
||||||
|
|
||||||
if (is<HTML::HTMLIFrameElement>(*node)) {
|
if (is<HTML::HTMLIFrameElement>(*node)) {
|
||||||
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
if (auto content_navigable = static_cast<HTML::HTMLIFrameElement&>(*node).content_navigable())
|
||||||
return content_navigable->event_handler().handle_drag_and_drop_event(type, viewport_position.translated(compute_mouse_event_offset({}, paintable->layout_node())), screen_position, button, buttons, modifiers, move(files));
|
return content_navigable->event_handler().handle_drag_and_drop_event(type, viewport_position.translated(compute_mouse_event_offset({}, *paintable)), screen_position, button, buttons, modifiers, move(files));
|
||||||
return EventResult::Dropped;
|
return EventResult::Dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||||
auto offset = compute_mouse_event_offset(page_offset, paintable->layout_node());
|
auto offset = compute_mouse_event_offset(page_offset, *paintable);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DragEvent::Type::DragStart:
|
case DragEvent::Type::DragStart:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
PASS (didn't crash)
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<style>
|
||||||
|
div::before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background-color: gray;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
internals.click(50, 60);
|
||||||
|
println("PASS (didn't crash)");
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue