diff --git a/Userland/Libraries/LibWeb/Page/EventHandler.cpp b/Userland/Libraries/LibWeb/Page/EventHandler.cpp index c9816975f7..688dc0b9c2 100644 --- a/Userland/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Userland/Libraries/LibWeb/Page/EventHandler.cpp @@ -40,6 +40,63 @@ namespace Web { +static Gfx::StandardCursor cursor_css_to_gfx(Optional cursor) +{ + if (!cursor.has_value()) { + return Gfx::StandardCursor::None; + } + switch (cursor.value()) { + case CSS::Cursor::Crosshair: + case CSS::Cursor::Cell: + return Gfx::StandardCursor::Crosshair; + case CSS::Cursor::Grab: + case CSS::Cursor::Grabbing: + return Gfx::StandardCursor::Drag; + case CSS::Cursor::Pointer: + return Gfx::StandardCursor::Hand; + case CSS::Cursor::Help: + return Gfx::StandardCursor::Help; + case CSS::Cursor::None: + return Gfx::StandardCursor::Hidden; + case CSS::Cursor::Text: + case CSS::Cursor::VerticalText: + return Gfx::StandardCursor::IBeam; + case CSS::Cursor::Move: + case CSS::Cursor::AllScroll: + return Gfx::StandardCursor::Move; + case CSS::Cursor::Progress: + case CSS::Cursor::Wait: + return Gfx::StandardCursor::Wait; + + case CSS::Cursor::ColResize: + return Gfx::StandardCursor::ResizeColumn; + case CSS::Cursor::EResize: + case CSS::Cursor::WResize: + case CSS::Cursor::EwResize: + return Gfx::StandardCursor::ResizeHorizontal; + + case CSS::Cursor::RowResize: + return Gfx::StandardCursor::ResizeRow; + case CSS::Cursor::NResize: + case CSS::Cursor::SResize: + case CSS::Cursor::NsResize: + return Gfx::StandardCursor::ResizeVertical; + + case CSS::Cursor::NeResize: + case CSS::Cursor::SwResize: + case CSS::Cursor::NeswResize: + return Gfx::StandardCursor::ResizeDiagonalBLTR; + + case CSS::Cursor::NwResize: + case CSS::Cursor::SeResize: + case CSS::Cursor::NwseResize: + return Gfx::StandardCursor::ResizeDiagonalTLBR; + + default: + return Gfx::StandardCursor::None; + } +} + static Gfx::IntPoint compute_mouse_event_offset(const Gfx::IntPoint& position, const Layout::Node& layout_node) { auto top_left_of_layout_node = layout_node.box_type_agnostic_position(); @@ -239,7 +296,7 @@ bool EventHandler::handle_mousemove(const Gfx::IntPoint& position, unsigned butt bool hovered_node_changed = false; bool is_hovering_link = false; - bool is_hovering_text = false; + Gfx::StandardCursor hovered_node_cursor = Gfx::StandardCursor::None; auto result = layout_root()->hit_test(position, Layout::HitTestType::Exact); const HTML::HTMLAnchorElement* hovered_link_element = nullptr; if (result.layout_node) { @@ -264,11 +321,16 @@ bool EventHandler::handle_mousemove(const Gfx::IntPoint& position, unsigned butt hovered_node_changed = node != document.hovered_node(); document.set_hovered_node(node); if (node) { - if (node->is_text()) - is_hovering_text = true; hovered_link_element = node->enclosing_link_element(); if (hovered_link_element) is_hovering_link = true; + + auto cursor = result.layout_node->computed_values().cursor(); + if (node->is_text() && cursor == CSS::Cursor::Auto) + hovered_node_cursor = Gfx::StandardCursor::IBeam; + else + hovered_node_cursor = cursor_css_to_gfx(cursor); + auto offset = compute_mouse_event_offset(position, *result.layout_node); node->dispatch_event(UIEvents::MouseEvent::create(UIEvents::EventNames::mousemove, offset.x(), offset.y())); // NOTE: Dispatching an event may have disturbed the world. @@ -287,12 +349,7 @@ bool EventHandler::handle_mousemove(const Gfx::IntPoint& position, unsigned butt } if (auto* page = m_frame.page()) { - if (is_hovering_link) - page->client().page_did_request_cursor_change(Gfx::StandardCursor::Hand); - else if (is_hovering_text) - page->client().page_did_request_cursor_change(Gfx::StandardCursor::IBeam); - else - page->client().page_did_request_cursor_change(Gfx::StandardCursor::None); + page->client().page_did_request_cursor_change(hovered_node_cursor); if (hovered_node_changed) { RefPtr hovered_html_element = document.hovered_node() ? document.hovered_node()->enclosing_html_element() : nullptr;