diff --git a/Libraries/LibWeb/Layout/LayoutNode.cpp b/Libraries/LibWeb/Layout/LayoutNode.cpp index 5bd0aebd64..c44e886d8f 100644 --- a/Libraries/LibWeb/Layout/LayoutNode.cpp +++ b/Libraries/LibWeb/Layout/LayoutNode.cpp @@ -254,4 +254,16 @@ void LayoutNodeWithStyle::apply_style(const CSS::StyleProperties& specified_styl style.border_bottom().color = specified_style.color_or_fallback(CSS::PropertyID::BorderBottomColor, document(), Color::Transparent); } +void LayoutNode::handle_mousedown(Badge, const Gfx::IntPoint&, unsigned, unsigned) +{ +} + +void LayoutNode::handle_mouseup(Badge, const Gfx::IntPoint&, unsigned, unsigned) +{ +} + +void LayoutNode::handle_mousemove(Badge, const Gfx::IntPoint&, unsigned, unsigned) +{ +} + } diff --git a/Libraries/LibWeb/Layout/LayoutNode.h b/Libraries/LibWeb/Layout/LayoutNode.h index 246d40761f..b9cc0136ad 100644 --- a/Libraries/LibWeb/Layout/LayoutNode.h +++ b/Libraries/LibWeb/Layout/LayoutNode.h @@ -99,6 +99,12 @@ public: bool is_inline_block() const { return is_inline() && is_block(); } + virtual bool wants_mouse_events() const { return false; } + + virtual void handle_mousedown(Badge, const Gfx::IntPoint&, unsigned button, unsigned modifiers); + virtual void handle_mouseup(Badge, const Gfx::IntPoint&, unsigned button, unsigned modifiers); + virtual void handle_mousemove(Badge, const Gfx::IntPoint&, unsigned buttons, unsigned modifiers); + enum class LayoutMode { Default, AllPossibleLineBreaks, diff --git a/Libraries/LibWeb/Page/EventHandler.cpp b/Libraries/LibWeb/Page/EventHandler.cpp index 32b750a821..57b73c9673 100644 --- a/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Libraries/LibWeb/Page/EventHandler.cpp @@ -75,9 +75,20 @@ bool EventHandler::handle_mouseup(const Gfx::IntPoint& position, unsigned button { if (!layout_root()) return false; + + if (m_mouse_event_tracking_layout_node) { + m_mouse_event_tracking_layout_node->handle_mouseup({}, position, button, modifiers); + return true; + } + bool handled_event = false; auto result = layout_root()->hit_test(position, HitTestType::Exact); + + if (result.layout_node && result.layout_node->wants_mouse_events()) { + result.layout_node->handle_mouseup({}, position, button, modifiers); + } + if (result.layout_node && result.layout_node->node()) { RefPtr node = result.layout_node->node(); if (is(*node)) { @@ -101,6 +112,12 @@ bool EventHandler::handle_mousedown(const Gfx::IntPoint& position, unsigned butt { if (!layout_root()) return false; + + if (m_mouse_event_tracking_layout_node) { + m_mouse_event_tracking_layout_node->handle_mousedown({}, position, button, modifiers); + return true; + } + NonnullRefPtr document = *m_frame.document(); auto& page_client = m_frame.page().client(); @@ -108,6 +125,11 @@ bool EventHandler::handle_mousedown(const Gfx::IntPoint& position, unsigned butt if (!result.layout_node) return false; + if (result.layout_node->wants_mouse_events()) { + result.layout_node->handle_mousedown({}, position, button, modifiers); + return true; + } + RefPtr node = result.layout_node->node(); document->set_hovered_node(node); if (!node) @@ -171,6 +193,12 @@ bool EventHandler::handle_mousemove(const Gfx::IntPoint& position, unsigned butt { if (!layout_root()) return false; + + if (m_mouse_event_tracking_layout_node) { + m_mouse_event_tracking_layout_node->handle_mousemove({}, position, buttons, modifiers); + return true; + } + auto& document = *m_frame.document(); auto& page_client = m_frame.page().client(); @@ -180,6 +208,14 @@ bool EventHandler::handle_mousemove(const Gfx::IntPoint& position, unsigned butt auto result = layout_root()->hit_test(position, HitTestType::Exact); const HTML::HTMLAnchorElement* hovered_link_element = nullptr; if (result.layout_node) { + + if (result.layout_node->wants_mouse_events()) { + result.layout_node->handle_mousemove({}, position, buttons, modifiers); + // FIXME: It feels a bit aggressive to always update the cursor like this. + page_client.page_did_request_cursor_change(Gfx::StandardCursor::None); + return true; + } + RefPtr node = result.layout_node->node(); if (node && is(*node)) { @@ -313,4 +349,12 @@ bool EventHandler::handle_keydown(KeyCode key, unsigned modifiers, u32 code_poin return false; } +void EventHandler::set_mouse_event_tracking_layout_node(LayoutNode* layout_node) +{ + if (layout_node) + m_mouse_event_tracking_layout_node = layout_node->make_weak_ptr(); + else + m_mouse_event_tracking_layout_node = nullptr; +} + } diff --git a/Libraries/LibWeb/Page/EventHandler.h b/Libraries/LibWeb/Page/EventHandler.h index 37350184bc..e077a71ded 100644 --- a/Libraries/LibWeb/Page/EventHandler.h +++ b/Libraries/LibWeb/Page/EventHandler.h @@ -27,6 +27,7 @@ #pragma once #include +#include #include #include #include @@ -47,6 +48,8 @@ public: bool handle_keydown(KeyCode, unsigned modifiers, u32 code_point); + void set_mouse_event_tracking_layout_node(LayoutNode*); + private: bool focus_next_element(); bool focus_previous_element(); @@ -59,6 +62,8 @@ private: Frame& m_frame; bool m_in_mouse_selection { false }; + + WeakPtr m_mouse_event_tracking_layout_node; }; }