mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
LibWeb: Allow layout nodes to receive and track mouse events
To implement form controls internally in LibWeb (necessary for multi process forms), we'll need the ability to handle events since we can't rely on LibGUI widgets anymore. A LayoutNode can now override wants_mouse_events() and if it returns true, it will now receive mousedown, mousemove and mouseup events. :^)
This commit is contained in:
parent
5782099106
commit
d6889ecf35
Notes:
sideshowbarker
2024-07-19 02:45:54 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/d6889ecf359
4 changed files with 67 additions and 0 deletions
|
@ -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<EventHandler>, const Gfx::IntPoint&, unsigned, unsigned)
|
||||
{
|
||||
}
|
||||
|
||||
void LayoutNode::handle_mouseup(Badge<EventHandler>, const Gfx::IntPoint&, unsigned, unsigned)
|
||||
{
|
||||
}
|
||||
|
||||
void LayoutNode::handle_mousemove(Badge<EventHandler>, const Gfx::IntPoint&, unsigned, unsigned)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<EventHandler>, const Gfx::IntPoint&, unsigned button, unsigned modifiers);
|
||||
virtual void handle_mouseup(Badge<EventHandler>, const Gfx::IntPoint&, unsigned button, unsigned modifiers);
|
||||
virtual void handle_mousemove(Badge<EventHandler>, const Gfx::IntPoint&, unsigned buttons, unsigned modifiers);
|
||||
|
||||
enum class LayoutMode {
|
||||
Default,
|
||||
AllPossibleLineBreaks,
|
||||
|
|
|
@ -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<DOM::Node> node = result.layout_node->node();
|
||||
if (is<HTML::HTMLIFrameElement>(*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<DOM::Node> 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<DOM::Node> node = result.layout_node->node();
|
||||
|
||||
if (node && is<HTML::HTMLIFrameElement>(*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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Forward.h>
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <Kernel/API/KeyCode.h>
|
||||
#include <LibGUI/Forward.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
|
@ -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<LayoutNode> m_mouse_event_tracking_layout_node;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue