Skip to main content

window_events/
lib.rs

1#[cfg(feature = "serde")]
2#[macro_use]
3extern crate serde;
4
5pub extern crate events_loop;
6
7use std::path::PathBuf;
8
9pub mod dpi;
10
11use dpi::{LogicalPosition, LogicalSize};
12
13#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
14pub struct WindowId(u64);
15
16impl WindowId {
17    pub fn to_u64(&self) -> u64 {
18        self.0
19    }
20
21    pub unsafe fn new(id: u64) -> Self {
22        WindowId(id)
23    }
24}
25
26#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
27pub struct DeviceId(u64);
28
29impl DeviceId {
30    pub fn to_u64(&self) -> u64 {
31        self.0
32    }
33
34    pub unsafe fn new(id: u64) -> Self {
35        DeviceId(id)
36    }
37}
38
39/// Describes a generic event.
40#[derive(Clone, Debug, PartialEq)]
41pub enum Event {
42    WindowEvent {
43        window_id: WindowId,
44        event: WindowEvent,
45    },
46    DeviceEvent {
47        device_id: DeviceId,
48        event: DeviceEvent,
49    },
50    Awakened,
51
52    /// The application has been suspended or resumed.
53    ///
54    /// The parameter is true if app was suspended, and false if it has been resumed.
55    Suspended(bool),
56}
57
58/// Describes an event from a `Window`.
59#[derive(Clone, Debug, PartialEq)]
60pub enum WindowEvent {
61    /// The size of the window has changed. Contains the client area's new dimensions.
62    Resized(LogicalSize),
63
64    /// The position of the window has changed. Contains the window's new position.
65    Moved(LogicalPosition),
66
67    /// The window has been requested to close.
68    CloseRequested,
69
70    /// The window has been destroyed.
71    Destroyed,
72
73    /// A file has been dropped into the window.
74    /// 
75    /// When the user drops multiple files at once, this event will be emitted for each file
76    /// separately.
77    DroppedFile(PathBuf),
78
79    /// A file is being hovered over the window.
80    /// 
81    /// When the user hovers multiple files at once, this event will be emitted for each file
82    /// separately.
83    HoveredFile(PathBuf),
84
85    /// A file was hovered, but has exited the window.
86    /// 
87    /// There will be a single `HoveredFileCancelled` event triggered even if multiple files were
88    /// hovered.
89    HoveredFileCancelled,
90
91    /// The window received a unicode character.
92    ReceivedCharacter(char),
93
94    /// The window gained or lost focus.
95    ///
96    /// The parameter is true if the window has gained focus, and false if it has lost focus.
97    Focused(bool),
98
99    /// An event from the keyboard has been received.
100    KeyboardInput { device_id: DeviceId, input: KeyboardInput },
101
102    /// The cursor has moved on the window.
103    CursorMoved {
104        device_id: DeviceId,
105
106        /// (x,y) coords in pixels relative to the top-left corner of the window. Because the range of this data is
107        /// limited by the display area and it may have been transformed by the OS to implement effects such as cursor
108        /// acceleration, it should not be used to implement non-cursor-like interactions such as 3D camera control.
109        position: LogicalPosition,
110        modifiers: ModifiersState
111    },
112
113    /// The cursor has entered the window.
114    CursorEntered { device_id: DeviceId },
115
116    /// The cursor has left the window.
117    CursorLeft { device_id: DeviceId },
118
119    /// A mouse wheel movement or touchpad scroll occurred.
120    MouseWheel { device_id: DeviceId, delta: MouseScrollDelta, phase: TouchPhase, modifiers: ModifiersState },
121
122    /// An mouse button press has been received.
123    MouseInput { device_id: DeviceId, state: ElementState, button: MouseButton, modifiers: ModifiersState },
124
125
126    /// Touchpad pressure event.
127    ///
128    /// At the moment, only supported on Apple forcetouch-capable macbooks.
129    /// The parameters are: pressure level (value between 0 and 1 representing how hard the touchpad
130    /// is being pressed) and stage (integer representing the click level).
131    TouchpadPressure { device_id: DeviceId, pressure: f32, stage: i64 },
132
133    /// Motion on some analog axis. May report data redundant to other, more specific events.
134    AxisMotion { device_id: DeviceId, axis: AxisId, value: f64 },
135
136    /// The window needs to be redrawn.
137    Refresh,
138
139    /// Touch event has been received
140    Touch(Touch),
141
142    /// The DPI factor of the window has changed.
143    ///
144    /// The following user actions can cause DPI changes:
145    ///
146    /// * Changing the display's resolution.
147    /// * Changing the display's DPI factor (e.g. in Control Panel on Windows).
148    /// * Moving the window to a display with a different DPI factor.
149    ///
150    /// For more information about DPI in general, see the [`dpi`](dpi/index.html) module.
151    HiDpiFactorChanged(f64),
152}
153
154/// Represents raw hardware events that are not associated with any particular window.
155///
156/// Useful for interactions that diverge significantly from a conventional 2D GUI, such as 3D camera or first-person
157/// game controls. Many physical actions, such as mouse movement, can produce both device and window events. Because
158/// window events typically arise from virtual devices (corresponding to GUI cursors and keyboard focus) the device IDs
159/// may not match.
160///
161/// Note that these events are delivered regardless of input focus.
162#[derive(Clone, Debug, PartialEq)]
163pub enum DeviceEvent {
164    Added,
165    Removed,
166
167    /// Change in physical position of a pointing device.
168    ///
169    /// This represents raw, unfiltered physical motion. Not to be confused with `WindowEvent::CursorMoved`.
170    MouseMotion {
171        /// (x, y) change in position in unspecified units.
172        ///
173        /// Different devices may use different units.
174        delta: (f64, f64),
175    },
176
177    /// Physical scroll event
178    MouseWheel {
179        delta: MouseScrollDelta,
180    },
181
182    /// Motion on some analog axis.  This event will be reported for all arbitrary input devices
183    /// that winit supports on this platform, including mouse devices.  If the device is a mouse
184    /// device then this will be reported alongside the MouseMotion event.
185    Motion { axis: AxisId, value: f64 },
186
187    Button { button: ButtonId, state: ElementState },
188    Key(KeyboardInput),
189    Text { codepoint: char },
190}
191
192/// Describes a keyboard input event.
193#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
194#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
195 pub struct KeyboardInput {
196    /// Identifies the physical key pressed
197    ///
198    /// This should not change if the user adjusts the host's keyboard map. Use when the physical location of the
199    /// key is more important than the key's host GUI semantics, such as for movement controls in a first-person
200    /// game.
201    pub scancode: ScanCode,
202
203    pub state: ElementState,
204
205    /// Identifies the semantic meaning of the key
206    ///
207    /// Use when the semantics of the key are more important than the physical location of the key, such as when
208    /// implementing appropriate behavior for "page up."
209    pub virtual_keycode: Option<VirtualKeyCode>,
210
211    /// Modifier keys active at the time of this input.
212    ///
213    /// This is tracked internally to avoid tracking errors arising from modifier key state changes when events from
214    /// this device are not being delivered to the application, e.g. due to keyboard focus being elsewhere.
215    pub modifiers: ModifiersState
216}
217
218/// Describes touch-screen input state.
219#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
220#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 
221pub enum TouchPhase {
222    Started,
223    Moved,
224    Ended,
225    Cancelled
226}
227
228/// Represents touch event
229///
230/// Every time user touches screen new Start event with some finger id is generated.
231/// When the finger is removed from the screen End event with same id is generated.
232///
233/// For every id there will be at least 2 events with phases Start and End (or Cancelled).
234/// There may be 0 or more Move events.
235///
236///
237/// Depending on platform implementation id may or may not be reused by system after End event.
238///
239/// Gesture regonizer using this event should assume that Start event received with same id
240/// as previously received End event is a new finger and has nothing to do with an old one.
241///
242/// Touch may be cancelled if for example window lost focus.
243#[derive(Debug, Clone, Copy, PartialEq)]
244pub struct Touch {
245    pub device_id: DeviceId,
246    pub phase: TouchPhase,
247    pub location: LogicalPosition,
248    /// unique identifier of a finger.
249    pub id: u64
250}
251
252/// Hardware-dependent keyboard scan code.
253pub type ScanCode = u32;
254
255/// Identifier for a specific analog axis on some device.
256pub type AxisId = u32;
257
258/// Identifier for a specific button on some device.
259pub type ButtonId = u32;
260
261/// Describes the input state of a key.
262#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
263#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 
264pub enum ElementState {
265    Pressed,
266    Released,
267}
268
269/// Describes a button of a mouse controller.
270#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
271#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 
272pub enum MouseButton {
273    Left,
274    Right,
275    Middle,
276    Other(u8),
277}
278
279/// Describes a difference in the mouse scroll wheel state.
280#[derive(Debug, Clone, Copy, PartialEq)]
281#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 
282pub enum MouseScrollDelta {
283	/// Amount in lines or rows to scroll in the horizontal
284	/// and vertical directions.
285	///
286	/// Positive values indicate movement forward
287	/// (away from the user) or rightwards.
288	LineDelta(f32, f32),
289	/// Amount in pixels to scroll in the horizontal and
290	/// vertical direction.
291	///
292	/// Scroll events are expressed as a PixelDelta if
293	/// supported by the device (eg. a touchpad) and
294	/// platform.
295	PixelDelta(LogicalPosition),
296}
297
298/// Symbolic name for a keyboard key.
299#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
300#[repr(u32)]
301#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 
302pub enum VirtualKeyCode {
303    /// The '1' key over the letters.
304    Key1,
305    /// The '2' key over the letters.
306    Key2,
307    /// The '3' key over the letters.
308    Key3,
309    /// The '4' key over the letters.
310    Key4,
311    /// The '5' key over the letters.
312    Key5,
313    /// The '6' key over the letters.
314    Key6,
315    /// The '7' key over the letters.
316    Key7,
317    /// The '8' key over the letters.
318    Key8,
319    /// The '9' key over the letters.
320    Key9,
321    /// The '0' key over the 'O' and 'P' keys.
322    Key0,
323
324    A,
325    B,
326    C,
327    D,
328    E,
329    F,
330    G,
331    H,
332    I,
333    J,
334    K,
335    L,
336    M,
337    N,
338    O,
339    P,
340    Q,
341    R,
342    S,
343    T,
344    U,
345    V,
346    W,
347    X,
348    Y,
349    Z,
350
351    /// The Escape key, next to F1.
352    Escape,
353
354    F1,
355    F2,
356    F3,
357    F4,
358    F5,
359    F6,
360    F7,
361    F8,
362    F9,
363    F10,
364    F11,
365    F12,
366    F13,
367    F14,
368    F15,
369    F16,
370    F17,
371    F18,
372    F19,
373    F20,
374    F21,
375    F22,
376    F23,
377    F24,
378
379    /// Print Screen/SysRq.
380    Snapshot,
381    /// Scroll Lock.
382    Scroll,
383    /// Pause/Break key, next to Scroll lock.
384    Pause,
385
386    /// `Insert`, next to Backspace.
387    Insert,
388    Home,
389    Delete,
390    End,
391    PageDown,
392    PageUp,
393
394    Left,
395    Up,
396    Right,
397    Down,
398
399    /// The Backspace key, right over Enter.
400    // TODO: rename
401    Back,
402    /// The Enter key.
403    Return,
404    /// The space bar.
405    Space,
406
407    /// The "Compose" key on Linux.
408    Compose,
409
410    Caret,
411
412    Numlock,
413    Numpad0,
414    Numpad1,
415    Numpad2,
416    Numpad3,
417    Numpad4,
418    Numpad5,
419    Numpad6,
420    Numpad7,
421    Numpad8,
422    Numpad9,
423
424    AbntC1,
425    AbntC2,
426    Add,
427    Apostrophe,
428    Apps,
429    At,
430    Ax,
431    Backslash,
432    Calculator,
433    Capital,
434    Colon,
435    Comma,
436    Convert,
437    Decimal,
438    Divide,
439    Equals,
440    Grave,
441    Kana,
442    Kanji,
443    LAlt,
444    LBracket,
445    LControl,
446    LShift,
447    LWin,
448    Mail,
449    MediaSelect,
450    MediaStop,
451    Minus,
452    Multiply,
453    Mute,
454    MyComputer,
455    NavigateForward, // also called "Prior"
456    NavigateBackward, // also called "Next"
457    NextTrack,
458    NoConvert,
459    NumpadComma,
460    NumpadEnter,
461    NumpadEquals,
462    OEM102,
463    Period,
464    PlayPause,
465    Power,
466    PrevTrack,
467    RAlt,
468    RBracket,
469    RControl,
470    RShift,
471    RWin,
472    Semicolon,
473    Slash,
474    Sleep,
475    Stop,
476    Subtract,
477    Sysrq,
478    Tab,
479    Underline,
480    Unlabeled,
481    VolumeDown,
482    VolumeUp,
483    Wake,
484    WebBack,
485    WebFavorites,
486    WebForward,
487    WebHome,
488    WebRefresh,
489    WebSearch,
490    WebStop,
491    Yen,
492    Copy,
493    Paste,
494    Cut,
495}
496
497/// Represents the current state of the keyboard modifiers
498///
499/// Each field of this struct represents a modifier and is `true` if this modifier is active.
500#[derive(Default, Debug, Hash, PartialEq, Eq, Clone, Copy)]
501#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
502#[cfg_attr(feature = "serde", serde(default))]
503pub struct ModifiersState {
504    /// The "shift" key
505    pub shift: bool,
506    /// The "control" key
507    pub ctrl: bool,
508    /// The "alt" key
509    pub alt: bool,
510    /// The "logo" key
511    ///
512    /// This is the "windows" key on PC and "command" key on Mac.
513    pub logo: bool
514}
515
516pub type EventsLoop = events_loop::EventsLoop<Event>;