diff --git a/Libraries/LibWeb/Page/EventHandler.cpp b/Libraries/LibWeb/Page/EventHandler.cpp index b5e27638729..6a6c4d7a8ec 100644 --- a/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Libraries/LibWeb/Page/EventHandler.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include namespace Web { @@ -297,6 +298,7 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix auto page_offset = compute_mouse_event_page_offset(viewport_position); auto offset = compute_mouse_event_offset(page_offset, *layout_node); + 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()); handled_event = EventResult::Handled; @@ -436,6 +438,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP m_mousedown_target = node.ptr(); auto page_offset = compute_mouse_event_page_offset(viewport_position); auto offset = compute_mouse_event_offset(page_offset, *layout_node); + 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()); } @@ -578,7 +581,10 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP m_mousemove_previous_screen_position = screen_position; - bool continue_ = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousemove, screen_position, page_offset, viewport_position, offset, movement, UIEvents::MouseButton::Primary, buttons, modifiers).release_value_but_fixme_should_propagate_errors()); + bool continue_ = node->dispatch_event(UIEvents::PointerEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::pointermove, screen_position, page_offset, viewport_position, offset, movement, UIEvents::MouseButton::Primary, buttons, modifiers).release_value_but_fixme_should_propagate_errors()); + if (!continue_) + return EventResult::Cancelled; + continue_ = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::mousemove, screen_position, page_offset, viewport_position, offset, movement, UIEvents::MouseButton::Primary, buttons, modifiers).release_value_but_fixme_should_propagate_errors()); if (!continue_) return EventResult::Cancelled; diff --git a/Libraries/LibWeb/UIEvents/EventNames.h b/Libraries/LibWeb/UIEvents/EventNames.h index 779ef1ccdd1..37a964bee89 100644 --- a/Libraries/LibWeb/UIEvents/EventNames.h +++ b/Libraries/LibWeb/UIEvents/EventNames.h @@ -1,37 +1,44 @@ /* * Copyright (c) 2020, the SerenityOS developers. * Copyright (c) 2021, Andreas Kling + * Copyright (c) 2024, Aliaksandr Kalenik * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once -#include #include namespace Web::UIEvents::EventNames { // FIXME: This is not all of the events -#define ENUMERATE_UI_EVENTS \ - __ENUMERATE_UI_EVENT(auxclick) \ - __ENUMERATE_UI_EVENT(beforeinput) \ - __ENUMERATE_UI_EVENT(click) \ - __ENUMERATE_UI_EVENT(contextmenu) \ - __ENUMERATE_UI_EVENT(dblclick) \ - __ENUMERATE_UI_EVENT(input) \ - __ENUMERATE_UI_EVENT(keydown) \ - __ENUMERATE_UI_EVENT(keypress) \ - __ENUMERATE_UI_EVENT(keyup) \ - __ENUMERATE_UI_EVENT(mousedown) \ - __ENUMERATE_UI_EVENT(mouseenter) \ - __ENUMERATE_UI_EVENT(mouseleave) \ - __ENUMERATE_UI_EVENT(mousemove) \ - __ENUMERATE_UI_EVENT(mouseout) \ - __ENUMERATE_UI_EVENT(mouseover) \ - __ENUMERATE_UI_EVENT(mouseup) \ - __ENUMERATE_UI_EVENT(resize) \ +#define ENUMERATE_UI_EVENTS \ + __ENUMERATE_UI_EVENT(auxclick) \ + __ENUMERATE_UI_EVENT(beforeinput) \ + __ENUMERATE_UI_EVENT(click) \ + __ENUMERATE_UI_EVENT(contextmenu) \ + __ENUMERATE_UI_EVENT(dblclick) \ + __ENUMERATE_UI_EVENT(input) \ + __ENUMERATE_UI_EVENT(keydown) \ + __ENUMERATE_UI_EVENT(keypress) \ + __ENUMERATE_UI_EVENT(keyup) \ + __ENUMERATE_UI_EVENT(mousedown) \ + __ENUMERATE_UI_EVENT(mouseenter) \ + __ENUMERATE_UI_EVENT(mouseleave) \ + __ENUMERATE_UI_EVENT(mousemove) \ + __ENUMERATE_UI_EVENT(mouseout) \ + __ENUMERATE_UI_EVENT(mouseover) \ + __ENUMERATE_UI_EVENT(mouseup) \ + __ENUMERATE_UI_EVENT(pointerdown) \ + __ENUMERATE_UI_EVENT(pointerenter) \ + __ENUMERATE_UI_EVENT(pointerleave) \ + __ENUMERATE_UI_EVENT(pointermove) \ + __ENUMERATE_UI_EVENT(pointerout) \ + __ENUMERATE_UI_EVENT(pointerover) \ + __ENUMERATE_UI_EVENT(pointerup) \ + __ENUMERATE_UI_EVENT(resize) \ __ENUMERATE_UI_EVENT(wheel) #define __ENUMERATE_UI_EVENT(name) extern FlyString name; diff --git a/Libraries/LibWeb/UIEvents/PointerEvent.cpp b/Libraries/LibWeb/UIEvents/PointerEvent.cpp index d6fbe73d59d..ad4c6c48a40 100644 --- a/Libraries/LibWeb/UIEvents/PointerEvent.cpp +++ b/Libraries/LibWeb/UIEvents/PointerEvent.cpp @@ -11,6 +11,31 @@ namespace Web::UIEvents { GC_DEFINE_ALLOCATOR(PointerEvent); +WebIDL::ExceptionOr> PointerEvent::create_from_platform_event(JS::Realm& realm, FlyString const& event_name, CSSPixelPoint screen, CSSPixelPoint page, CSSPixelPoint client, CSSPixelPoint offset, Optional movement, unsigned button, unsigned buttons, unsigned modifiers) +{ + PointerEventInit event_init {}; + event_init.ctrl_key = modifiers & Mod_Ctrl; + event_init.shift_key = modifiers & Mod_Shift; + event_init.alt_key = modifiers & Mod_Alt; + event_init.meta_key = modifiers & Mod_Super; + event_init.screen_x = screen.x().to_double(); + event_init.screen_y = screen.y().to_double(); + event_init.client_x = client.x().to_double(); + event_init.client_y = client.y().to_double(); + if (movement.has_value()) { + event_init.movement_x = movement.value().x().to_double(); + event_init.movement_y = movement.value().y().to_double(); + } + event_init.button = mouse_button_to_button_code(static_cast(button)); + event_init.buttons = buttons; + auto event = PointerEvent::create(realm, event_name, event_init, page.x().to_double(), page.y().to_double(), offset.x().to_double(), offset.y().to_double()); + event->set_is_trusted(true); + event->set_bubbles(true); + event->set_cancelable(true); + event->set_composed(true); + return event; +} + PointerEvent::PointerEvent(JS::Realm& realm, FlyString const& type, PointerEventInit const& event_init, double page_x, double page_y, double offset_x, double offset_y) : MouseEvent(realm, type, event_init, page_x, page_y, offset_x, offset_y) , m_pointer_id(event_init.pointer_id) diff --git a/Libraries/LibWeb/UIEvents/PointerEvent.h b/Libraries/LibWeb/UIEvents/PointerEvent.h index 316372f2080..cabca7b8a45 100644 --- a/Libraries/LibWeb/UIEvents/PointerEvent.h +++ b/Libraries/LibWeb/UIEvents/PointerEvent.h @@ -36,6 +36,7 @@ class PointerEvent : public MouseEvent { public: [[nodiscard]] static GC::Ref create(JS::Realm&, FlyString const& type, PointerEventInit const& = {}, double page_x = 0, double page_y = 0, double offset_x = 0, double offset_y = 0); + [[nodiscard]] static WebIDL::ExceptionOr> create_from_platform_event(JS::Realm&, FlyString const& event_name, CSSPixelPoint screen, CSSPixelPoint page, CSSPixelPoint client, CSSPixelPoint offset, Optional movement, unsigned button, unsigned buttons, unsigned modifiers); static WebIDL::ExceptionOr> construct_impl(JS::Realm&, FlyString const& type, PointerEventInit const&); virtual ~PointerEvent() override; diff --git a/Tests/LibWeb/Text/expected/UIEvents/pointer-events.txt b/Tests/LibWeb/Text/expected/UIEvents/pointer-events.txt new file mode 100644 index 00000000000..2bd873d9615 --- /dev/null +++ b/Tests/LibWeb/Text/expected/UIEvents/pointer-events.txt @@ -0,0 +1,4 @@ +pointerdown at (10, 20) +mousedown at (10, 20) +pointerup at (10, 20) +mouseup at (10, 20) diff --git a/Tests/LibWeb/Text/input/UIEvents/pointer-events.html b/Tests/LibWeb/Text/input/UIEvents/pointer-events.html new file mode 100644 index 00000000000..dde14d0713d --- /dev/null +++ b/Tests/LibWeb/Text/input/UIEvents/pointer-events.html @@ -0,0 +1,24 @@ + + +