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