@@ -9,23 +9,21 @@ use std::os::unix::prelude::AsRawFd;
9
9
use std:: path:: Path ;
10
10
use std:: ptr;
11
11
use std:: thread;
12
+ use std:: time:: Duration ;
12
13
use std:: {
13
- collections:: HashSet ,
14
14
mem:: zeroed,
15
15
os:: raw:: c_int,
16
16
sync:: { mpsc:: Sender , Arc , Mutex } ,
17
17
time:: SystemTime ,
18
18
} ;
19
- use strum:: IntoEnumIterator ;
20
- use x11:: xlib:: { self , AnyModifier , Display , GrabModeAsync , KeyPressMask , XUngrabKey } ;
19
+ use x11:: xlib:: { self , Display , GrabModeAsync , KeyPressMask , KeyReleaseMask } ;
21
20
22
21
#[ derive( Debug ) ]
23
22
pub struct MyDisplay ( * mut xlib:: Display ) ;
24
23
unsafe impl Sync for MyDisplay { }
25
24
unsafe impl Send for MyDisplay { }
26
25
27
26
lazy_static:: lazy_static! {
28
- pub static ref KEYS : Arc <Mutex <Option <HashSet <RdevKey >>>> = Arc :: new( Mutex :: new( None ) ) ;
29
27
pub static ref SENDER : Arc <Mutex <Option <Sender <GrabEvent >>>> = Arc :: new( Mutex :: new( None ) ) ;
30
28
}
31
29
@@ -43,13 +41,6 @@ pub enum GrabEvent {
43
41
KeyEvent ( Event ) ,
44
42
}
45
43
46
- pub fn init_keys ( keys : HashSet < RdevKey > ) {
47
- let mut global_keys = KEYS . lock ( ) . unwrap ( ) ;
48
- if global_keys. is_none ( ) {
49
- * global_keys = Some ( keys) ;
50
- }
51
- }
52
-
53
44
fn convert_event ( key : RdevKey , is_press : bool ) -> Event {
54
45
Event {
55
46
event_type : if is_press {
@@ -64,56 +55,34 @@ fn convert_event(key: RdevKey, is_press: bool) -> Event {
64
55
}
65
56
}
66
57
67
- fn is_key_grabed ( key : RdevKey ) -> bool {
68
- let global_keys = KEYS . lock ( ) . unwrap ( ) ;
69
- if let Some ( keys) = & * global_keys {
70
- keys. get ( & key) . is_some ( )
71
- } else {
72
- panic ! ( "[-] grab error in rdev: Please init keys first" ) ;
73
- }
74
- }
75
-
76
- fn grab_key ( display : * mut Display , grab_window : u64 , keycode : i32 ) {
58
+ fn grab_keys ( display : * mut Display , grab_window : u64 ) {
77
59
unsafe {
78
- xlib:: XGrabKey (
60
+ xlib:: XGrabKeyboard (
79
61
display,
80
- keycode,
81
- AnyModifier ,
82
62
grab_window,
83
63
c_int:: from ( true ) ,
84
64
GrabModeAsync ,
85
65
GrabModeAsync ,
66
+ xlib:: CurrentTime ,
86
67
) ;
68
+ xlib:: XFlush ( display) ;
69
+ thread:: sleep ( Duration :: from_millis ( 50 ) ) ;
87
70
}
88
71
}
89
72
90
- fn grab_keys ( display : * mut Display , grab_window : u64 ) {
91
- for key in RdevKey :: iter ( ) {
92
- let keycode: i32 = linux_keycode_from_key ( key) . unwrap_or_default ( ) as _ ;
93
- if is_key_grabed ( key) {
94
- grab_key ( display, grab_window, keycode) ;
95
- }
96
- }
97
- }
98
-
99
- fn ungrab_key ( display : * mut Display , grab_window : u64 , keycode : i32 ) {
73
+ fn ungrab_keys ( display : * mut Display ) {
100
74
unsafe {
101
- XUngrabKey ( display, keycode, AnyModifier , grab_window) ;
102
- }
103
- }
104
-
105
- fn ungrab_keys ( display : * mut Display , grab_window : u64 ) {
106
- for key in RdevKey :: iter ( ) {
107
- let keycode: i32 = linux_keycode_from_key ( key) . unwrap_or_default ( ) as _ ;
108
- if is_key_grabed ( key) {
109
- ungrab_key ( display, grab_window, keycode) ;
110
- }
75
+ xlib:: XUngrabKeyboard ( display, xlib:: CurrentTime ) ;
76
+ xlib:: XFlush ( display) ;
77
+ thread:: sleep ( Duration :: from_millis ( 50 ) ) ;
111
78
}
112
79
}
113
80
114
81
pub fn enable_grab ( ) -> Result < ( ) , GrabError > {
115
82
if let Some ( tx) = & * SENDER . lock ( ) . unwrap ( ) {
116
83
tx. send ( GrabEvent :: Grab ) . ok ( ) ;
84
+ /* if too fast: poll cannot perceive events */
85
+ thread:: sleep ( Duration :: from_millis ( 50 ) ) ;
117
86
} else {
118
87
return Err ( GrabError :: ListenError ) ;
119
88
} ;
@@ -123,21 +92,22 @@ pub fn enable_grab() -> Result<(), GrabError> {
123
92
pub fn disable_grab ( ) -> Result < ( ) , GrabError > {
124
93
if let Some ( tx) = & * SENDER . lock ( ) . unwrap ( ) {
125
94
tx. send ( GrabEvent :: UnGrab ) . ok ( ) ;
95
+ thread:: sleep ( Duration :: from_millis ( 50 ) ) ;
126
96
} else {
127
97
return Err ( GrabError :: ListenError ) ;
128
98
} ;
129
99
Ok ( ( ) )
130
100
}
131
101
132
- pub fn start_grab_listen < T > ( callback : T , keys : HashSet < RdevKey > )
102
+ pub fn start_grab_listen < T > ( callback : T )
133
103
where
134
104
T : FnMut ( Event ) -> Option < Event > + ' static ,
135
105
{
136
106
unsafe {
137
107
GLOBAL_CALLBACK = Some ( Box :: new ( callback) ) ;
138
108
}
139
- init_keys ( keys) ;
140
109
start_grab_service ( ) ;
110
+ thread:: sleep ( Duration :: from_millis ( 50 ) ) ;
141
111
}
142
112
143
113
pub fn exit_grab_listen ( ) -> Result < ( ) , GrabError > {
@@ -215,10 +185,8 @@ fn start_grab_thread() {
215
185
let grab_window = unsafe { xlib:: XRootWindowOfScreen ( screen) } ;
216
186
217
187
unsafe {
218
- xlib:: XSelectInput ( display, grab_window, KeyPressMask ) ;
188
+ xlib:: XSelectInput ( display, grab_window, KeyPressMask | KeyReleaseMask ) ;
219
189
}
220
- grab_keys ( display, grab_window) ;
221
- unsafe { xlib:: XFlush ( display) } ;
222
190
223
191
let grab_fd = unsafe { xlib:: XConnectionNumber ( display) } ;
224
192
unlink_socket ( FILE_PATH ) ;
@@ -264,13 +232,11 @@ fn start_grab_thread() {
264
232
socket
265
233
. recv ( buf. as_mut_slice ( ) )
266
234
. expect ( "recv function failed" ) ;
267
- // if recv "1": grab key
235
+ // if recv "1": grab key
268
236
if buf[ 0 ] == 49 {
269
237
grab_keys ( display, grab_window) ;
270
- unsafe { xlib:: XFlush ( display) } ;
271
238
} else {
272
- ungrab_keys ( display, grab_window) ;
273
- unsafe { xlib:: XFlush ( display) } ;
239
+ ungrab_keys ( display) ;
274
240
}
275
241
}
276
242
GRAB_KEY => unsafe {
0 commit comments