enigo_copy/
lib.rs

1//! Enigo lets you simulate mouse and keyboard input-events as if they were
2//! made by the actual hardware. It is available on Linux (X11), macOS and
3//! Windows.
4//!
5//! It can be used for testing user interfaces on different platforms, building
6//! remote control applications or just automating tasks for user interfaces
7//! unaccessible by a public API or scripting language.
8//!
9//! This library is in an early alpha status, the API will change in
10//! in the future.
11//!
12//! In order to use the library, you only have to know about three
13//! things:
14//! - [`KeyboardControllable`] (trait): used to simulate a key click, enter text
15//!   or something similar
16//! - [`MouseControllable`] (trait): do something with the mouse or you find out
17//!   the display
18//! size
19//! - [`Enigo`] (struct): implements the two traits [`KeyboardControllable`] and
20//!   [`MouseControllable`]
21//!
22//! A simple [DSL](https://en.wikipedia.org/wiki/Domain-specific_language)
23//! is available. It is documented in the [`dsl`] module.
24
25//! # Examples
26//! ```no_run
27//! use enigo::*;
28//! let mut enigo = Enigo::new();
29//! //paste
30//! enigo.key_down(Key::Control);
31//! enigo.key_click(Key::Layout('v'));
32//! enigo.key_up(Key::Control);
33//! ```
34//!
35//! ```no_run
36//! use enigo::*;
37//! let mut enigo = Enigo::new();
38//! enigo.mouse_move_to(500, 200);
39//! enigo.mouse_down(MouseButton::Left);
40//! enigo.mouse_move_relative(100, 100);
41//! enigo.mouse_up(MouseButton::Left);
42//! enigo.key_sequence("hello world");
43//! ```
44
45#![deny(clippy::pedantic)]
46#![allow(clippy::cast_lossless)]
47#![allow(clippy::cast_possible_truncation)]
48#![allow(clippy::cast_possible_wrap)]
49#![allow(clippy::cast_sign_loss)]
50#![allow(deprecated)]
51
52#[cfg(target_os = "macos")]
53#[macro_use]
54extern crate objc;
55
56// TODO(dustin) use interior mutability not &mut self
57
58#[cfg(target_os = "windows")]
59mod win;
60#[cfg(target_os = "windows")]
61pub use crate::win::Enigo;
62
63#[cfg(target_os = "macos")]
64mod macos;
65#[cfg(target_os = "macos")]
66pub use crate::macos::Enigo;
67
68#[cfg(target_os = "linux")]
69mod linux;
70#[cfg(target_os = "linux")]
71pub use crate::linux::Enigo;
72
73/// DSL parser module
74///
75/// The current status is that you can just print [unicode](http://unicode.org/) characters like [emoji](http://getemoji.com/) without the `{+SHIFT}`
76/// [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) or any other "special" key on the Linux, macOS and Windows operating system.
77pub mod dsl;
78
79#[cfg(feature = "with_serde")]
80#[macro_use]
81extern crate serde_derive;
82
83#[cfg(feature = "with_serde")]
84extern crate serde;
85
86#[cfg_attr(feature = "with_serde", derive(Serialize, Deserialize))]
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
88/// [`MouseButton`] represents a mouse button and is used in e.g
89/// [`MouseControllable::mouse_click`].
90
91// Warning! If there are ANY CHANGES to this enum, we
92// need to change the size of the array in the macOS implementation of the Enigo
93// struct that stores the nth click for each MouseButton
94pub enum MouseButton {
95    /// Left mouse button
96    Left,
97    /// Middle mouse button
98    Middle,
99    /// Right mouse button
100    Right,
101
102    /// Scroll up button. It is better to use the
103    /// [MouseControllable::mouse_scroll_y] method to scroll.
104    ScrollUp,
105    /// Scroll down button. It is better to use the
106    /// [MouseControllable::mouse_scroll_y] method to scroll.
107    ScrollDown,
108    /// Scroll left button. It is better to use the
109    /// [MouseControllable::mouse_scroll_x] method to scroll.
110    ScrollLeft,
111    /// Scroll right button. It is better to use the
112    /// [MouseControllable::mouse_scroll_x] method to scroll.
113    ScrollRight,
114}
115
116/// Contains functions to control the mouse and to get the size of the display.
117/// Enigo uses a Cartesian coordinate system for specifying coordinates. The
118/// origin in this system is located in the top-left corner of the current
119/// screen, with positive values extending along the axes down and to the
120/// right of the origin point and it is measured in pixels. The same coordinate
121/// system is used on all operating systems.
122pub trait MouseControllable {
123    /// Move the mouse cursor to the specified x and y coordinates.
124    ///
125    /// The topleft corner of your monitor screen is x=0 y=0. Move
126    /// the cursor down the screen by increasing the y and to the right
127    /// by increasing x coordinate.
128    ///
129    /// # Example
130    ///
131    /// ```no_run
132    /// use enigo::*;
133    /// let mut enigo = Enigo::new();
134    /// enigo.mouse_move_to(500, 200);
135    /// ```
136    fn mouse_move_to(&mut self, x: i32, y: i32);
137
138    /// Move the mouse cursor the specified amount in the x and y
139    /// direction. A positive x value moves the mouse cursor `x` pixels to the
140    /// right. A negative value for `x` moves the mouse cursor to the left.
141    /// A positive value of y moves the mouse cursor down, a negative one
142    /// moves the mouse cursor up.
143    ///
144    /// # Example
145    ///
146    /// ```no_run
147    /// use enigo::*;
148    /// let mut enigo = Enigo::new();
149    /// enigo.mouse_move_relative(100, 100);
150    /// ```
151    fn mouse_move_relative(&mut self, x: i32, y: i32);
152
153    /// Push down the mouse button specified by the parameter
154    /// `button` of type [`MouseButton`] and hold it until it is released by
155    /// [`MouseControllable::mouse_up`].
156    /// Calls to [`MouseControllable::mouse_move_to`] or
157    /// [`MouseControllable::mouse_move_relative`] will
158    /// work like expected and will e.g. drag widgets or highlight text.
159    ///
160    /// # Example
161    ///
162    /// ```no_run
163    /// use enigo::*;
164    /// let mut enigo = Enigo::new();
165    /// enigo.mouse_down(MouseButton::Left);
166    /// ```
167    fn mouse_down(&mut self, button: MouseButton);
168
169    /// Release a pushed down mouse button
170    ///
171    /// Lift up a previously pushed down button (by invoking
172    /// [`MouseControllable::mouse_down`]).
173    /// If the button was not pushed down or consecutive calls without
174    /// invoking [`MouseControllable::mouse_down`] will emit lift up
175    /// events. It depends on the operating system whats actually happening
176    /// – my guess is it will just get ignored.
177    ///
178    /// # Example
179    ///
180    /// ```no_run
181    /// use enigo::*;
182    /// let mut enigo = Enigo::new();
183    /// enigo.mouse_down(MouseButton::Right);
184    /// enigo.mouse_up(MouseButton::Right);
185    /// ```
186    fn mouse_up(&mut self, button: MouseButton);
187
188    /// Click a mouse button
189    ///
190    /// It is essentially just a consecutive invocation of
191    /// [`MouseControllable::mouse_down`]
192    /// followed by a [`MouseControllable::mouse_up`]. Just for
193    /// convenience.
194    ///
195    /// # Example
196    ///
197    /// ```no_run
198    /// use enigo::*;
199    /// let mut enigo = Enigo::new();
200    /// enigo.mouse_click(MouseButton::Right);
201    /// ```
202    fn mouse_click(&mut self, button: MouseButton);
203
204    /// Scroll the mouse (wheel) left or right
205    ///
206    /// Positive numbers for `length` scroll to the right and negative ones to
207    /// the left. The value that is specified translates to `lines` defined
208    /// by the operating system and is essentially one 15° (click) rotation
209    /// on the mouse wheel. How many lines it moves depends on the current
210    /// setting in the operating system.
211    ///
212    /// # Example
213    ///
214    /// ```no_run
215    /// use enigo::*;
216    /// let mut enigo = Enigo::new();
217    /// enigo.mouse_scroll_x(2);
218    /// ```
219    fn mouse_scroll_x(&mut self, length: i32);
220
221    /// Scroll the mouse (wheel) up or down
222    ///
223    /// Positive numbers for `length` scroll down and negative ones up. The
224    /// value that is specified translates to `lines` defined by the
225    /// operating system and is essentially one 15° (click) rotation on the
226    /// mouse wheel. How many lines it moves depends on the current setting
227    /// in the operating system.
228    ///
229    /// # Example
230    ///
231    /// ```no_run
232    /// use enigo::*;
233    /// let mut enigo = Enigo::new();
234    /// enigo.mouse_scroll_y(2);
235    /// ```
236    fn mouse_scroll_y(&mut self, length: i32);
237
238    /// Get the (width, height) of the main display in screen coordinates
239    /// (pixels). This currently only works on the main display
240    ///
241    /// # Example
242    ///
243    /// ```no_run
244    /// use enigo::*;
245    /// let mut enigo = Enigo::new();
246    /// let (width, height) = enigo.main_display_size();
247    /// ```
248    #[must_use]
249    fn main_display_size(&self) -> (i32, i32);
250
251    /// Get the location of the mouse in screen coordinates (pixels).
252    ///
253    /// # Example
254    ///
255    /// ```no_run
256    /// use enigo::*;
257    /// let mut enigo = Enigo::new();
258    /// let (x, y) = enigo.mouse_location();
259    /// ```
260    #[must_use]
261    fn mouse_location(&self) -> (i32, i32);
262}
263
264/// A key on the keyboard.
265/// For alphabetical keys, use [`Key::Layout`] for a system independent key.
266/// If a key is missing, you can use the raw keycode with [`Key::Raw`].
267#[cfg_attr(feature = "with_serde", derive(Serialize, Deserialize))]
268#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
269pub enum Key {
270    /// alt key on Linux and Windows (option key on macOS)
271    Alt,
272    /// backspace key
273    Backspace,
274    /// caps lock key
275    CapsLock,
276    #[deprecated(since = "0.0.12", note = "now renamed to Meta")]
277    /// command key on macOS (super key on Linux, windows key on Windows)
278    Command,
279    /// control key
280    Control,
281    /// delete key
282    Delete,
283    /// down arrow key
284    DownArrow,
285    /// end key
286    End,
287    /// escape key (esc)
288    Escape,
289    /// F1 key
290    F1,
291    /// F2 key
292    F2,
293    /// F3 key
294    F3,
295    /// F4 key
296    F4,
297    /// F5 key
298    F5,
299    /// F6 key
300    F6,
301    /// F7 key
302    F7,
303    /// F8 key
304    F8,
305    /// F9 key
306    F9,
307    /// F10 key
308    F10,
309    /// F11 key
310    F11,
311    /// F12 key
312    F12,
313    /// F13 key
314    F13,
315    /// F14 key
316    F14,
317    /// F15 key
318    F15,
319    /// F16 key
320    F16,
321    /// F17 key
322    F17,
323    /// F18 key
324    F18,
325    /// F19 key
326    F19,
327    /// F20 key
328    F20,
329    /// home key
330    Home,
331    /// left arrow key
332    LeftArrow,
333    /// meta key (also known as "windows", "super", and "command")
334    Meta,
335    /// option key on macOS (alt key on Linux and Windows)
336    Option,
337    /// page down key
338    PageDown,
339    /// page up key
340    PageUp,
341    /// return key
342    Return,
343    /// right arrow key
344    RightArrow,
345    /// shift key
346    Shift,
347    /// space key
348    Space,
349    #[deprecated(since = "0.0.12", note = "now renamed to Meta")]
350    /// super key on linux (command key on macOS, windows key on Windows)
351    Super,
352    /// tab key (tabulator)
353    Tab,
354    /// up arrow key
355    UpArrow,
356    #[deprecated(since = "0.0.12", note = "now renamed to Meta")]
357    /// windows key on Windows (super key on Linux, command key on macOS)
358    Windows,
359    /// keyboard layout dependent key
360    Layout(char),
361    /// raw keycode eg 0x38
362    Raw(u16),
363}
364
365/// Contains functions to simulate key presses and to input text.
366///
367/// For the keyboard there are currently two modes you can use. The first mode
368/// is represented by the [`key_sequence`](KeyboardControllable::key_sequence)
369/// function. It's purpose is to simply write unicode characters. This is
370/// independent of the keyboard layout. Please note that
371/// you're not be able to use modifier keys like Control
372/// to influence the outcome. If you want to use modifier keys to e.g.
373/// copy/paste, use the Layout variant. Please note that this is indeed layout
374/// dependent.
375pub trait KeyboardControllable {
376    /// Type the string parsed with DSL.
377    ///
378    /// Typing {+SHIFT}hello{-SHIFT} becomes HELLO.
379    /// Please have a look at the [dsl] module for more information.
380    fn key_sequence_parse(&mut self, sequence: &str)
381    where
382        Self: Sized,
383    {
384        self.key_sequence_parse_try(sequence)
385            .expect("Could not parse sequence");
386    }
387
388    /// Same as [`KeyboardControllable::key_sequence_parse`] except returns any
389    /// errors
390    ///  # Errors
391    ///
392    /// Returns a [`dsl::ParseError`] if the sequence cannot be parsed
393    fn key_sequence_parse_try(&mut self, sequence: &str) -> Result<(), dsl::ParseError>
394    where
395        Self: Sized,
396    {
397        dsl::eval(self, sequence)
398    }
399
400    /// Enter the text. You can use unicode here like: ❤️. This works
401    /// regardless of the current keyboardlayout. You cannot use this function
402    /// for entering shortcuts or something similar. For shortcuts, use the
403    /// [`KeyboardControllable::key_click`] method instead.
404    ///
405    /// # Example
406    ///
407    /// ```no_run
408    /// use enigo::*;
409    /// let mut enigo = Enigo::new();
410    /// enigo.key_sequence("hello world ❤️");
411    /// ```
412    fn key_sequence(&mut self, sequence: &str);
413
414    /// Press down the given key
415    fn key_down(&mut self, key: Key);
416
417    /// Release a pressed down key
418    fn key_up(&mut self, key: Key);
419
420    /// Press and release the key. It is the same as calling the
421    /// [`KeyboardControllable::key_down`] and
422    /// [`KeyboardControllable::key_up`] functions consecutively
423    fn key_click(&mut self, key: Key);
424}
425
426impl Enigo {
427    /// Constructs a new `Enigo` instance.
428    ///
429    /// # Example
430    ///
431    /// ```no_run
432    /// use enigo::*;
433    /// let mut enigo = Enigo::new();
434    /// ```
435    #[must_use]
436    pub fn new() -> Self {
437        Self::default()
438    }
439}
440
441use std::fmt;
442
443impl fmt::Debug for Enigo {
444    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
445        write!(f, "Enigo")
446    }
447}