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 malloc_size_of_derive::MallocSizeOf;
10use serde::{Deserialize, Serialize};
11use webrender_api::ExternalScrollId;
12
13use crate::WebViewPoint;
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(Clone, Copy, 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    #[cfg(feature = "gamepad")]
45    Gamepad(GamepadEvent),
46    Ime(ImeEvent),
47    Keyboard(KeyboardEvent),
48    MouseButton(MouseButtonEvent),
49    MouseLeftViewport(MouseLeftViewportEvent),
50    MouseMove(MouseMoveEvent),
51    Scroll(ScrollEvent),
52    Touch(TouchEvent),
53    Wheel(WheelEvent),
54}
55
56#[derive(Clone, Debug, Deserialize, Serialize)]
57pub struct InputEventAndId {
58    pub event: InputEvent,
59    pub id: InputEventId,
60}
61
62impl From<InputEvent> for InputEventAndId {
63    fn from(event: InputEvent) -> Self {
64        Self {
65            event,
66            id: InputEventId::new(),
67        }
68    }
69}
70
71/// An editing action that should be performed on a `WebView`.
72#[derive(Clone, Debug, Deserialize, Serialize)]
73pub enum EditingActionEvent {
74    Copy,
75    Cut,
76    Paste,
77}
78
79impl InputEvent {
80    pub fn point(&self) -> Option<WebViewPoint> {
81        match self {
82            InputEvent::EditingAction(..) => None,
83            #[cfg(feature = "gamepad")]
84            InputEvent::Gamepad(..) => None,
85            InputEvent::Ime(..) => None,
86            InputEvent::Keyboard(..) => None,
87            InputEvent::MouseButton(event) => Some(event.point),
88            InputEvent::MouseMove(event) => Some(event.point),
89            InputEvent::MouseLeftViewport(_) => None,
90            InputEvent::Touch(event) => Some(event.point),
91            InputEvent::Wheel(event) => Some(event.point),
92            InputEvent::Scroll(..) => None,
93        }
94    }
95}
96
97#[derive(Clone, Debug, Default, Deserialize, Serialize)]
98pub struct KeyboardEvent {
99    pub event: ::keyboard_types::KeyboardEvent,
100}
101
102impl KeyboardEvent {
103    pub fn new(keyboard_event: ::keyboard_types::KeyboardEvent) -> Self {
104        Self {
105            event: keyboard_event,
106        }
107    }
108
109    pub fn new_without_event(
110        state: KeyState,
111        key: Key,
112        code: Code,
113        location: Location,
114        modifiers: Modifiers,
115        repeat: bool,
116        is_composing: bool,
117    ) -> Self {
118        Self::new(::keyboard_types::KeyboardEvent {
119            state,
120            key,
121            code,
122            location,
123            modifiers,
124            repeat,
125            is_composing,
126        })
127    }
128
129    pub fn from_state_and_key(state: KeyState, key: Key) -> Self {
130        Self::new(::keyboard_types::KeyboardEvent {
131            state,
132            key,
133            ..::keyboard_types::KeyboardEvent::default()
134        })
135    }
136}
137
138#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
139pub struct MouseButtonEvent {
140    pub action: MouseButtonAction,
141    pub button: MouseButton,
142    pub point: WebViewPoint,
143}
144
145impl MouseButtonEvent {
146    pub fn new(action: MouseButtonAction, button: MouseButton, point: WebViewPoint) -> Self {
147        Self {
148            action,
149            button,
150            point,
151        }
152    }
153}
154
155#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
156pub enum MouseButton {
157    Left,
158    Middle,
159    Right,
160    Back,
161    Forward,
162    Other(u16),
163}
164
165impl<T: Into<u64>> From<T> for MouseButton {
166    fn from(value: T) -> Self {
167        let value = value.into();
168        match value {
169            0 => MouseButton::Left,
170            1 => MouseButton::Middle,
171            2 => MouseButton::Right,
172            3 => MouseButton::Back,
173            4 => MouseButton::Forward,
174            _ => MouseButton::Other(value as u16),
175        }
176    }
177}
178
179impl From<MouseButton> for i16 {
180    fn from(value: MouseButton) -> Self {
181        match value {
182            MouseButton::Left => 0,
183            MouseButton::Middle => 1,
184            MouseButton::Right => 2,
185            MouseButton::Back => 3,
186            MouseButton::Forward => 4,
187            MouseButton::Other(value) => value as i16,
188        }
189    }
190}
191
192/// The types of mouse events
193#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
194pub enum MouseButtonAction {
195    /// Mouse button down
196    Down,
197    /// Mouse button up
198    Up,
199}
200
201#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
202pub struct MouseMoveEvent {
203    pub point: WebViewPoint,
204    pub is_compatibility_event_for_touch: bool,
205}
206
207impl MouseMoveEvent {
208    pub fn new(point: WebViewPoint) -> Self {
209        Self {
210            point,
211            is_compatibility_event_for_touch: false,
212        }
213    }
214
215    pub fn new_compatibility_for_touch(point: WebViewPoint) -> Self {
216        Self {
217            point,
218            is_compatibility_event_for_touch: true,
219        }
220    }
221}
222
223#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)]
224pub struct MouseLeftViewportEvent {
225    pub focus_moving_to_another_iframe: bool,
226}
227
228/// The type of input represented by a multi-touch event.
229#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
230pub enum TouchEventType {
231    /// A new touch point came in contact with the screen.
232    Down,
233    /// An existing touch point changed location.
234    Move,
235    /// A touch point was removed from the screen.
236    Up,
237    /// The system stopped tracking a touch point.
238    Cancel,
239}
240
241/// An opaque identifier for a touch point.
242///
243/// <http://w3c.github.io/touch-events/#widl-Touch-identifier>
244#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
245pub struct TouchId(pub i32);
246
247#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
248pub struct TouchEvent {
249    pub event_type: TouchEventType,
250    pub id: TouchId,
251    pub point: WebViewPoint,
252    /// cancelable default value is true, once the first move has been processed by script disable it.
253    cancelable: bool,
254}
255
256impl TouchEvent {
257    pub fn new(event_type: TouchEventType, id: TouchId, point: WebViewPoint) -> Self {
258        TouchEvent {
259            event_type,
260            id,
261            point,
262            cancelable: true,
263        }
264    }
265
266    #[doc(hidden)]
267    pub fn disable_cancelable(&mut self) {
268        self.cancelable = false;
269    }
270
271    #[doc(hidden)]
272    pub fn is_cancelable(&self) -> bool {
273        self.cancelable
274    }
275}
276
277/// Mode to measure WheelDelta floats in
278#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
279pub enum WheelMode {
280    /// Delta values are specified in pixels
281    DeltaPixel = 0x00,
282    /// Delta values are specified in lines
283    DeltaLine = 0x01,
284    /// Delta values are specified in pages
285    DeltaPage = 0x02,
286}
287
288/// The Wheel event deltas in every direction
289#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
290pub struct WheelDelta {
291    /// Delta in the left/right direction
292    pub x: f64,
293    /// Delta in the up/down direction
294    pub y: f64,
295    /// Delta in the direction going into/out of the screen
296    pub z: f64,
297    /// Mode to measure the floats in
298    pub mode: WheelMode,
299}
300
301#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
302pub struct WheelEvent {
303    pub delta: WheelDelta,
304    pub point: WebViewPoint,
305}
306
307impl WheelEvent {
308    pub fn new(delta: WheelDelta, point: WebViewPoint) -> Self {
309        WheelEvent { delta, point }
310    }
311}
312
313#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
314pub struct ScrollEvent {
315    pub external_id: ExternalScrollId,
316}
317
318#[derive(Clone, Debug, Deserialize, Serialize)]
319pub enum ImeEvent {
320    Composition(CompositionEvent),
321    Dismissed,
322}
323
324#[cfg(feature = "gamepad")]
325#[derive(
326    Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize,
327)]
328/// Index of gamepad in list of system's connected gamepads
329pub struct GamepadIndex(pub usize);
330
331#[cfg(feature = "gamepad")]
332#[derive(Clone, Debug, Deserialize, Serialize)]
333/// The minimum and maximum values that can be reported for axis or button input from this gamepad
334pub struct GamepadInputBounds {
335    /// Minimum and maximum axis values
336    pub axis_bounds: (f64, f64),
337    /// Minimum and maximum button values
338    pub button_bounds: (f64, f64),
339}
340
341#[cfg(feature = "gamepad")]
342#[derive(Clone, Debug, Deserialize, Serialize)]
343/// The haptic effects supported by this gamepad
344pub struct GamepadSupportedHapticEffects {
345    /// Gamepad support for dual rumble effects
346    pub supports_dual_rumble: bool,
347    /// Gamepad support for trigger rumble effects
348    pub supports_trigger_rumble: bool,
349}
350
351#[cfg(feature = "gamepad")]
352#[derive(Clone, Debug, Deserialize, Serialize)]
353/// The type of Gamepad event
354pub enum GamepadEvent {
355    /// A new gamepad has been connected
356    /// <https://www.w3.org/TR/gamepad/#event-gamepadconnected>
357    Connected(
358        GamepadIndex,
359        String,
360        GamepadInputBounds,
361        GamepadSupportedHapticEffects,
362    ),
363    /// An existing gamepad has been disconnected
364    /// <https://www.w3.org/TR/gamepad/#event-gamepaddisconnected>
365    Disconnected(GamepadIndex),
366    /// An existing gamepad has been updated
367    /// <https://www.w3.org/TR/gamepad/#receiving-inputs>
368    Updated(GamepadIndex, GamepadUpdateType),
369}
370
371#[cfg(feature = "gamepad")]
372#[derive(Clone, Debug, Deserialize, Serialize)]
373/// The type of Gamepad input being updated
374pub enum GamepadUpdateType {
375    /// Axis index and input value
376    /// <https://www.w3.org/TR/gamepad/#dfn-represents-a-standard-gamepad-axis>
377    Axis(usize, f64),
378    /// Button index and input value
379    /// <https://www.w3.org/TR/gamepad/#dfn-represents-a-standard-gamepad-button>
380    Button(usize, f64),
381}