summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWez Furlong <wez@wezfurlong.org>2024-06-09 06:20:56 -0700
committerWez Furlong <wez@wezfurlong.org>2024-06-09 06:20:56 -0700
commit2d2b476643a246ca17f30cfcbb280e76bf6c281a (patch)
treebd653ccfada8456c566270ae16ebb9535aafc10b
parent9b18364dafd4d35095a9019ed37394ede449e7dc (diff)
Add --wait-for-device flag
This is a simple approach for the case where the device isn't plugged in on startup. It works by polling the devices in a loop every few seconds. It is probably better and more robust to use udev rules for this purpose, but this approach will do for a quick and dirty ad-hoc user. closes: #35 closes: #46 closes: #60
-rw-r--r--src/main.rs47
1 files changed, 45 insertions, 2 deletions
diff --git a/src/main.rs b/src/main.rs
index 5828a37..d578185 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,4 @@
+use crate::deviceinfo::DeviceInfo;
use crate::mapping::*;
use crate::remapper::*;
use anyhow::{Context, Result};
@@ -40,6 +41,14 @@ enum Opt {
/// Override the phys device specified by the config file
#[arg(long)]
phys: Option<String>,
+
+ /// If the device isn't found on startup, wait forever
+ /// until the device is plugged in. This works by polling
+ /// the set of devices every few seconds. It is not as
+ /// efficient as setting up a udev rule to spawn evremap,
+ /// but is simpler to setup ad-hoc.
+ #[arg(long)]
+ wait_for_device: bool,
},
}
@@ -68,6 +77,36 @@ fn setup_logger() {
builder.init();
}
+fn get_device(
+ device_name: &str,
+ phys: Option<&str>,
+ wait_for_device: bool,
+) -> anyhow::Result<DeviceInfo> {
+ match deviceinfo::DeviceInfo::with_name(device_name, phys) {
+ Ok(dev) => return Ok(dev),
+ Err(err) if !wait_for_device => return Err(err),
+ Err(err) => {
+ log::warn!("{err:#}. Will wait until it is attached.");
+ }
+ }
+
+ const MAX_SLEEP: Duration = Duration::from_secs(10);
+ const ONE_SECOND: Duration = Duration::from_secs(1);
+ let mut sleep = ONE_SECOND;
+
+ loop {
+ std::thread::sleep(sleep);
+ sleep = (sleep + ONE_SECOND).min(MAX_SLEEP);
+
+ match deviceinfo::DeviceInfo::with_name(device_name, phys) {
+ Ok(dev) => return Ok(dev),
+ Err(err) => {
+ log::debug!("{err:#}");
+ }
+ }
+ }
+}
+
fn main() -> Result<()> {
setup_logger();
let opt = Opt::parse();
@@ -80,6 +119,7 @@ fn main() -> Result<()> {
delay,
device_name,
phys,
+ wait_for_device,
} => {
let mut mapping_config = MappingConfig::from_file(&config_file).context(format!(
"loading MappingConfig from {}",
@@ -104,8 +144,11 @@ fn main() -> Result<()> {
log::warn!("Short delay: release any keys now!");
std::thread::sleep(Duration::from_secs_f64(delay));
- let device_info =
- deviceinfo::DeviceInfo::with_name(device_name, mapping_config.phys.as_deref())?;
+ let device_info = get_device(
+ device_name,
+ mapping_config.phys.as_deref(),
+ wait_for_device,
+ )?;
let mut mapper = InputMapper::create_mapper(device_info.path, mapping_config.mappings)?;
mapper.run_mapper()