mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-10 01:51:03 +09:00
LibWeb: Implement the PointerEvent interface
As defined in: https://w3c.github.io/pointerevents With the exception of the getCoalescedEvents and getPredictedEvents APIs. There are still many other parts of that spec (such as the event handlers) left to implement, but this does get us at least some of the way.
This commit is contained in:
parent
d7b77d7695
commit
b873e5bc1d
Notes:
sideshowbarker
2024-07-16 21:45:42 +09:00
Author: https://github.com/shannonbooth
Commit: b873e5bc1d
Pull-request: https://github.com/SerenityOS/serenity/pull/23886
Reviewed-by: https://github.com/kennethmyhra ✅
9 changed files with 224 additions and 0 deletions
|
@ -62,6 +62,7 @@ static bool is_platform_object(Type const& type)
|
|||
"Path2D"sv,
|
||||
"PerformanceEntry"sv,
|
||||
"PerformanceMark"sv,
|
||||
"PointerEvent"sv,
|
||||
"ReadableStreamBYOBReader"sv,
|
||||
"ReadableStreamDefaultReader"sv,
|
||||
"RadioNodeList"sv,
|
||||
|
|
|
@ -635,6 +635,7 @@ set(SOURCES
|
|||
UIEvents/FocusEvent.cpp
|
||||
UIEvents/KeyboardEvent.cpp
|
||||
UIEvents/MouseEvent.cpp
|
||||
UIEvents/PointerEvent.cpp
|
||||
UIEvents/UIEvent.cpp
|
||||
UIEvents/WheelEvent.cpp
|
||||
UserTiming/PerformanceMark.cpp
|
||||
|
|
|
@ -148,6 +148,7 @@ public:
|
|||
bool fast_is() const = delete;
|
||||
|
||||
virtual bool is_mouse_event() const { return false; }
|
||||
virtual bool is_pointer_event() const { return false; }
|
||||
|
||||
protected:
|
||||
void initialize_event(String const&, bool, bool);
|
||||
|
|
|
@ -656,6 +656,7 @@ class SVGTitleElement;
|
|||
namespace Web::UIEvents {
|
||||
class KeyboardEvent;
|
||||
class MouseEvent;
|
||||
class PointerEvent;
|
||||
class UIEvents;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <LibWeb/UIEvents/EventNames.h>
|
||||
#include <LibWeb/UIEvents/FocusEvent.h>
|
||||
#include <LibWeb/UIEvents/MouseEvent.h>
|
||||
#include <LibWeb/UIEvents/PointerEvent.h>
|
||||
#include <LibWeb/WebIDL/DOMException.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
|
|
49
Userland/Libraries/LibWeb/UIEvents/PointerEvent.cpp
Normal file
49
Userland/Libraries/LibWeb/UIEvents/PointerEvent.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/PointerEventPrototype.h>
|
||||
#include <LibWeb/UIEvents/PointerEvent.h>
|
||||
|
||||
namespace Web::UIEvents {
|
||||
|
||||
JS_DEFINE_ALLOCATOR(PointerEvent);
|
||||
|
||||
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)
|
||||
, m_width(event_init.width)
|
||||
, m_height(event_init.height)
|
||||
, m_pressure(event_init.pressure)
|
||||
, m_tangential_pressure(event_init.tangential_pressure)
|
||||
, m_tilt_x(event_init.tilt_x.value_or(0))
|
||||
, m_tilt_y(event_init.tilt_y.value_or(0))
|
||||
, m_twist(event_init.twist)
|
||||
, m_altitude_angle(event_init.altitude_angle.value_or(DEFAULT_ALTITUDE_ANGLE))
|
||||
, m_azimuth_angle(event_init.azimuth_angle.value_or(0))
|
||||
, m_pointer_type(event_init.pointer_type)
|
||||
, m_is_primary(event_init.is_primary)
|
||||
{
|
||||
}
|
||||
|
||||
PointerEvent::~PointerEvent() = default;
|
||||
|
||||
void PointerEvent::initialize(JS::Realm& realm)
|
||||
{
|
||||
Base::initialize(realm);
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(PointerEvent);
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<PointerEvent> PointerEvent::create(JS::Realm& realm, FlyString const& type, PointerEventInit const& event_init, double page_x, double page_y, double offset_x, double offset_y)
|
||||
{
|
||||
return realm.heap().allocate<PointerEvent>(realm, realm, type, event_init, page_x, page_y, offset_x, offset_y);
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<PointerEvent>> PointerEvent::construct_impl(JS::Realm& realm, FlyString const& type, PointerEventInit const& event_init)
|
||||
{
|
||||
return create(realm, type, event_init);
|
||||
}
|
||||
|
||||
}
|
131
Userland/Libraries/LibWeb/UIEvents/PointerEvent.h
Normal file
131
Userland/Libraries/LibWeb/UIEvents/PointerEvent.h
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/UIEvents/MouseEvent.h>
|
||||
#include <LibWeb/WebIDL/Types.h>
|
||||
|
||||
namespace Web::UIEvents {
|
||||
|
||||
struct PointerEventInit : public MouseEventInit {
|
||||
WebIDL::Long pointer_id { 0 };
|
||||
double width { 1 };
|
||||
double height { 1 };
|
||||
float pressure { 0 };
|
||||
float tangential_pressure { 0 };
|
||||
Optional<WebIDL::Long> tilt_x;
|
||||
Optional<WebIDL::Long> tilt_y;
|
||||
WebIDL::Long twist { 0 };
|
||||
Optional<double> altitude_angle;
|
||||
Optional<double> azimuth_angle;
|
||||
String pointer_type;
|
||||
bool is_primary { false };
|
||||
};
|
||||
|
||||
// https://w3c.github.io/pointerevents/#pointerevent-interface
|
||||
class PointerEvent : public MouseEvent {
|
||||
WEB_PLATFORM_OBJECT(PointerEvent, MouseEvent);
|
||||
JS_DECLARE_ALLOCATOR(PointerEvent);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static JS::NonnullGCPtr<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);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<PointerEvent>> construct_impl(JS::Realm&, FlyString const& type, PointerEventInit const&);
|
||||
|
||||
virtual ~PointerEvent() override;
|
||||
|
||||
WebIDL::Long pointer_id() const { return m_pointer_id; }
|
||||
double width() const { return m_width; }
|
||||
double height() const { return m_height; }
|
||||
float pressure() const { return m_pressure; }
|
||||
float tangential_pressure() const { return m_tangential_pressure; }
|
||||
WebIDL::Long tilt_x() const { return m_tilt_x; }
|
||||
WebIDL::Long tilt_y() const { return m_tilt_y; }
|
||||
WebIDL::Long twist() const { return m_twist; }
|
||||
double altitude_angle() const { return m_altitude_angle; }
|
||||
double azimuth_angle() const { return m_azimuth_angle; }
|
||||
String const& pointer_type() const { return m_pointer_type; }
|
||||
bool is_primary() const { return m_is_primary; }
|
||||
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-pressure
|
||||
// For hardware and platforms that do not support pressure, the value MUST be 0.5 when in the active buttons state and 0 otherwise.
|
||||
static constexpr float ACTIVE_PRESSURE_DEFAULT_IN_ACTIVE_BUTTON_STATE { 0.5 };
|
||||
|
||||
protected:
|
||||
PointerEvent(JS::Realm&, FlyString const& type, PointerEventInit const&, double page_x, double page_y, double offset_x, double offset_y);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
private:
|
||||
virtual bool is_pointer_event() const final { return true; }
|
||||
|
||||
// A unique identifier for the pointer causing the event.
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-pointerid
|
||||
WebIDL::Long m_pointer_id { 0 };
|
||||
|
||||
// The width (magnitude on the X axis), in CSS pixels (see [CSS21]), of the contact geometry of the pointer
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-width
|
||||
double m_width { 1 };
|
||||
|
||||
// The height (magnitude on the Y axis), in CSS pixels (see [CSS21]), of the contact geometry of the pointer.
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-width
|
||||
double m_height { 1 };
|
||||
|
||||
// The normalized pressure of the pointer input in the range of [0,1], where 0 and 1 represent the minimum and
|
||||
// maximum pressure the hardware is capable of detecting, respectively
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-pressure
|
||||
float m_pressure { 0 };
|
||||
|
||||
// The normalized tangential pressure (also known as barrel pressure), typically set by an additional control
|
||||
// (e.g. a finger wheel on an airbrush stylus), of the pointer input in the range of [-1,1], where 0 is the
|
||||
// neutral position of the control
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-tangentialpressure
|
||||
float m_tangential_pressure { 0 };
|
||||
|
||||
// The plane angle (in degrees, in the range of [-90,90]) between the Y-Z plane and the plane containing both the
|
||||
// transducer (e.g. pen/stylus) axis and the Y axis
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-tiltx
|
||||
WebIDL::Long m_tilt_x { 0 };
|
||||
|
||||
// The plane angle (in degrees, in the range of [-90,90]) between the X-Z plane and the plane containing both the
|
||||
// transducer (e.g. pen/stylus) axis and the X axis
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-tilty
|
||||
WebIDL::Long m_tilt_y { 0 };
|
||||
|
||||
// The clockwise rotation (in degrees, in the range of [0,359]) of a transducer (e.g. pen/stylus) around its own major axis
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-twist
|
||||
WebIDL::Long m_twist { 0 };
|
||||
|
||||
// The altitude (in radians) of the transducer (e.g. pen/stylus), in the range [0,π/2] — where 0 is parallel to the surface
|
||||
// (X-Y plane), and π/2 is perpendicular to the surface
|
||||
// For hardware and platforms that do not report tilt or angle, the value MUST be π/2.
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-altitudeangle
|
||||
static constexpr double DEFAULT_ALTITUDE_ANGLE { AK::Pi<double> / 2 };
|
||||
double m_altitude_angle { DEFAULT_ALTITUDE_ANGLE };
|
||||
|
||||
// The azimuth angle (in radians) of the transducer (e.g. pen/stylus), in the range [0, 2π] — where 0 represents a transducer
|
||||
// whose cap is pointing in the direction of increasing X values (point to "3 o'clock" if looking straight down) on the X-Y
|
||||
// plane, and the values progressively increase when going clockwise (π/2 at "6 o'clock", π at "9 o'clock", 3π/2 at "12 o'clock").
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-azimuthangle
|
||||
double m_azimuth_angle { 0 };
|
||||
|
||||
// Indicates the device type that caused the event (mouse, pen, touch, etc.)
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-pointertype
|
||||
String m_pointer_type;
|
||||
|
||||
// Indicates if the pointer represents the primary pointer of this pointer type
|
||||
// https://w3c.github.io/pointerevents/#dom-pointerevent-isprimary
|
||||
bool m_is_primary { false };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
template<>
|
||||
inline bool Event::fast_is<UIEvents::PointerEvent>() const { return is_pointer_event(); }
|
||||
|
||||
}
|
38
Userland/Libraries/LibWeb/UIEvents/PointerEvent.idl
Normal file
38
Userland/Libraries/LibWeb/UIEvents/PointerEvent.idl
Normal file
|
@ -0,0 +1,38 @@
|
|||
#import <UIEvents/MouseEvent.idl>
|
||||
|
||||
dictionary PointerEventInit : MouseEventInit {
|
||||
long pointerId = 0;
|
||||
double width = 1;
|
||||
double height = 1;
|
||||
float pressure = 0;
|
||||
float tangentialPressure = 0;
|
||||
long tiltX;
|
||||
long tiltY;
|
||||
long twist = 0;
|
||||
double altitudeAngle;
|
||||
double azimuthAngle;
|
||||
DOMString pointerType = "";
|
||||
boolean isPrimary = false;
|
||||
// FIXME: sequence<PointerEvent> coalescedEvents = [];
|
||||
// FIXME: sequence<PointerEvent> predictedEvents = [];
|
||||
};
|
||||
|
||||
// https://w3c.github.io/pointerevents/#pointerevent-interface
|
||||
[Exposed=Window]
|
||||
interface PointerEvent : MouseEvent {
|
||||
constructor(DOMString type, optional PointerEventInit eventInitDict = {});
|
||||
readonly attribute long pointerId;
|
||||
readonly attribute double width;
|
||||
readonly attribute double height;
|
||||
readonly attribute float pressure;
|
||||
readonly attribute float tangentialPressure;
|
||||
readonly attribute long tiltX;
|
||||
readonly attribute long tiltY;
|
||||
readonly attribute long twist;
|
||||
readonly attribute double altitudeAngle;
|
||||
readonly attribute double azimuthAngle;
|
||||
readonly attribute DOMString pointerType;
|
||||
readonly attribute boolean isPrimary;
|
||||
// FIXME: [SecureContext] sequence<PointerEvent> getCoalescedEvents();
|
||||
// FIXME: sequence<PointerEvent> getPredictedEvents();
|
||||
};
|
|
@ -279,6 +279,7 @@ libweb_js_bindings(Selection/Selection)
|
|||
libweb_js_bindings(UIEvents/FocusEvent)
|
||||
libweb_js_bindings(UIEvents/KeyboardEvent)
|
||||
libweb_js_bindings(UIEvents/MouseEvent)
|
||||
libweb_js_bindings(UIEvents/PointerEvent)
|
||||
libweb_js_bindings(UIEvents/UIEvent)
|
||||
libweb_js_bindings(UIEvents/WheelEvent)
|
||||
libweb_js_bindings(UserTiming/PerformanceMark)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue