Coverage Report

Created: 2026-02-16 07:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibWeb/UIEvents/PointerEvent.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <LibWeb/UIEvents/MouseEvent.h>
10
#include <LibWeb/WebIDL/Types.h>
11
12
namespace Web::UIEvents {
13
14
struct PointerEventInit : public MouseEventInit {
15
    WebIDL::Long pointer_id { 0 };
16
    double width { 1 };
17
    double height { 1 };
18
    float pressure { 0 };
19
    float tangential_pressure { 0 };
20
    Optional<WebIDL::Long> tilt_x;
21
    Optional<WebIDL::Long> tilt_y;
22
    WebIDL::Long twist { 0 };
23
    Optional<double> altitude_angle;
24
    Optional<double> azimuth_angle;
25
    String pointer_type;
26
    bool is_primary { false };
27
    WebIDL::Long persistent_device_id { 0 };
28
    AK::Vector<JS::Handle<PointerEvent>> coalesced_events;
29
    AK::Vector<JS::Handle<PointerEvent>> predicted_events;
30
};
31
32
// https://w3c.github.io/pointerevents/#pointerevent-interface
33
class PointerEvent : public MouseEvent {
34
    WEB_PLATFORM_OBJECT(PointerEvent, MouseEvent);
35
    JS_DECLARE_ALLOCATOR(PointerEvent);
36
37
public:
38
    [[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);
39
    static WebIDL::ExceptionOr<JS::NonnullGCPtr<PointerEvent>> construct_impl(JS::Realm&, FlyString const& type, PointerEventInit const&);
40
41
    virtual ~PointerEvent() override;
42
43
0
    WebIDL::Long pointer_id() const { return m_pointer_id; }
44
0
    double width() const { return m_width; }
45
0
    double height() const { return m_height; }
46
0
    float pressure() const { return m_pressure; }
47
0
    float tangential_pressure() const { return m_tangential_pressure; }
48
0
    WebIDL::Long tilt_x() const { return m_tilt_x; }
49
0
    WebIDL::Long tilt_y() const { return m_tilt_y; }
50
0
    WebIDL::Long twist() const { return m_twist; }
51
0
    double altitude_angle() const { return m_altitude_angle; }
52
0
    double azimuth_angle() const { return m_azimuth_angle; }
53
0
    String const& pointer_type() const { return m_pointer_type; }
54
0
    bool is_primary() const { return m_is_primary; }
55
0
    WebIDL::Long persistent_device_id() const { return m_persistent_device_id; }
56
0
    AK::ReadonlySpan<JS::NonnullGCPtr<PointerEvent>> get_coalesced_events() const { return m_coalesced_events; }
57
0
    AK::ReadonlySpan<JS::NonnullGCPtr<PointerEvent>> get_predicted_events() const { return m_predicted_events; }
58
59
    // https://w3c.github.io/pointerevents/#dom-pointerevent-pressure
60
    // For hardware and platforms that do not support pressure, the value MUST be 0.5 when in the active buttons state and 0 otherwise.
61
    static constexpr float ACTIVE_PRESSURE_DEFAULT_IN_ACTIVE_BUTTON_STATE { 0.5 };
62
63
protected:
64
    PointerEvent(JS::Realm&, FlyString const& type, PointerEventInit const&, double page_x, double page_y, double offset_x, double offset_y);
65
66
    virtual void initialize(JS::Realm&) override;
67
    virtual void visit_edges(Cell::Visitor&) override;
68
69
private:
70
0
    virtual bool is_pointer_event() const final { return true; }
71
72
    // A unique identifier for the pointer causing the event.
73
    // https://w3c.github.io/pointerevents/#dom-pointerevent-pointerid
74
    WebIDL::Long m_pointer_id { 0 };
75
76
    // The width (magnitude on the X axis), in CSS pixels (see [CSS21]), of the contact geometry of the pointer
77
    // https://w3c.github.io/pointerevents/#dom-pointerevent-width
78
    double m_width { 1 };
79
80
    // The height (magnitude on the Y axis), in CSS pixels (see [CSS21]), of the contact geometry of the pointer.
81
    // https://w3c.github.io/pointerevents/#dom-pointerevent-width
82
    double m_height { 1 };
83
84
    // The normalized pressure of the pointer input in the range of [0,1], where 0 and 1 represent the minimum and
85
    // maximum pressure the hardware is capable of detecting, respectively
86
    // https://w3c.github.io/pointerevents/#dom-pointerevent-pressure
87
    float m_pressure { 0 };
88
89
    // The normalized tangential pressure (also known as barrel pressure), typically set by an additional control
90
    // (e.g. a finger wheel on an airbrush stylus), of the pointer input in the range of [-1,1], where 0 is the
91
    // neutral position of the control
92
    // https://w3c.github.io/pointerevents/#dom-pointerevent-tangentialpressure
93
    float m_tangential_pressure { 0 };
94
95
    // The plane angle (in degrees, in the range of [-90,90]) between the Y-Z plane and the plane containing both the
96
    // transducer (e.g. pen/stylus) axis and the Y axis
97
    // https://w3c.github.io/pointerevents/#dom-pointerevent-tiltx
98
    WebIDL::Long m_tilt_x { 0 };
99
100
    // The plane angle (in degrees, in the range of [-90,90]) between the X-Z plane and the plane containing both the
101
    // transducer (e.g. pen/stylus) axis and the X axis
102
    // https://w3c.github.io/pointerevents/#dom-pointerevent-tilty
103
    WebIDL::Long m_tilt_y { 0 };
104
105
    // The clockwise rotation (in degrees, in the range of [0,359]) of a transducer (e.g. pen/stylus) around its own major axis
106
    // https://w3c.github.io/pointerevents/#dom-pointerevent-twist
107
    WebIDL::Long m_twist { 0 };
108
109
    // The altitude (in radians) of the transducer (e.g. pen/stylus), in the range [0,π/2] — where 0 is parallel to the surface
110
    // (X-Y plane), and π/2 is perpendicular to the surface
111
    // For hardware and platforms that do not report tilt or angle, the value MUST be π/2.
112
    // https://w3c.github.io/pointerevents/#dom-pointerevent-altitudeangle
113
    static constexpr double DEFAULT_ALTITUDE_ANGLE { AK::Pi<double> / 2 };
114
    double m_altitude_angle { DEFAULT_ALTITUDE_ANGLE };
115
116
    // The azimuth angle (in radians) of the transducer (e.g. pen/stylus), in the range [0, 2π] — where 0 represents a transducer
117
    // whose cap is pointing in the direction of increasing X values (point to "3 o'clock" if looking straight down) on the X-Y
118
    // plane, and the values progressively increase when going clockwise (π/2 at "6 o'clock", π at "9 o'clock", 3π/2 at "12 o'clock").
119
    // https://w3c.github.io/pointerevents/#dom-pointerevent-azimuthangle
120
    double m_azimuth_angle { 0 };
121
122
    // Indicates the device type that caused the event (mouse, pen, touch, etc.)
123
    // https://w3c.github.io/pointerevents/#dom-pointerevent-pointertype
124
    String m_pointer_type;
125
126
    // Indicates if the pointer represents the primary pointer of this pointer type
127
    // https://w3c.github.io/pointerevents/#dom-pointerevent-isprimary
128
    bool m_is_primary { false };
129
130
    // A unique identifier for the pointing device.
131
    // https://w3c.github.io/pointerevents/#dom-pointerevent-persistentdeviceid
132
    WebIDL::Long m_persistent_device_id { 0 };
133
134
    // https://w3c.github.io/pointerevents/#dom-pointerevent-getcoalescedevents
135
    AK::Vector<JS::NonnullGCPtr<PointerEvent>> m_coalesced_events;
136
137
    // https://w3c.github.io/pointerevents/#dom-pointerevent-getpredictedevents
138
    AK::Vector<JS::NonnullGCPtr<PointerEvent>> m_predicted_events;
139
};
140
141
}
142
143
namespace Web::DOM {
144
145
template<>
146
0
inline bool Event::fast_is<UIEvents::PointerEvent>() const { return is_pointer_event(); }
147
148
}