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};
11
12use crate::WebViewPoint;
13
14#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
15pub struct InputEventId(usize);
16
17static INPUT_EVENT_ID: AtomicUsize = AtomicUsize::new(0);
18
19impl InputEventId {
20    fn new() -> Self {
21        Self(INPUT_EVENT_ID.fetch_add(1, Ordering::Relaxed))
22    }
23}
24
25bitflags! {
26    #[derive(Clone, Copy, Default, Deserialize, PartialEq, Serialize)]
27    pub struct InputEventResult: u8 {
28        /// Whether or not this input event's default behavior was prevented via script.
29        const DefaultPrevented = 1 << 0;
30        /// Whether or not the WebView handled this event. Some events have default handlers in
31        /// Servo, such as keyboard events that insert characters in `<input>` areas. When these
32        /// handlers are triggered, this flag is included. This can be used to prevent triggering
33        /// behavior (such as keybindings) when the WebView has already consumed the event for its
34        /// own purpose.
35        const Consumed = 1 << 1;
36    }
37}
38
39#[derive(Deserialize, Serialize)]
40pub struct InputEventOutcome {
41    pub id: InputEventId,
42    pub result: InputEventResult,
43}
44
45/// An input event that is sent from the embedder to Servo.
46#[derive(Clone, Debug, Deserialize, Serialize)]
47pub enum InputEvent {
48    EditingAction(EditingActionEvent),
49    #[cfg(feature = "gamepad")]
50    Gamepad(GamepadEvent),
51    Ime(ImeEvent),
52    Keyboard(KeyboardEvent),
53    MouseButton(MouseButtonEvent),
54    MouseLeftViewport(MouseLeftViewportEvent),
55    MouseMove(MouseMoveEvent),
56    Touch(TouchEvent),
57    Wheel(WheelEvent),
58}
59
60#[derive(Clone, Debug, Deserialize, Serialize)]
61pub struct InputEventAndId {
62    pub event: InputEvent,
63    pub id: InputEventId,
64}
65
66impl From<InputEvent> for InputEventAndId {
67    fn from(event: InputEvent) -> Self {
68        Self {
69            event,
70            id: InputEventId::new(),
71        }
72    }
73}
74
75/// An editing action that should be performed on a `WebView`.
76#[derive(Clone, Debug, Deserialize, Serialize)]
77pub enum EditingActionEvent {
78    Copy,
79    Cut,
80    Paste,
81}
82
83impl InputEvent {
84    pub fn point(&self) -> Option<WebViewPoint> {
85        match self {
86            InputEvent::EditingAction(..) => None,
87            #[cfg(feature = "gamepad")]
88            InputEvent::Gamepad(..) => None,
89            InputEvent::Ime(..) => None,
90            InputEvent::Keyboard(..) => None,
91            InputEvent::MouseButton(event) => Some(event.point),
92            InputEvent::MouseMove(event) => Some(event.point),
93            InputEvent::MouseLeftViewport(_) => None,
94            InputEvent::Touch(event) => Some(event.point),
95            InputEvent::Wheel(event) => Some(event.point),
96        }
97    }
98}
99
100#[derive(Clone, Debug, Default, Deserialize, Serialize)]
101pub struct KeyboardEvent {
102    pub event: ::keyboard_types::KeyboardEvent,
103}
104
105impl KeyboardEvent {
106    pub fn new(keyboard_event: ::keyboard_types::KeyboardEvent) -> Self {
107        Self {
108            event: keyboard_event,
109        }
110    }
111
112    pub fn new_without_event(
113        state: KeyState,
114        key: Key,
115        code: Code,
116        location: Location,
117        modifiers: Modifiers,
118        repeat: bool,
119        is_composing: bool,
120    ) -> Self {
121        Self::new(::keyboard_types::KeyboardEvent {
122            state,
123            key,
124            code,
125            location,
126            modifiers,
127            repeat,
128            is_composing,
129        })
130    }
131
132    pub fn from_state_and_key(state: KeyState, key: Key) -> Self {
133        Self::new(::keyboard_types::KeyboardEvent {
134            state,
135            key,
136            ..::keyboard_types::KeyboardEvent::default()
137        })
138    }
139}
140
141#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
142pub struct MouseButtonEvent {
143    pub action: MouseButtonAction,
144    pub button: MouseButton,
145    pub point: WebViewPoint,
146}
147
148impl MouseButtonEvent {
149    pub fn new(action: MouseButtonAction, button: MouseButton, point: WebViewPoint) -> Self {
150        Self {
151            action,
152            button,
153            point,
154        }
155    }
156}
157
158#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
159pub enum MouseButton {
160    Left,
161    Middle,
162    Right,
163    Back,
164    Forward,
165    Other(u16),
166}
167
168impl<T: Into<u64>> From<T> for MouseButton {
169    fn from(value: T) -> Self {
170        let value = value.into();
171        match value {
172            0 => MouseButton::Left,
173            1 => MouseButton::Middle,
174            2 => MouseButton::Right,
175            3 => MouseButton::Back,
176            4 => MouseButton::Forward,
177            _ => MouseButton::Other(value as u16),
178        }
179    }
180}
181
182impl From<MouseButton> for i16 {
183    fn from(value: MouseButton) -> Self {
184        match value {
185            MouseButton::Left => 0,
186            MouseButton::Middle => 1,
187            MouseButton::Right => 2,
188            MouseButton::Back => 3,
189            MouseButton::Forward => 4,
190            MouseButton::Other(value) => value as i16,
191        }
192    }
193}
194
195/// The types of mouse events
196#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
197pub enum MouseButtonAction {
198    /// Mouse button down
199    Down,
200    /// Mouse button up
201    Up,
202}
203
204#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
205pub struct MouseMoveEvent {
206    pub point: WebViewPoint,
207    pub is_compatibility_event_for_touch: bool,
208}
209
210impl MouseMoveEvent {
211    pub fn new(point: WebViewPoint) -> Self {
212        Self {
213            point,
214            is_compatibility_event_for_touch: false,
215        }
216    }
217
218    pub fn new_compatibility_for_touch(point: WebViewPoint) -> Self {
219        Self {
220            point,
221            is_compatibility_event_for_touch: true,
222        }
223    }
224}
225
226#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)]
227pub struct MouseLeftViewportEvent {
228    pub focus_moving_to_another_iframe: bool,
229}
230
231/// The type of input represented by a multi-touch event.
232#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
233pub enum TouchEventType {
234    /// A new touch point came in contact with the screen.
235    Down,
236    /// An existing touch point changed location.
237    Move,
238    /// A touch point was removed from the screen.
239    Up,
240    /// The system stopped tracking a touch point.
241    Cancel,
242}
243
244/// An opaque identifier for a touch point.
245///
246/// <http://w3c.github.io/touch-events/#widl-Touch-identifier>
247#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
248pub struct TouchId(pub i32);
249
250#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
251pub struct TouchEvent {
252    pub event_type: TouchEventType,
253    pub touch_id: TouchId,
254    pub point: WebViewPoint,
255    /// cancelable default value is true, once the first move has been processed by script disable it.
256    cancelable: bool,
257}
258
259impl TouchEvent {
260    pub fn new(event_type: TouchEventType, touch_id: TouchId, point: WebViewPoint) -> Self {
261        TouchEvent {
262            event_type,
263            touch_id,
264            point,
265            cancelable: true,
266        }
267    }
268
269    #[doc(hidden)]
270    pub fn disable_cancelable(&mut self) {
271        self.cancelable = false;
272    }
273
274    #[doc(hidden)]
275    pub fn is_cancelable(&self) -> bool {
276        self.cancelable
277    }
278}
279
280/// Mode to measure WheelDelta floats in
281#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
282pub enum WheelMode {
283    /// Delta values are specified in pixels
284    DeltaPixel = 0x00,
285    /// Delta values are specified in lines
286    DeltaLine = 0x01,
287    /// Delta values are specified in pages
288    DeltaPage = 0x02,
289}
290
291/// The Wheel event deltas in every direction
292#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
293pub struct WheelDelta {
294    /// Delta in the left/right direction. A positive value means that the view scrolls left,
295    /// revealing more content to the left of the current viewport.
296    pub x: f64,
297    /// Delta in the up/down direction. A positive value means that the view scrolls up, revealing
298    /// more content above the current viewport.
299    pub y: f64,
300    /// Delta in the direction going into/out of the screen
301    pub z: f64,
302    /// Mode to measure the floats in
303    pub mode: WheelMode,
304}
305
306#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
307pub struct WheelEvent {
308    pub delta: WheelDelta,
309    pub point: WebViewPoint,
310}
311
312impl WheelEvent {
313    pub fn new(delta: WheelDelta, point: WebViewPoint) -> Self {
314        WheelEvent { delta, point }
315    }
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}