2
2
[ ![ Crate] ( https://img.shields.io/crates/v/rdev.svg )] ( https://crates.io/crates/rdev )
3
3
[ ![ API] ( https://docs.rs/rdev/badge.svg )] ( https://docs.rs/rdev )
4
4
5
- Simple library to listen and send events to keyboard and mouse.
5
+ # rdev
6
+
7
+ Simple library to listen and send events to keyboard and mouse on MacOS, Windows and Linux
8
+ (x11).
6
9
7
10
You can also check out [ Enigo] ( https://github.com/Enigo-rs/Enigo ) which is another
8
11
crate which helped me write this one.
9
12
10
13
This crate is so far a pet project for me to understand the rust ecosystem.
11
14
12
- ## Simple Usage
13
-
14
- ### Listening to global events
15
+ ## Listening to global events
15
16
16
17
``` rust
17
18
use rdev :: {listen, Event };
18
19
19
- fn main () {
20
- // This will block.
21
- if let Err (error ) = listen (callback ) {
22
- println! (" Error: {:?}" , error )
23
- }
20
+ // This will block.
21
+ if let Err (error ) = listen (callback ) {
22
+ println! (" Error: {:?}" , error )
24
23
}
25
24
26
25
fn callback (event : Event ) {
@@ -32,7 +31,7 @@ fn callback(event: Event) {
32
31
}
33
32
```
34
33
35
- ### Sending some events
34
+ ## Sending some events
36
35
37
36
``` rust
38
37
use rdev :: {simulate, Button , EventType , Key , SimulateError };
@@ -50,95 +49,31 @@ fn send(event_type: &EventType) {
50
49
thread :: sleep (delay );
51
50
}
52
51
53
- fn main () {
54
- send (& EventType :: KeyPress (Key :: KeyS ));
55
- send (& EventType :: KeyRelease (Key :: KeyS ));
56
-
57
- send (& EventType :: MouseMove { x : 0.0 , y : 0.0 });
58
- send (& EventType :: MouseMove { x : 400.0 , y : 400.0 });
59
- send (& EventType :: ButtonPress (Button :: Left ));
60
- send (& EventType :: ButtonRelease (Button :: Right ));
61
- send (& EventType :: Wheel {
62
- delta_x : 0 ,
63
- delta_y : 1 ,
64
- });
65
- }
66
- ```
67
-
68
- ### Getting the main screen size
69
-
70
- ``` rust
71
- use rdev :: {display_size};
72
-
73
- fn main () {
74
- let (w , h ) = display_size ();
75
- assert! (w > 0 );
76
- assert! (h > 0 );
77
- }
78
- ```
79
-
80
- ### Keyboard state
81
-
82
- We can define a dummy Keyboard, that we will use to detect
83
- what kind of EventType trigger some String. We get the currently used
84
- layout for now !
85
- Caveat : This is layout dependent. If your app needs to support
86
- layout switching don't use this !
87
- Caveat: On Linux, the dead keys mechanism is not implemented.
88
- Caveat: Only shift and dead keys are implemented, Alt+unicode code on windows
89
- won't work.
90
-
91
- ``` rust
92
- use rdev :: {Keyboard , EventType , Key , KeyboardState };
93
-
94
- let mut keyboard = Keyboard :: new (). unwrap ();
95
- let string = keyboard . add (& EventType :: KeyPress (Key :: KeyS ));
96
- // string == Some("s")
52
+ send (& EventType :: KeyPress (Key :: KeyS ));
53
+ send (& EventType :: KeyRelease (Key :: KeyS ));
54
+
55
+ send (& EventType :: MouseMove { x : 0.0 , y : 0.0 });
56
+ send (& EventType :: MouseMove { x : 400.0 , y : 400.0 });
57
+ send (& EventType :: ButtonPress (Button :: Left ));
58
+ send (& EventType :: ButtonRelease (Button :: Right ));
59
+ send (& EventType :: Wheel {
60
+ delta_x : 0 ,
61
+ delta_y : 1 ,
62
+ });
97
63
```
98
-
99
- ### Grabbing global events.
100
-
101
- In the callback, returning None ignores the event
102
- and returning the event let's it pass. There is no modification of the event
103
- possible here.
104
- Caveat: On MacOS, you require the grab
105
- loop needs to be the primary app (no fork before) and need to have accessibility
106
- settings enabled.
107
- On Linux, this is not implemented, you will always receive an error.
108
-
109
- ``` rust
110
- use rdev :: {grab, Event , EventType , Key };
111
-
112
- fn callback (event : Event ) -> Option <Event > {
113
- println! (" My callback {:?}" , event );
114
- match event . event_type{
115
- EventType :: KeyPress (Key :: Tab ) => None ,
116
- _ => Some (event ),
117
- }
118
- }
119
- fn main (){
120
- // This will block.
121
- if let Err (error ) = grab (callback ) {
122
- println! (" Error: {:?}" , error )
123
- }
124
- }
125
- ```
126
-
127
- ### Serialization
128
-
129
- Serialization and deserialization is optional behind the feature "serialize".
130
-
131
- ### Event struct
64
+ ## Main structs
65
+ ### Event
132
66
133
67
In order to detect what a user types, we need to plug to the OS level management
134
68
of keyboard state (modifiers like shift, ctrl, but also dead keys if they exist).
135
69
136
- In order to see what is the outcome of an event, you need to read the Event::name option.
70
+ ` EventType ` corresponds to a * physical* event, corresponding to QWERTY layout
71
+ ` Event ` corresponds to an actual event that was received and ` Event.name ` reflects
72
+ what key was interpreted by the OS at that time, it will respect the layout.
137
73
138
74
``` rust
139
75
/// When events arrive from the system we can add some information
140
- /// time is when the event was received, name *will* be at some point changed
141
- /// to be mapped to the function of the key (Alt, s, Return and so on).
76
+ /// time is when the event was received.
142
77
#[derive(Debug )]
143
78
pub struct Event {
144
79
pub time : SystemTime ,
@@ -152,7 +87,7 @@ not displayable unicode characters. We send exactly what the OS sends us so do s
152
87
before using it.
153
88
Caveat: Dead keys don't function yet on Linux
154
89
155
- ### Events enum
90
+ ### EventType
156
91
157
92
In order to manage different OS, the current EventType choices is a mix&match
158
93
to account for all possible events.
@@ -194,3 +129,46 @@ pub enum EventType {
194
129
For now the code only works for Linux (X11), MacOS and Windows. On MacOS, the listen
195
130
loop needs to be the primary app (no fork before) and needs to have accessibility
196
131
settings enabled (Terminal added in System Preferences > Security & Privacy > Privacy > Accessibility).
132
+
133
+ ## Getting the main screen size
134
+
135
+ ``` rust
136
+ use rdev :: {display_size};
137
+
138
+ let (w , h ) = display_size (). unwrap ();
139
+ assert! (w > 0 );
140
+ assert! (h > 0 );
141
+ ```
142
+
143
+ ## Keyboard state
144
+
145
+ We can define a dummy Keyboard, that we will use to detect
146
+ what kind of EventType trigger some String. We get the currently used
147
+ layout for now !
148
+ Caveat : This is layout dependent. If your app needs to support
149
+ layout switching don't use this !
150
+ Caveat: On Linux, the dead keys mechanism is not implemented.
151
+ Caveat: Only shift and dead keys are implemented, Alt+unicode code on windows
152
+ won't work.
153
+
154
+ ``` rust
155
+ use rdev :: {Keyboard , EventType , Key , KeyboardState };
156
+
157
+ let mut keyboard = Keyboard :: new (). unwrap ();
158
+ let string = keyboard . add (& EventType :: KeyPress (Key :: KeyS ));
159
+ // string == Some("s")
160
+ ```
161
+
162
+ ## Grabbing global events. (Requires ` unstable_grab ` feature)
163
+
164
+ In the callback, returning None ignores the event
165
+ and returning the event let's it pass. There is no modification of the event
166
+ possible here.
167
+ Caveat: On MacOS, you require the grab
168
+ loop needs to be the primary app (no fork before) and need to have accessibility
169
+ settings enabled.
170
+ ** Not implemented on Linux, you will always receive an error.**
171
+
172
+ ## Serialization
173
+
174
+ Serialization and deserialization. (Requires ` serialize ` feature).
0 commit comments