diff --git a/src/input/composite_device/mod.rs b/src/input/composite_device/mod.rs index ae1538e..318a347 100644 --- a/src/input/composite_device/mod.rs +++ b/src/input/composite_device/mod.rs @@ -113,6 +113,9 @@ pub struct CompositeDevice { source_devices: HashMap, /// Source devices that this composite device will consume. source_devices_discovered: Vec, + /// Source devices that should be hidden before they are started. This + /// is a list of devnode paths to hide (e.g. ["/dev/input/event10", "/dev/hidraw1"]) + source_devices_to_hide: Vec, /// HashSet of source devices that are blocked from passing their input events to target /// events. source_devices_blocked: HashSet, @@ -165,7 +168,7 @@ pub struct CompositeDevice { } impl CompositeDevice { - pub async fn new( + pub fn new( conn: Connection, manager: mpsc::Sender, config: CompositeDeviceConfig, @@ -195,6 +198,7 @@ impl CompositeDevice { rx, source_devices: HashMap::new(), source_devices_discovered: Vec::new(), + source_devices_to_hide: Vec::new(), source_devices_blocked: HashSet::new(), source_device_paths: Vec::new(), source_device_tasks: JoinSet::new(), @@ -239,7 +243,7 @@ impl CompositeDevice { } } - if let Err(e) = device.add_source_device(device_info).await { + if let Err(e) = device.add_source_device(device_info) { return Err(e.to_string().into()); } @@ -602,7 +606,13 @@ impl CompositeDevice { /// Start and run the source devices that this composite device will /// consume. async fn run_source_devices(&mut self) -> Result<(), Box> { - // Keep a list of all the tasks + // Hide the device if specified + for source_path in self.source_devices_to_hide.drain(..) { + log::debug!("Hiding device: {}", source_path); + if let Err(e) = hide_device(source_path.as_str()).await { + log::warn!("Failed to hide device '{source_path}': {e:?}"); + } + } log::debug!("Starting new source devices"); // Start listening for events from all source devices @@ -1387,7 +1397,7 @@ impl CompositeDevice { /// Executed whenever a source device is added to this [CompositeDevice]. async fn on_source_device_added(&mut self, device: UdevDevice) -> Result<(), Box> { - if let Err(e) = self.add_source_device(device).await { + if let Err(e) = self.add_source_device(device) { return Err(e.to_string().into()); } self.run_source_devices().await?; @@ -1432,7 +1442,7 @@ impl CompositeDevice { } /// Creates and adds a source device using the given [SourceDeviceInfo] - async fn add_source_device( + fn add_source_device( &mut self, device: UdevDevice, ) -> Result<(), Box> { @@ -1456,10 +1466,7 @@ impl CompositeDevice { let should_hide = !should_passthru && subsystem.as_str() != "iio"; if should_hide { let source_path = device.devnode(); - log::debug!("Hiding device: {}", source_path); - if let Err(e) = hide_device(source_path.as_str()).await { - log::warn!("Failed to hide device '{source_path}': {e:?}"); - } + self.source_devices_to_hide.push(source_path); } let source_device = match subsystem.as_str() { diff --git a/src/input/manager.rs b/src/input/manager.rs index b646751..04c3bc3 100644 --- a/src/input/manager.rs +++ b/src/input/manager.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use std::collections::HashSet; use std::error::Error; use std::fs; +use std::path::PathBuf; use std::time::Duration; use ::procfs::CpuInfo; @@ -546,8 +547,7 @@ impl Manager { device, self.next_composite_dbus_path()?, capability_map, - ) - .await?; + )?; // Check to see if there's already a CompositeDevice for // these source devices. @@ -1553,6 +1553,13 @@ impl Manager { continue; }; + // Ensure the path is a valid devnode + let full_path = PathBuf::from(format!("{base_path}/{name}")); + if full_path.is_dir() { + log::trace!("Devnode path {base_path}/{name} is a directory. Skipping."); + continue; + } + // Wait until the device has initialized with udev const MAX_TRIES: u8 = 80; let mut attempt: u8 = 0;