1
+ use crate :: deviceinfo:: DeviceInfo ;
1
2
use crate :: mapping:: * ;
2
3
use crate :: remapper:: * ;
3
4
use anyhow:: { Context , Result } ;
@@ -40,6 +41,14 @@ enum Opt {
40
41
/// Override the phys device specified by the config file
41
42
#[ arg( long) ]
42
43
phys : Option < String > ,
44
+
45
+ /// If the device isn't found on startup, wait forever
46
+ /// until the device is plugged in. This works by polling
47
+ /// the set of devices every few seconds. It is not as
48
+ /// efficient as setting up a udev rule to spawn evremap,
49
+ /// but is simpler to setup ad-hoc.
50
+ #[ arg( long) ]
51
+ wait_for_device : bool ,
43
52
} ,
44
53
}
45
54
@@ -68,6 +77,36 @@ fn setup_logger() {
68
77
builder. init ( ) ;
69
78
}
70
79
80
+ fn get_device (
81
+ device_name : & str ,
82
+ phys : Option < & str > ,
83
+ wait_for_device : bool ,
84
+ ) -> anyhow:: Result < DeviceInfo > {
85
+ match deviceinfo:: DeviceInfo :: with_name ( device_name, phys) {
86
+ Ok ( dev) => return Ok ( dev) ,
87
+ Err ( err) if !wait_for_device => return Err ( err) ,
88
+ Err ( err) => {
89
+ log:: warn!( "{err:#}. Will wait until it is attached." ) ;
90
+ }
91
+ }
92
+
93
+ const MAX_SLEEP : Duration = Duration :: from_secs ( 10 ) ;
94
+ const ONE_SECOND : Duration = Duration :: from_secs ( 1 ) ;
95
+ let mut sleep = ONE_SECOND ;
96
+
97
+ loop {
98
+ std:: thread:: sleep ( sleep) ;
99
+ sleep = ( sleep + ONE_SECOND ) . min ( MAX_SLEEP ) ;
100
+
101
+ match deviceinfo:: DeviceInfo :: with_name ( device_name, phys) {
102
+ Ok ( dev) => return Ok ( dev) ,
103
+ Err ( err) => {
104
+ log:: debug!( "{err:#}" ) ;
105
+ }
106
+ }
107
+ }
108
+ }
109
+
71
110
fn main ( ) -> Result < ( ) > {
72
111
setup_logger ( ) ;
73
112
let opt = Opt :: parse ( ) ;
@@ -80,6 +119,7 @@ fn main() -> Result<()> {
80
119
delay,
81
120
device_name,
82
121
phys,
122
+ wait_for_device,
83
123
} => {
84
124
let mut mapping_config = MappingConfig :: from_file ( & config_file) . context ( format ! (
85
125
"loading MappingConfig from {}" ,
@@ -104,8 +144,11 @@ fn main() -> Result<()> {
104
144
log:: warn!( "Short delay: release any keys now!" ) ;
105
145
std:: thread:: sleep ( Duration :: from_secs_f64 ( delay) ) ;
106
146
107
- let device_info =
108
- deviceinfo:: DeviceInfo :: with_name ( device_name, mapping_config. phys . as_deref ( ) ) ?;
147
+ let device_info = get_device (
148
+ device_name,
149
+ mapping_config. phys . as_deref ( ) ,
150
+ wait_for_device,
151
+ ) ?;
109
152
110
153
let mut mapper = InputMapper :: create_mapper ( device_info. path , mapping_config. mappings ) ?;
111
154
mapper. run_mapper ( )
0 commit comments