mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-03 14:50:02 +00:00
LibWeb: Dispatch pointer events in EventHandler
Now, along with the mouse events we also dispatch pointerup, pointerdown and pointermove. With this change shape painting works on https://excalidraw.com/
This commit is contained in:
parent
e4dc758343
commit
8614e0f856
Notes:
github-actions[bot]
2024-11-21 23:33:48 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 8614e0f856
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2491
6 changed files with 87 additions and 20 deletions
|
@ -31,6 +31,7 @@
|
||||||
#include <LibWeb/UIEvents/KeyboardEvent.h>
|
#include <LibWeb/UIEvents/KeyboardEvent.h>
|
||||||
#include <LibWeb/UIEvents/MouseButton.h>
|
#include <LibWeb/UIEvents/MouseButton.h>
|
||||||
#include <LibWeb/UIEvents/MouseEvent.h>
|
#include <LibWeb/UIEvents/MouseEvent.h>
|
||||||
|
#include <LibWeb/UIEvents/PointerEvent.h>
|
||||||
#include <LibWeb/UIEvents/WheelEvent.h>
|
#include <LibWeb/UIEvents/WheelEvent.h>
|
||||||
|
|
||||||
namespace Web {
|
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 page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
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());
|
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;
|
handled_event = EventResult::Handled;
|
||||||
|
|
||||||
|
@ -436,6 +438,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
|
||||||
m_mousedown_target = node.ptr();
|
m_mousedown_target = node.ptr();
|
||||||
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
auto page_offset = compute_mouse_event_page_offset(viewport_position);
|
||||||
auto offset = compute_mouse_event_offset(page_offset, *layout_node);
|
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());
|
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;
|
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_)
|
if (!continue_)
|
||||||
return EventResult::Cancelled;
|
return EventResult::Cancelled;
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, the SerenityOS developers.
|
* Copyright (c) 2020, the SerenityOS developers.
|
||||||
* Copyright (c) 2021, Andreas Kling <andreas@ladybird.org>
|
* Copyright (c) 2021, Andreas Kling <andreas@ladybird.org>
|
||||||
|
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Error.h>
|
|
||||||
#include <AK/FlyString.h>
|
#include <AK/FlyString.h>
|
||||||
|
|
||||||
namespace Web::UIEvents::EventNames {
|
namespace Web::UIEvents::EventNames {
|
||||||
|
@ -31,6 +31,13 @@ namespace Web::UIEvents::EventNames {
|
||||||
__ENUMERATE_UI_EVENT(mouseout) \
|
__ENUMERATE_UI_EVENT(mouseout) \
|
||||||
__ENUMERATE_UI_EVENT(mouseover) \
|
__ENUMERATE_UI_EVENT(mouseover) \
|
||||||
__ENUMERATE_UI_EVENT(mouseup) \
|
__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(resize) \
|
||||||
__ENUMERATE_UI_EVENT(wheel)
|
__ENUMERATE_UI_EVENT(wheel)
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,31 @@ namespace Web::UIEvents {
|
||||||
|
|
||||||
GC_DEFINE_ALLOCATOR(PointerEvent);
|
GC_DEFINE_ALLOCATOR(PointerEvent);
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<GC::Ref<PointerEvent>> PointerEvent::create_from_platform_event(JS::Realm& realm, FlyString const& event_name, CSSPixelPoint screen, CSSPixelPoint page, CSSPixelPoint client, CSSPixelPoint offset, Optional<CSSPixelPoint> 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<MouseButton>(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)
|
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)
|
: MouseEvent(realm, type, event_init, page_x, page_y, offset_x, offset_y)
|
||||||
, m_pointer_id(event_init.pointer_id)
|
, m_pointer_id(event_init.pointer_id)
|
||||||
|
|
|
@ -36,6 +36,7 @@ class PointerEvent : public MouseEvent {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] static GC::Ref<PointerEvent> 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 GC::Ref<PointerEvent> 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<GC::Ref<PointerEvent>> create_from_platform_event(JS::Realm&, FlyString const& event_name, CSSPixelPoint screen, CSSPixelPoint page, CSSPixelPoint client, CSSPixelPoint offset, Optional<CSSPixelPoint> movement, unsigned button, unsigned buttons, unsigned modifiers);
|
||||||
static WebIDL::ExceptionOr<GC::Ref<PointerEvent>> construct_impl(JS::Realm&, FlyString const& type, PointerEventInit const&);
|
static WebIDL::ExceptionOr<GC::Ref<PointerEvent>> construct_impl(JS::Realm&, FlyString const& type, PointerEventInit const&);
|
||||||
|
|
||||||
virtual ~PointerEvent() override;
|
virtual ~PointerEvent() override;
|
||||||
|
|
4
Tests/LibWeb/Text/expected/UIEvents/pointer-events.txt
Normal file
4
Tests/LibWeb/Text/expected/UIEvents/pointer-events.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
pointerdown at (10, 20)
|
||||||
|
mousedown at (10, 20)
|
||||||
|
pointerup at (10, 20)
|
||||||
|
mouseup at (10, 20)
|
24
Tests/LibWeb/Text/input/UIEvents/pointer-events.html
Normal file
24
Tests/LibWeb/Text/input/UIEvents/pointer-events.html
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<script>
|
||||||
|
asyncTest(done => {
|
||||||
|
function logEvent(event) {
|
||||||
|
println(`${event.type} at (${event.clientX}, ${event.clientY})`);
|
||||||
|
if (event.type === "mouseup") {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventsToLog = [
|
||||||
|
'pointerdown',
|
||||||
|
'pointerup',
|
||||||
|
'mousedown',
|
||||||
|
'mouseup',
|
||||||
|
];
|
||||||
|
eventsToLog.forEach(eventType => {
|
||||||
|
window.addEventListener(eventType, logEvent);
|
||||||
|
});
|
||||||
|
|
||||||
|
internals.click(10, 20);
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue