1 //! The `Event` enum and assorted supporting types.
2 //!
3 //! These are sent to the closure given to [`EventLoop::run(...)`][event_loop_run], where they get
4 //! processed and used to modify the program state. For more details, see the root-level documentation.
5 //!
6 //! Some of these events represent different "parts" of a traditional event-handling loop. You could
7 //! approximate the basic ordering loop of [`EventLoop::run(...)`][event_loop_run] like this:
8 //!
9 //! ```rust,ignore
10 //! let mut control_flow = ControlFlow::Poll;
11 //! let mut start_cause = StartCause::Init;
12 //!
13 //! while control_flow != ControlFlow::Exit {
14 //!     event_handler(NewEvents(start_cause), ..., &mut control_flow);
15 //!
16 //!     for e in (window events, user events, device events) {
17 //!         event_handler(e, ..., &mut control_flow);
18 //!     }
19 //!     event_handler(MainEventsCleared, ..., &mut control_flow);
20 //!
21 //!     for w in (redraw windows) {
22 //!         event_handler(RedrawRequested(w), ..., &mut control_flow);
23 //!     }
24 //!     event_handler(RedrawEventsCleared, ..., &mut control_flow);
25 //!
26 //!     start_cause = wait_if_necessary(control_flow);
27 //! }
28 //!
29 //! event_handler(LoopDestroyed, ..., &mut control_flow);
30 //! ```
31 //!
32 //! This leaves out timing details like `ControlFlow::WaitUntil` but hopefully
33 //! describes what happens in what order.
34 //!
35 //! [event_loop_run]: crate::event_loop::EventLoop::run
36 use instant::Instant;
37 use std::path::PathBuf;
38 
39 use crate::{
40     dpi::{PhysicalPosition, PhysicalSize},
41     platform_impl,
42     window::{Theme, WindowId},
43 };
44 
45 /// Describes a generic event.
46 ///
47 /// See the module-level docs for more information on the event loop manages each event.
48 #[derive(Debug, PartialEq)]
49 pub enum Event<'a, T: 'static> {
50     /// Emitted when new events arrive from the OS to be processed.
51     ///
52     /// This event type is useful as a place to put code that should be done before you start
53     /// processing events, such as updating frame timing information for benchmarking or checking
54     /// the [`StartCause`][crate::event::StartCause] to see if a timer set by
55     /// [`ControlFlow::WaitUntil`](crate::event_loop::ControlFlow::WaitUntil) has elapsed.
56     NewEvents(StartCause),
57 
58     /// Emitted when the OS sends an event to a winit window.
59     WindowEvent {
60         window_id: WindowId,
61         event: WindowEvent<'a>,
62     },
63 
64     /// Emitted when the OS sends an event to a device.
65     DeviceEvent {
66         device_id: DeviceId,
67         event: DeviceEvent,
68     },
69 
70     /// Emitted when an event is sent from [`EventLoopProxy::send_event`](crate::event_loop::EventLoopProxy::send_event)
71     UserEvent(T),
72 
73     /// Emitted when the application has been suspended.
74     Suspended,
75 
76     /// Emitted when the application has been resumed.
77     Resumed,
78 
79     /// Emitted when all of the event loop's input events have been processed and redraw processing
80     /// is about to begin.
81     ///
82     /// This event is useful as a place to put your code that should be run after all
83     /// state-changing events have been handled and you want to do stuff (updating state, performing
84     /// calculations, etc) that happens as the "main body" of your event loop. If your program only draws
85     /// graphics when something changes, it's usually better to do it in response to
86     /// [`Event::RedrawRequested`](crate::event::Event::RedrawRequested), which gets emitted
87     /// immediately after this event. Programs that draw graphics continuously, like most games,
88     /// can render here unconditionally for simplicity.
89     MainEventsCleared,
90 
91     /// Emitted after `MainEventsCleared` when a window should be redrawn.
92     ///
93     /// This gets triggered in two scenarios:
94     /// - The OS has performed an operation that's invalidated the window's contents (such as
95     ///   resizing the window).
96     /// - The application has explicitly requested a redraw via
97     ///   [`Window::request_redraw`](crate::window::Window::request_redraw).
98     ///
99     /// During each iteration of the event loop, Winit will aggregate duplicate redraw requests
100     /// into a single event, to help avoid duplicating rendering work.
101     ///
102     /// Mainly of interest to applications with mostly-static graphics that avoid redrawing unless
103     /// something changes, like most non-game GUIs.
104     RedrawRequested(WindowId),
105 
106     /// Emitted after all `RedrawRequested` events have been processed and control flow is about to
107     /// be taken away from the program. If there are no `RedrawRequested` events, it is emitted
108     /// immediately after `MainEventsCleared`.
109     ///
110     /// This event is useful for doing any cleanup or bookkeeping work after all the rendering
111     /// tasks have been completed.
112     RedrawEventsCleared,
113 
114     /// Emitted when the event loop is being shut down.
115     ///
116     /// This is irreversable - if this event is emitted, it is guaranteed to be the last event that
117     /// gets emitted. You generally want to treat this as an "do on quit" event.
118     LoopDestroyed,
119 }
120 
121 impl<T: Clone> Clone for Event<'static, T> {
clone(&self) -> Self122     fn clone(&self) -> Self {
123         use self::Event::*;
124         match self {
125             WindowEvent { window_id, event } => WindowEvent {
126                 window_id: *window_id,
127                 event: event.clone(),
128             },
129             UserEvent(event) => UserEvent(event.clone()),
130             DeviceEvent { device_id, event } => DeviceEvent {
131                 device_id: *device_id,
132                 event: event.clone(),
133             },
134             NewEvents(cause) => NewEvents(cause.clone()),
135             MainEventsCleared => MainEventsCleared,
136             RedrawRequested(wid) => RedrawRequested(*wid),
137             RedrawEventsCleared => RedrawEventsCleared,
138             LoopDestroyed => LoopDestroyed,
139             Suspended => Suspended,
140             Resumed => Resumed,
141         }
142     }
143 }
144 
145 impl<'a, T> Event<'a, T> {
map_nonuser_event<U>(self) -> Result<Event<'a, U>, Event<'a, T>>146     pub fn map_nonuser_event<U>(self) -> Result<Event<'a, U>, Event<'a, T>> {
147         use self::Event::*;
148         match self {
149             UserEvent(_) => Err(self),
150             WindowEvent { window_id, event } => Ok(WindowEvent { window_id, event }),
151             DeviceEvent { device_id, event } => Ok(DeviceEvent { device_id, event }),
152             NewEvents(cause) => Ok(NewEvents(cause)),
153             MainEventsCleared => Ok(MainEventsCleared),
154             RedrawRequested(wid) => Ok(RedrawRequested(wid)),
155             RedrawEventsCleared => Ok(RedrawEventsCleared),
156             LoopDestroyed => Ok(LoopDestroyed),
157             Suspended => Ok(Suspended),
158             Resumed => Ok(Resumed),
159         }
160     }
161 
162     /// If the event doesn't contain a reference, turn it into an event with a `'static` lifetime.
163     /// Otherwise, return `None`.
to_static(self) -> Option<Event<'static, T>>164     pub fn to_static(self) -> Option<Event<'static, T>> {
165         use self::Event::*;
166         match self {
167             WindowEvent { window_id, event } => event
168                 .to_static()
169                 .map(|event| WindowEvent { window_id, event }),
170             UserEvent(event) => Some(UserEvent(event)),
171             DeviceEvent { device_id, event } => Some(DeviceEvent { device_id, event }),
172             NewEvents(cause) => Some(NewEvents(cause)),
173             MainEventsCleared => Some(MainEventsCleared),
174             RedrawRequested(wid) => Some(RedrawRequested(wid)),
175             RedrawEventsCleared => Some(RedrawEventsCleared),
176             LoopDestroyed => Some(LoopDestroyed),
177             Suspended => Some(Suspended),
178             Resumed => Some(Resumed),
179         }
180     }
181 }
182 
183 /// Describes the reason the event loop is resuming.
184 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
185 pub enum StartCause {
186     /// Sent if the time specified by `ControlFlow::WaitUntil` has been reached. Contains the
187     /// moment the timeout was requested and the requested resume time. The actual resume time is
188     /// guaranteed to be equal to or after the requested resume time.
189     ResumeTimeReached {
190         start: Instant,
191         requested_resume: Instant,
192     },
193 
194     /// Sent if the OS has new events to send to the window, after a wait was requested. Contains
195     /// the moment the wait was requested and the resume time, if requested.
196     WaitCancelled {
197         start: Instant,
198         requested_resume: Option<Instant>,
199     },
200 
201     /// Sent if the event loop is being resumed after the loop's control flow was set to
202     /// `ControlFlow::Poll`.
203     Poll,
204 
205     /// Sent once, immediately after `run` is called. Indicates that the loop was just initialized.
206     Init,
207 }
208 
209 /// Describes an event from a `Window`.
210 #[derive(Debug, PartialEq)]
211 pub enum WindowEvent<'a> {
212     /// The size of the window has changed. Contains the client area's new dimensions.
213     Resized(PhysicalSize<u32>),
214 
215     /// The position of the window has changed. Contains the window's new position.
216     Moved(PhysicalPosition<i32>),
217 
218     /// The window has been requested to close.
219     CloseRequested,
220 
221     /// The window has been destroyed.
222     Destroyed,
223 
224     /// A file has been dropped into the window.
225     ///
226     /// When the user drops multiple files at once, this event will be emitted for each file
227     /// separately.
228     DroppedFile(PathBuf),
229 
230     /// A file is being hovered over the window.
231     ///
232     /// When the user hovers multiple files at once, this event will be emitted for each file
233     /// separately.
234     HoveredFile(PathBuf),
235 
236     /// A file was hovered, but has exited the window.
237     ///
238     /// There will be a single `HoveredFileCancelled` event triggered even if multiple files were
239     /// hovered.
240     HoveredFileCancelled,
241 
242     /// The window received a unicode character.
243     ReceivedCharacter(char),
244 
245     /// The window gained or lost focus.
246     ///
247     /// The parameter is true if the window has gained focus, and false if it has lost focus.
248     Focused(bool),
249 
250     /// An event from the keyboard has been received.
251     KeyboardInput {
252         device_id: DeviceId,
253         input: KeyboardInput,
254         /// If `true`, the event was generated synthetically by winit
255         /// in one of the following circumstances:
256         ///
257         /// * Synthetic key press events are generated for all keys pressed
258         ///   when a window gains focus. Likewise, synthetic key release events
259         ///   are generated for all keys pressed when a window goes out of focus.
260         ///   ***Currently, this is only functional on X11 and Windows***
261         ///
262         /// Otherwise, this value is always `false`.
263         is_synthetic: bool,
264     },
265 
266     /// The keyboard modifiers have changed.
267     ///
268     /// Platform-specific behavior:
269     /// - **Web**: This API is currently unimplemented on the web. This isn't by design - it's an
270     ///   issue, and it should get fixed - but it's the current state of the API.
271     ModifiersChanged(ModifiersState),
272 
273     /// The cursor has moved on the window.
274     CursorMoved {
275         device_id: DeviceId,
276 
277         /// (x,y) coords in pixels relative to the top-left corner of the window. Because the range of this data is
278         /// limited by the display area and it may have been transformed by the OS to implement effects such as cursor
279         /// acceleration, it should not be used to implement non-cursor-like interactions such as 3D camera control.
280         position: PhysicalPosition<f64>,
281         #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
282         modifiers: ModifiersState,
283     },
284 
285     /// The cursor has entered the window.
286     CursorEntered { device_id: DeviceId },
287 
288     /// The cursor has left the window.
289     CursorLeft { device_id: DeviceId },
290 
291     /// A mouse wheel movement or touchpad scroll occurred.
292     MouseWheel {
293         device_id: DeviceId,
294         delta: MouseScrollDelta,
295         phase: TouchPhase,
296         #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
297         modifiers: ModifiersState,
298     },
299 
300     /// An mouse button press has been received.
301     MouseInput {
302         device_id: DeviceId,
303         state: ElementState,
304         button: MouseButton,
305         #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
306         modifiers: ModifiersState,
307     },
308 
309     /// Touchpad pressure event.
310     ///
311     /// At the moment, only supported on Apple forcetouch-capable macbooks.
312     /// The parameters are: pressure level (value between 0 and 1 representing how hard the touchpad
313     /// is being pressed) and stage (integer representing the click level).
314     TouchpadPressure {
315         device_id: DeviceId,
316         pressure: f32,
317         stage: i64,
318     },
319 
320     /// Motion on some analog axis. May report data redundant to other, more specific events.
321     AxisMotion {
322         device_id: DeviceId,
323         axis: AxisId,
324         value: f64,
325     },
326 
327     /// Touch event has been received
328     Touch(Touch),
329 
330     /// The window's scale factor has changed.
331     ///
332     /// The following user actions can cause DPI changes:
333     ///
334     /// * Changing the display's resolution.
335     /// * Changing the display's scale factor (e.g. in Control Panel on Windows).
336     /// * Moving the window to a display with a different scale factor.
337     ///
338     /// After this event callback has been processed, the window will be resized to whatever value
339     /// is pointed to by the `new_inner_size` reference. By default, this will contain the size suggested
340     /// by the OS, but it can be changed to any value.
341     ///
342     /// For more information about DPI in general, see the [`dpi`](crate::dpi) module.
343     ScaleFactorChanged {
344         scale_factor: f64,
345         new_inner_size: &'a mut PhysicalSize<u32>,
346     },
347 
348     /// The system window theme has changed.
349     ///
350     /// Applications might wish to react to this to change the theme of the content of the window
351     /// when the system changes the window theme.
352     ///
353     /// At the moment this is only supported on Windows.
354     ThemeChanged(Theme),
355 }
356 
357 impl Clone for WindowEvent<'static> {
clone(&self) -> Self358     fn clone(&self) -> Self {
359         use self::WindowEvent::*;
360         return match self {
361             Resized(size) => Resized(size.clone()),
362             Moved(pos) => Moved(pos.clone()),
363             CloseRequested => CloseRequested,
364             Destroyed => Destroyed,
365             DroppedFile(file) => DroppedFile(file.clone()),
366             HoveredFile(file) => HoveredFile(file.clone()),
367             HoveredFileCancelled => HoveredFileCancelled,
368             ReceivedCharacter(c) => ReceivedCharacter(*c),
369             Focused(f) => Focused(*f),
370             KeyboardInput {
371                 device_id,
372                 input,
373                 is_synthetic,
374             } => KeyboardInput {
375                 device_id: *device_id,
376                 input: *input,
377                 is_synthetic: *is_synthetic,
378             },
379 
380             ModifiersChanged(modifiers) => ModifiersChanged(modifiers.clone()),
381             #[allow(deprecated)]
382             CursorMoved {
383                 device_id,
384                 position,
385                 modifiers,
386             } => CursorMoved {
387                 device_id: *device_id,
388                 position: *position,
389                 modifiers: *modifiers,
390             },
391             CursorEntered { device_id } => CursorEntered {
392                 device_id: *device_id,
393             },
394             CursorLeft { device_id } => CursorLeft {
395                 device_id: *device_id,
396             },
397             #[allow(deprecated)]
398             MouseWheel {
399                 device_id,
400                 delta,
401                 phase,
402                 modifiers,
403             } => MouseWheel {
404                 device_id: *device_id,
405                 delta: *delta,
406                 phase: *phase,
407                 modifiers: *modifiers,
408             },
409             #[allow(deprecated)]
410             MouseInput {
411                 device_id,
412                 state,
413                 button,
414                 modifiers,
415             } => MouseInput {
416                 device_id: *device_id,
417                 state: *state,
418                 button: *button,
419                 modifiers: *modifiers,
420             },
421             TouchpadPressure {
422                 device_id,
423                 pressure,
424                 stage,
425             } => TouchpadPressure {
426                 device_id: *device_id,
427                 pressure: *pressure,
428                 stage: *stage,
429             },
430             AxisMotion {
431                 device_id,
432                 axis,
433                 value,
434             } => AxisMotion {
435                 device_id: *device_id,
436                 axis: *axis,
437                 value: *value,
438             },
439             Touch(touch) => Touch(*touch),
440             ThemeChanged(theme) => ThemeChanged(theme.clone()),
441             ScaleFactorChanged { .. } => {
442                 unreachable!("Static event can't be about scale factor changing")
443             }
444         };
445     }
446 }
447 
448 impl<'a> WindowEvent<'a> {
to_static(self) -> Option<WindowEvent<'static>>449     pub fn to_static(self) -> Option<WindowEvent<'static>> {
450         use self::WindowEvent::*;
451         match self {
452             Resized(size) => Some(Resized(size)),
453             Moved(position) => Some(Moved(position)),
454             CloseRequested => Some(CloseRequested),
455             Destroyed => Some(Destroyed),
456             DroppedFile(file) => Some(DroppedFile(file)),
457             HoveredFile(file) => Some(HoveredFile(file)),
458             HoveredFileCancelled => Some(HoveredFileCancelled),
459             ReceivedCharacter(c) => Some(ReceivedCharacter(c)),
460             Focused(focused) => Some(Focused(focused)),
461             KeyboardInput {
462                 device_id,
463                 input,
464                 is_synthetic,
465             } => Some(KeyboardInput {
466                 device_id,
467                 input,
468                 is_synthetic,
469             }),
470             ModifiersChanged(modifiers) => Some(ModifiersChanged(modifiers)),
471             #[allow(deprecated)]
472             CursorMoved {
473                 device_id,
474                 position,
475                 modifiers,
476             } => Some(CursorMoved {
477                 device_id,
478                 position,
479                 modifiers,
480             }),
481             CursorEntered { device_id } => Some(CursorEntered { device_id }),
482             CursorLeft { device_id } => Some(CursorLeft { device_id }),
483             #[allow(deprecated)]
484             MouseWheel {
485                 device_id,
486                 delta,
487                 phase,
488                 modifiers,
489             } => Some(MouseWheel {
490                 device_id,
491                 delta,
492                 phase,
493                 modifiers,
494             }),
495             #[allow(deprecated)]
496             MouseInput {
497                 device_id,
498                 state,
499                 button,
500                 modifiers,
501             } => Some(MouseInput {
502                 device_id,
503                 state,
504                 button,
505                 modifiers,
506             }),
507             TouchpadPressure {
508                 device_id,
509                 pressure,
510                 stage,
511             } => Some(TouchpadPressure {
512                 device_id,
513                 pressure,
514                 stage,
515             }),
516             AxisMotion {
517                 device_id,
518                 axis,
519                 value,
520             } => Some(AxisMotion {
521                 device_id,
522                 axis,
523                 value,
524             }),
525             Touch(touch) => Some(Touch(touch)),
526             ThemeChanged(theme) => Some(ThemeChanged(theme)),
527             ScaleFactorChanged { .. } => None,
528         }
529     }
530 }
531 
532 /// Identifier of an input device.
533 ///
534 /// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which
535 /// identifies its origin. Note that devices may be virtual (representing an on-screen cursor and keyboard focus) or
536 /// physical. Virtual devices typically aggregate inputs from multiple physical devices.
537 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
538 pub struct DeviceId(pub(crate) platform_impl::DeviceId);
539 
540 impl DeviceId {
541     /// Returns a dummy `DeviceId`, useful for unit testing. The only guarantee made about the return
542     /// value of this function is that it will always be equal to itself and to future values returned
543     /// by this function.  No other guarantees are made. This may be equal to a real `DeviceId`.
544     ///
545     /// **Passing this into a winit function will result in undefined behavior.**
dummy() -> Self546     pub unsafe fn dummy() -> Self {
547         DeviceId(platform_impl::DeviceId::dummy())
548     }
549 }
550 
551 /// Represents raw hardware events that are not associated with any particular window.
552 ///
553 /// Useful for interactions that diverge significantly from a conventional 2D GUI, such as 3D camera or first-person
554 /// game controls. Many physical actions, such as mouse movement, can produce both device and window events. Because
555 /// window events typically arise from virtual devices (corresponding to GUI cursors and keyboard focus) the device IDs
556 /// may not match.
557 ///
558 /// Note that these events are delivered regardless of input focus.
559 #[derive(Clone, Debug, PartialEq)]
560 pub enum DeviceEvent {
561     Added,
562     Removed,
563 
564     /// Change in physical position of a pointing device.
565     ///
566     /// This represents raw, unfiltered physical motion. Not to be confused with `WindowEvent::CursorMoved`.
567     MouseMotion {
568         /// (x, y) change in position in unspecified units.
569         ///
570         /// Different devices may use different units.
571         delta: (f64, f64),
572     },
573 
574     /// Physical scroll event
575     MouseWheel {
576         delta: MouseScrollDelta,
577     },
578 
579     /// Motion on some analog axis.  This event will be reported for all arbitrary input devices
580     /// that winit supports on this platform, including mouse devices.  If the device is a mouse
581     /// device then this will be reported alongside the MouseMotion event.
582     Motion {
583         axis: AxisId,
584         value: f64,
585     },
586 
587     Button {
588         button: ButtonId,
589         state: ElementState,
590     },
591 
592     Key(KeyboardInput),
593 
594     Text {
595         codepoint: char,
596     },
597 }
598 
599 /// Describes a keyboard input event.
600 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
601 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
602 pub struct KeyboardInput {
603     /// Identifies the physical key pressed
604     ///
605     /// This should not change if the user adjusts the host's keyboard map. Use when the physical location of the
606     /// key is more important than the key's host GUI semantics, such as for movement controls in a first-person
607     /// game.
608     pub scancode: ScanCode,
609 
610     pub state: ElementState,
611 
612     /// Identifies the semantic meaning of the key
613     ///
614     /// Use when the semantics of the key are more important than the physical location of the key, such as when
615     /// implementing appropriate behavior for "page up."
616     pub virtual_keycode: Option<VirtualKeyCode>,
617 
618     /// Modifier keys active at the time of this input.
619     ///
620     /// This is tracked internally to avoid tracking errors arising from modifier key state changes when events from
621     /// this device are not being delivered to the application, e.g. due to keyboard focus being elsewhere.
622     #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
623     pub modifiers: ModifiersState,
624 }
625 
626 /// Describes touch-screen input state.
627 #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
628 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
629 pub enum TouchPhase {
630     Started,
631     Moved,
632     Ended,
633     Cancelled,
634 }
635 
636 /// Represents a touch event
637 ///
638 /// Every time the user touches the screen, a new `Start` event with an unique
639 /// identifier for the finger is generated. When the finger is lifted, an `End`
640 /// event is generated with the same finger id.
641 ///
642 /// After a `Start` event has been emitted, there may be zero or more `Move`
643 /// events when the finger is moved or the touch pressure changes.
644 ///
645 /// The finger id may be reused by the system after an `End` event. The user
646 /// should assume that a new `Start` event received with the same id has nothing
647 /// to do with the old finger and is a new finger.
648 ///
649 /// A `Cancelled` event is emitted when the system has canceled tracking this
650 /// touch, such as when the window loses focus, or on iOS if the user moves the
651 /// device against their face.
652 #[derive(Debug, Clone, Copy, PartialEq)]
653 pub struct Touch {
654     pub device_id: DeviceId,
655     pub phase: TouchPhase,
656     pub location: PhysicalPosition<f64>,
657     /// Describes how hard the screen was pressed. May be `None` if the platform
658     /// does not support pressure sensitivity.
659     ///
660     /// ## Platform-specific
661     ///
662     /// - Only available on **iOS** 9.0+ and **Windows** 8+.
663     pub force: Option<Force>,
664     /// Unique identifier of a finger.
665     pub id: u64,
666 }
667 
668 /// Describes the force of a touch event
669 #[derive(Debug, Clone, Copy, PartialEq)]
670 pub enum Force {
671     /// On iOS, the force is calibrated so that the same number corresponds to
672     /// roughly the same amount of pressure on the screen regardless of the
673     /// device.
674     Calibrated {
675         /// The force of the touch, where a value of 1.0 represents the force of
676         /// an average touch (predetermined by the system, not user-specific).
677         ///
678         /// The force reported by Apple Pencil is measured along the axis of the
679         /// pencil. If you want a force perpendicular to the device, you need to
680         /// calculate this value using the `altitude_angle` value.
681         force: f64,
682         /// The maximum possible force for a touch.
683         ///
684         /// The value of this field is sufficiently high to provide a wide
685         /// dynamic range for values of the `force` field.
686         max_possible_force: f64,
687         /// The altitude (in radians) of the stylus.
688         ///
689         /// A value of 0 radians indicates that the stylus is parallel to the
690         /// surface. The value of this property is Pi/2 when the stylus is
691         /// perpendicular to the surface.
692         altitude_angle: Option<f64>,
693     },
694     /// If the platform reports the force as normalized, we have no way of
695     /// knowing how much pressure 1.0 corresponds to – we know it's the maximum
696     /// amount of force, but as to how much force, you might either have to
697     /// press really really hard, or not hard at all, depending on the device.
698     Normalized(f64),
699 }
700 
701 impl Force {
702     /// Returns the force normalized to the range between 0.0 and 1.0 inclusive.
703     /// Instead of normalizing the force, you should prefer to handle
704     /// `Force::Calibrated` so that the amount of force the user has to apply is
705     /// consistent across devices.
normalized(&self) -> f64706     pub fn normalized(&self) -> f64 {
707         match self {
708             Force::Calibrated {
709                 force,
710                 max_possible_force,
711                 altitude_angle,
712             } => {
713                 let force = match altitude_angle {
714                     Some(altitude_angle) => force / altitude_angle.sin(),
715                     None => *force,
716                 };
717                 force / max_possible_force
718             }
719             Force::Normalized(force) => *force,
720         }
721     }
722 }
723 
724 /// Hardware-dependent keyboard scan code.
725 pub type ScanCode = u32;
726 
727 /// Identifier for a specific analog axis on some device.
728 pub type AxisId = u32;
729 
730 /// Identifier for a specific button on some device.
731 pub type ButtonId = u32;
732 
733 /// Describes the input state of a key.
734 #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
735 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
736 pub enum ElementState {
737     Pressed,
738     Released,
739 }
740 
741 /// Describes a button of a mouse controller.
742 #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
743 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
744 pub enum MouseButton {
745     Left,
746     Right,
747     Middle,
748     Other(u16),
749 }
750 
751 /// Describes a difference in the mouse scroll wheel state.
752 #[derive(Debug, Clone, Copy, PartialEq)]
753 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
754 pub enum MouseScrollDelta {
755     /// Amount in lines or rows to scroll in the horizontal
756     /// and vertical directions.
757     ///
758     /// Positive values indicate movement forward
759     /// (away from the user) or rightwards.
760     LineDelta(f32, f32),
761     /// Amount in pixels to scroll in the horizontal and
762     /// vertical direction.
763     ///
764     /// Scroll events are expressed as a PixelDelta if
765     /// supported by the device (eg. a touchpad) and
766     /// platform.
767     PixelDelta(PhysicalPosition<f64>),
768 }
769 
770 /// Symbolic name for a keyboard key.
771 #[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
772 #[repr(u32)]
773 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
774 pub enum VirtualKeyCode {
775     /// The '1' key over the letters.
776     Key1,
777     /// The '2' key over the letters.
778     Key2,
779     /// The '3' key over the letters.
780     Key3,
781     /// The '4' key over the letters.
782     Key4,
783     /// The '5' key over the letters.
784     Key5,
785     /// The '6' key over the letters.
786     Key6,
787     /// The '7' key over the letters.
788     Key7,
789     /// The '8' key over the letters.
790     Key8,
791     /// The '9' key over the letters.
792     Key9,
793     /// The '0' key over the 'O' and 'P' keys.
794     Key0,
795 
796     A,
797     B,
798     C,
799     D,
800     E,
801     F,
802     G,
803     H,
804     I,
805     J,
806     K,
807     L,
808     M,
809     N,
810     O,
811     P,
812     Q,
813     R,
814     S,
815     T,
816     U,
817     V,
818     W,
819     X,
820     Y,
821     Z,
822 
823     /// The Escape key, next to F1.
824     Escape,
825 
826     F1,
827     F2,
828     F3,
829     F4,
830     F5,
831     F6,
832     F7,
833     F8,
834     F9,
835     F10,
836     F11,
837     F12,
838     F13,
839     F14,
840     F15,
841     F16,
842     F17,
843     F18,
844     F19,
845     F20,
846     F21,
847     F22,
848     F23,
849     F24,
850 
851     /// Print Screen/SysRq.
852     Snapshot,
853     /// Scroll Lock.
854     Scroll,
855     /// Pause/Break key, next to Scroll lock.
856     Pause,
857 
858     /// `Insert`, next to Backspace.
859     Insert,
860     Home,
861     Delete,
862     End,
863     PageDown,
864     PageUp,
865 
866     Left,
867     Up,
868     Right,
869     Down,
870 
871     /// The Backspace key, right over Enter.
872     // TODO: rename
873     Back,
874     /// The Enter key.
875     Return,
876     /// The space bar.
877     Space,
878 
879     /// The "Compose" key on Linux.
880     Compose,
881 
882     Caret,
883 
884     Numlock,
885     Numpad0,
886     Numpad1,
887     Numpad2,
888     Numpad3,
889     Numpad4,
890     Numpad5,
891     Numpad6,
892     Numpad7,
893     Numpad8,
894     Numpad9,
895     NumpadAdd,
896     NumpadDivide,
897     NumpadDecimal,
898     NumpadComma,
899     NumpadEnter,
900     NumpadEquals,
901     NumpadMultiply,
902     NumpadSubtract,
903 
904     AbntC1,
905     AbntC2,
906     Apostrophe,
907     Apps,
908     Asterisk,
909     At,
910     Ax,
911     Backslash,
912     Calculator,
913     Capital,
914     Colon,
915     Comma,
916     Convert,
917     Equals,
918     Grave,
919     Kana,
920     Kanji,
921     LAlt,
922     LBracket,
923     LControl,
924     LShift,
925     LWin,
926     Mail,
927     MediaSelect,
928     MediaStop,
929     Minus,
930     Mute,
931     MyComputer,
932     // also called "Next"
933     NavigateForward,
934     // also called "Prior"
935     NavigateBackward,
936     NextTrack,
937     NoConvert,
938     OEM102,
939     Period,
940     PlayPause,
941     Plus,
942     Power,
943     PrevTrack,
944     RAlt,
945     RBracket,
946     RControl,
947     RShift,
948     RWin,
949     Semicolon,
950     Slash,
951     Sleep,
952     Stop,
953     Sysrq,
954     Tab,
955     Underline,
956     Unlabeled,
957     VolumeDown,
958     VolumeUp,
959     Wake,
960     WebBack,
961     WebFavorites,
962     WebForward,
963     WebHome,
964     WebRefresh,
965     WebSearch,
966     WebStop,
967     Yen,
968     Copy,
969     Paste,
970     Cut,
971 }
972 
973 impl ModifiersState {
974     /// Returns `true` if the shift key is pressed.
shift(&self) -> bool975     pub fn shift(&self) -> bool {
976         self.intersects(Self::SHIFT)
977     }
978     /// Returns `true` if the control key is pressed.
ctrl(&self) -> bool979     pub fn ctrl(&self) -> bool {
980         self.intersects(Self::CTRL)
981     }
982     /// Returns `true` if the alt key is pressed.
alt(&self) -> bool983     pub fn alt(&self) -> bool {
984         self.intersects(Self::ALT)
985     }
986     /// Returns `true` if the logo key is pressed.
logo(&self) -> bool987     pub fn logo(&self) -> bool {
988         self.intersects(Self::LOGO)
989     }
990 }
991 
992 bitflags! {
993     /// Represents the current state of the keyboard modifiers
994     ///
995     /// Each flag represents a modifier and is set if this modifier is active.
996     #[derive(Default)]
997     pub struct ModifiersState: u32 {
998         // left and right modifiers are currently commented out, but we should be able to support
999         // them in a future release
1000         /// The "shift" key.
1001         const SHIFT = 0b100 << 0;
1002         // const LSHIFT = 0b010 << 0;
1003         // const RSHIFT = 0b001 << 0;
1004         /// The "control" key.
1005         const CTRL = 0b100 << 3;
1006         // const LCTRL = 0b010 << 3;
1007         // const RCTRL = 0b001 << 3;
1008         /// The "alt" key.
1009         const ALT = 0b100 << 6;
1010         // const LALT = 0b010 << 6;
1011         // const RALT = 0b001 << 6;
1012         /// This is the "windows" key on PC and "command" key on Mac.
1013         const LOGO = 0b100 << 9;
1014         // const LLOGO = 0b010 << 9;
1015         // const RLOGO = 0b001 << 9;
1016     }
1017 }
1018 
1019 #[cfg(feature = "serde")]
1020 mod modifiers_serde {
1021     use super::ModifiersState;
1022     use serde::{Deserialize, Deserializer, Serialize, Serializer};
1023 
1024     #[derive(Default, Serialize, Deserialize)]
1025     #[serde(default)]
1026     #[serde(rename = "ModifiersState")]
1027     pub struct ModifiersStateSerialize {
1028         pub shift: bool,
1029         pub ctrl: bool,
1030         pub alt: bool,
1031         pub logo: bool,
1032     }
1033 
1034     impl Serialize for ModifiersState {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,1035         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1036         where
1037             S: Serializer,
1038         {
1039             let s = ModifiersStateSerialize {
1040                 shift: self.shift(),
1041                 ctrl: self.ctrl(),
1042                 alt: self.alt(),
1043                 logo: self.logo(),
1044             };
1045             s.serialize(serializer)
1046         }
1047     }
1048 
1049     impl<'de> Deserialize<'de> for ModifiersState {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,1050         fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1051         where
1052             D: Deserializer<'de>,
1053         {
1054             let ModifiersStateSerialize {
1055                 shift,
1056                 ctrl,
1057                 alt,
1058                 logo,
1059             } = ModifiersStateSerialize::deserialize(deserializer)?;
1060             let mut m = ModifiersState::empty();
1061             m.set(ModifiersState::SHIFT, shift);
1062             m.set(ModifiersState::CTRL, ctrl);
1063             m.set(ModifiersState::ALT, alt);
1064             m.set(ModifiersState::LOGO, logo);
1065             Ok(m)
1066         }
1067     }
1068 }
1069