embedder_traits/
input_events.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::sync::atomic::{AtomicUsize, Ordering};
6
7use bitflags::bitflags;
8use keyboard_types::{Code, CompositionEvent, Key, KeyState, Location, Modifiers};
9use log::error;
10use malloc_size_of_derive::MallocSizeOf;
11use serde::{Deserialize, Serialize};
12use webrender_api::ExternalScrollId;
13use webrender_api::units::DevicePoint;
14
15#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
16pub struct InputEventId(usize);
17
18static INPUT_EVENT_ID: AtomicUsize = AtomicUsize::new(0);
19
20impl InputEventId {
21    fn new() -> Self {
22        Self(INPUT_EVENT_ID.fetch_add(1, Ordering::Relaxed))
23    }
24}
25
26bitflags! {
27    #[derive(Default, Deserialize, PartialEq, Serialize)]
28    pub struct InputEventResult: u8 {
29        /// Whether or not this input event's default behavior was prevented via script.
30        const DefaultPrevented = 1 << 0;
31        /// Whether or not the WebView handled this event. Some events have default handlers in
32        /// Servo, such as keyboard events that insert characters in `<input>` areas. When these
33        /// handlers are triggered, this flag is included. This can be used to prevent triggering
34        /// behavior (such as keybindings) when the WebView has already consumed the event for its
35        /// own purpose.
36        const Consumed = 1 << 1;
37    }
38}
39
40/// An input event that is sent from the embedder to Servo.
41#[derive(Clone, Debug, Deserialize, Serialize)]
42pub enum InputEvent {
43    EditingAction(EditingActionEvent),
44    Gamepad(GamepadEvent),
45    Ime(ImeEvent),
46    Keyboard(KeyboardEvent),
47    MouseButton(MouseButtonEvent),
48    MouseLeftViewport(MouseLeftViewportEvent),
49    MouseMove(MouseMoveEvent),
50    Scroll(ScrollEvent),
51    Touch(TouchEvent),
52    Wheel(WheelEvent),
53}
54
55#[derive(Clone, Debug, Deserialize, Serialize)]
56pub struct InputEventAndId {
57    pub event: InputEvent,
58    pub id: InputEventId,
59}
60
61impl From<InputEvent> for InputEventAndId {
62    fn from(event: InputEvent) -> Self {
63        Self {
64            event,
65            id: InputEventId::new(),
66        }
67    }
68}
69
70/// An editing action that should be performed on a `WebView`.
71#[derive(Clone, Debug, Deserialize, Serialize)]
72pub enum EditingActionEvent {
73    Copy,
74    Cut,
75    Paste,
76}
77
78impl InputEvent {
79    pub fn point(&self) -> Option<DevicePoint> {
80        match self {
81            InputEvent::EditingAction(..) => None,
82            InputEvent::Gamepad(..) => None,
83            InputEvent::Ime(..) => None,
84            InputEvent::Keyboard(..) => None,
85            InputEvent::MouseButton(event) => Some(event.point),
86            InputEvent::MouseMove(event) => Some(event.point),
87            InputEvent::MouseLeftViewport(_) => None,
88            InputEvent::Touch(event) => Some(event.point),
89            InputEvent::Wheel(event) => Some(event.point),
90            InputEvent::Scroll(..) => None,
91        }
92    }
93}
94
95#[derive(Clone, Debug, Default, Deserialize, Serialize)]
96pub struct KeyboardEvent {
97    pub event: ::keyboard_types::KeyboardEvent,
98}
99
100impl KeyboardEvent {
101    pub fn new(keyboard_event: ::keyboard_types::KeyboardEvent) -> Self {
102        Self {
103            event: keyboard_event,
104        }
105    }
106
107    pub fn new_without_event(
108        state: KeyState,
109        key: Key,
110        code: Code,
111        location: Location,
112        modifiers: Modifiers,
113        repeat: bool,
114        is_composing: bool,
115    ) -> Self {
116        Self::new(::keyboard_types::KeyboardEvent {
117            state,
118            key,
119            code,
120            location,
121            modifiers,
122            repeat,
123            is_composing,
124        })
125    }
126
127    pub fn from_state_and_key(state: KeyState, key: Key) -> Self {
128        Self::new(::keyboard_types::KeyboardEvent {
129            state,
130            key,
131            ..::keyboard_types::KeyboardEvent::default()
132        })
133    }
134}
135
136#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
137pub struct MouseButtonEvent {
138    pub action: MouseButtonAction,
139    pub button: MouseButton,
140    pub point: DevicePoint,
141}
142
143impl MouseButtonEvent {
144    pub fn new(action: MouseButtonAction, button: MouseButton, point: DevicePoint) -> Self {
145        Self {
146            action,
147            button,
148            point,
149        }
150    }
151}
152
153#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
154pub enum MouseButton {
155    Left,
156    Middle,
157    Right,
158    Back,
159    Forward,
160    Other(u16),
161}
162
163impl<T: Into<u64>> From<T> for MouseButton {
164    fn from(value: T) -> Self {
165        let value = value.into();
166        match value {
167            0 => MouseButton::Left,
168            1 => MouseButton::Middle,
169            2 => MouseButton::Right,
170            3 => MouseButton::Back,
171            4 => MouseButton::Forward,
172            _ => MouseButton::Other(value as u16),
173        }
174    }
175}
176
177impl From<MouseButton> for i16 {
178    fn from(value: MouseButton) -> Self {
179        match value {
180            MouseButton::Left => 0,
181            MouseButton::Middle => 1,
182            MouseButton::Right => 2,
183            MouseButton::Back => 3,
184            MouseButton::Forward => 4,
185            MouseButton::Other(value) => value as i16,
186        }
187    }
188}
189
190/// The types of mouse events
191#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
192pub enum MouseButtonAction {
193    /// Mouse button down
194    Down,
195    /// Mouse button up
196    Up,
197}
198
199#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
200pub struct MouseMoveEvent {
201    pub point: DevicePoint,
202}
203
204impl MouseMoveEvent {
205    pub fn new(point: DevicePoint) -> Self {
206        Self { point }
207    }
208}
209
210#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)]
211pub struct MouseLeftViewportEvent {
212    pub focus_moving_to_another_iframe: bool,
213}
214
215/// The type of input represented by a multi-touch event.
216#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
217pub enum TouchEventType {
218    /// A new touch point came in contact with the screen.
219    Down,
220    /// An existing touch point changed location.
221    Move,
222    /// A touch point was removed from the screen.
223    Up,
224    /// The system stopped tracking a touch point.
225    Cancel,
226}
227
228/// An opaque identifier for a touch point.
229///
230/// <http://w3c.github.io/touch-events/#widl-Touch-identifier>
231#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
232pub struct TouchId(pub i32);
233
234/// An ID for a sequence of touch events between a `Down` and the `Up` or `Cancel` event.
235/// The ID is the same for all events between `Down` and `Up` or `Cancel`
236#[repr(transparent)]
237#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
238pub struct TouchSequenceId(u32);
239
240impl TouchSequenceId {
241    pub const fn new() -> Self {
242        Self(0)
243    }
244
245    /// Increments the ID for the next touch sequence.
246    ///
247    /// The increment is wrapping, since we can assume that the touch handler
248    /// script for touch sequence N will have finished processing by the time
249    /// we have wrapped around.
250    pub fn next(&mut self) {
251        self.0 = self.0.wrapping_add(1);
252    }
253}
254
255#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
256pub struct TouchEvent {
257    pub event_type: TouchEventType,
258    pub id: TouchId,
259    pub point: DevicePoint,
260    /// cancelable default value is true, once the first move has been processed by script disable it.
261    cancelable: bool,
262    /// The sequence_id will be set by servo's touch handler.
263    sequence_id: Option<TouchSequenceId>,
264}
265
266impl TouchEvent {
267    pub fn new(event_type: TouchEventType, id: TouchId, point: DevicePoint) -> Self {
268        TouchEvent {
269            event_type,
270            id,
271            point,
272            sequence_id: None,
273            cancelable: true,
274        }
275    }
276    /// Embedders should ignore this.
277    #[doc(hidden)]
278    pub fn init_sequence_id(&mut self, sequence_id: TouchSequenceId) {
279        if self.sequence_id.is_none() {
280            self.sequence_id = Some(sequence_id);
281        } else {
282            // We could allow embedders to set the sequence ID.
283            error!("Sequence ID already set.");
284        }
285    }
286
287    #[doc(hidden)]
288    pub fn expect_sequence_id(&self) -> TouchSequenceId {
289        self.sequence_id.expect("Sequence ID not initialized")
290    }
291
292    #[doc(hidden)]
293    pub fn disable_cancelable(&mut self) {
294        self.cancelable = false;
295    }
296
297    #[doc(hidden)]
298    pub fn is_cancelable(&self) -> bool {
299        self.cancelable
300    }
301}
302
303/// Mode to measure WheelDelta floats in
304#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
305pub enum WheelMode {
306    /// Delta values are specified in pixels
307    DeltaPixel = 0x00,
308    /// Delta values are specified in lines
309    DeltaLine = 0x01,
310    /// Delta values are specified in pages
311    DeltaPage = 0x02,
312}
313
314/// The Wheel event deltas in every direction
315#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
316pub struct WheelDelta {
317    /// Delta in the left/right direction
318    pub x: f64,
319    /// Delta in the up/down direction
320    pub y: f64,
321    /// Delta in the direction going into/out of the screen
322    pub z: f64,
323    /// Mode to measure the floats in
324    pub mode: WheelMode,
325}
326
327#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
328pub struct WheelEvent {
329    pub delta: WheelDelta,
330    pub point: DevicePoint,
331}
332
333impl WheelEvent {
334    pub fn new(delta: WheelDelta, point: DevicePoint) -> Self {
335        WheelEvent { delta, point }
336    }
337}
338
339#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
340pub struct ScrollEvent {
341    pub external_id: ExternalScrollId,
342}
343
344#[derive(Clone, Debug, Deserialize, Serialize)]
345pub enum ImeEvent {
346    Composition(CompositionEvent),
347    Dismissed,
348}
349
350#[derive(
351    Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize,
352)]
353/// Index of gamepad in list of system's connected gamepads
354pub struct GamepadIndex(pub usize);
355
356#[derive(Clone, Debug, Deserialize, Serialize)]
357/// The minimum and maximum values that can be reported for axis or button input from this gamepad
358pub struct GamepadInputBounds {
359    /// Minimum and maximum axis values
360    pub axis_bounds: (f64, f64),
361    /// Minimum and maximum button values
362    pub button_bounds: (f64, f64),
363}
364
365#[derive(Clone, Debug, Deserialize, Serialize)]
366/// The haptic effects supported by this gamepad
367pub struct GamepadSupportedHapticEffects {
368    /// Gamepad support for dual rumble effects
369    pub supports_dual_rumble: bool,
370    /// Gamepad support for trigger rumble effects
371    pub supports_trigger_rumble: bool,
372}
373
374#[derive(Clone, Debug, Deserialize, Serialize)]
375/// The type of Gamepad event
376pub enum GamepadEvent {
377    /// A new gamepad has been connected
378    /// <https://www.w3.org/TR/gamepad/#event-gamepadconnected>
379    Connected(
380        GamepadIndex,
381        String,
382        GamepadInputBounds,
383        GamepadSupportedHapticEffects,
384    ),
385    /// An existing gamepad has been disconnected
386    /// <https://www.w3.org/TR/gamepad/#event-gamepaddisconnected>
387    Disconnected(GamepadIndex),
388    /// An existing gamepad has been updated
389    /// <https://www.w3.org/TR/gamepad/#receiving-inputs>
390    Updated(GamepadIndex, GamepadUpdateType),
391}
392
393#[derive(Clone, Debug, Deserialize, Serialize)]
394/// The type of Gamepad input being updated
395pub enum GamepadUpdateType {
396    /// Axis index and input value
397    /// <https://www.w3.org/TR/gamepad/#dfn-represents-a-standard-gamepad-axis>
398    Axis(usize, f64),
399    /// Button index and input value
400    /// <https://www.w3.org/TR/gamepad/#dfn-represents-a-standard-gamepad-button>
401    Button(usize, f64),
402}