LibWeb+UI: Add an explicit IPC to handle mouse leave events

The faux position we created here is adjusted by the device pixel ratio
later on, which would invoke integer overflow on screens with a DPR
greater than 1.

Instead of creating special data for a mouse move event, let's just add
an explicit leave event handler.
This commit is contained in:
Timothy Flynn 2025-07-28 12:57:31 -04:00 committed by Andreas Kling
parent 8600925713
commit 67cc02ab59
Notes: github-actions[bot] 2025-07-28 19:27:37 +00:00
11 changed files with 66 additions and 7 deletions

View file

@ -861,6 +861,44 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
return EventResult::Handled;
}
EventResult EventHandler::handle_mouseleave()
{
if (should_ignore_device_input_event())
return EventResult::Dropped;
if (!m_navigable->active_document())
return EventResult::Dropped;
if (!m_navigable->active_document()->is_fully_active())
return EventResult::Dropped;
m_navigable->active_document()->update_layout(DOM::UpdateLayoutReason::EventHandlerHandleMouseMove);
if (!paint_root())
return EventResult::Dropped;
auto& document = *m_navigable->active_document();
auto& page = m_navigable->page();
if (auto* hovered_node = document.hovered_node()) {
if (auto* paintable = hovered_node->paintable(); paintable && paintable->wants_mouse_events())
paintable->handle_mouseleave({});
document.set_hovered_node(nullptr);
}
if (page.is_in_tooltip_area()) {
page.set_is_in_tooltip_area(false);
page.client().page_did_leave_tooltip_area();
}
if (page.is_hovering_link()) {
page.set_is_hovering_link(false);
page.client().page_did_unhover_link();
}
return EventResult::Handled;
}
EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
{
if (should_ignore_device_input_event())

View file

@ -29,6 +29,7 @@ public:
EventResult handle_mouseup(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
EventResult handle_mousedown(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
EventResult handle_mousemove(CSSPixelPoint, CSSPixelPoint screen_position, unsigned buttons, unsigned modifiers);
EventResult handle_mouseleave();
EventResult handle_mousewheel(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, int wheel_delta_x, int wheel_delta_y);
EventResult handle_doubleclick(CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);

View file

@ -44,6 +44,7 @@ struct MouseEvent {
MouseDown,
MouseUp,
MouseMove,
MouseLeave,
MouseWheel,
DoubleClick,
};

View file

@ -209,6 +209,11 @@ EventResult Page::handle_mousemove(DevicePixelPoint position, DevicePixelPoint s
return top_level_traversable()->event_handler().handle_mousemove(device_to_css_point(position), device_to_css_point(screen_position), buttons, modifiers);
}
EventResult Page::handle_mouseleave()
{
return top_level_traversable()->event_handler().handle_mouseleave();
}
EventResult Page::handle_mousewheel(DevicePixelPoint position, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, DevicePixels wheel_delta_x, DevicePixels wheel_delta_y)
{
return top_level_traversable()->event_handler().handle_mousewheel(device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers, wheel_delta_x.value(), wheel_delta_y.value());

View file

@ -92,6 +92,7 @@ public:
EventResult handle_mouseup(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
EventResult handle_mousedown(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
EventResult handle_mousemove(DevicePixelPoint, DevicePixelPoint screen_position, unsigned buttons, unsigned modifiers);
EventResult handle_mouseleave();
EventResult handle_mousewheel(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, DevicePixels wheel_delta_x, DevicePixels wheel_delta_y);
EventResult handle_doubleclick(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);