From fcf10c393b629c1db103b082d9d42ffb6da7d796 Mon Sep 17 00:00:00 2001 From: Matthew Schwartz Date: Thu, 12 Jun 2025 22:39:42 -0700 Subject: [PATCH] wip: allow custom InputPlumber target devices in configuration file Some devices may need more than only one InputPlumber target device, i.e. the MSI Claw series needs a `keyboard` target in order to grab the volume keys. To account for this, lets add the ability to specify multiple targets within the device configuration files. --- src/hardware.rs | 6 ++++++ src/inputplumber.rs | 42 +++++++++++++++++++++++++++++++++++++----- src/manager/user.rs | 7 +++++-- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/hardware.rs b/src/hardware.rs index 661984a..4c8f93c 100644 --- a/src/hardware.rs +++ b/src/hardware.rs @@ -71,6 +71,7 @@ pub(crate) struct DeviceConfig { pub gpu_clocks: Option>, pub battery_charge_limit: Option, pub performance_profile: Option, + pub inputplumber: Option, } #[derive(Clone, Deserialize, Debug)] @@ -100,6 +101,11 @@ pub(crate) struct FirmwareAttributeConfig { pub performance_profile: Option, } +#[derive(Clone, Deserialize, Debug)] +pub struct InputPlumberConfig { + pub target_devices: Option>, +} + #[derive(Clone, Deserialize, Debug)] pub(crate) struct PerformanceProfileConfig { pub suggested_default: String, diff --git a/src/inputplumber.rs b/src/inputplumber.rs index aec1b21..116791d 100644 --- a/src/inputplumber.rs +++ b/src/inputplumber.rs @@ -15,6 +15,7 @@ use zbus::proxy::CacheProperties; use zbus::zvariant::ObjectPath; use zbus::Connection; +use crate::hardware; use crate::Service; #[zbus::proxy( @@ -100,13 +101,44 @@ impl DeckService { .path(path)? .build() .await?; - if !self.is_deck(&proxy).await? { - debug!("Changing CompositeDevice {} into `deck-uhid` type", path); - proxy.set_target_devices(&["deck-uhid"]).await + + let configured_target_devices: Option> = match hardware::device_config().await { + Ok(Some(config)) => config + .inputplumber + .as_ref() + .and_then(|inputplumber_settings| inputplumber_settings.target_devices.clone()), + Ok(None) => { + debug!("No device_config found for inputplumber settings at path: {path}",); + None + } + Err(e) => { + tracing::warn!( + "Failed to load device_config for inputplumber settings at path {path}: {e}", + ); + None + } + }; + + let current_targets = proxy.target_devices().await?; + + if let Some(targets_from_config) = configured_target_devices { + if current_targets != targets_from_config { + let target_devices: Vec<&str> = + targets_from_config.iter().map(AsRef::as_ref).collect(); + debug!("Changing CompositeDevice {path} to configured targets: {target_devices:?}",); + proxy.set_target_devices(&target_devices).await?; + } else { + let target_devices: Vec<&str> = + targets_from_config.iter().map(AsRef::as_ref).collect(); + debug!("CompositeDevice {path} already has configured targets: {target_devices:?}",); + } + } else if !self.is_deck(&proxy).await? { + debug!("CompositeDevice {path} not configured, setting to default 'deck-uhid'",); + proxy.set_target_devices(&["deck-uhid"]).await?; } else { - debug!("CompositeDevice {} is already `deck-uhid` type", path); - Ok(()) + debug!("CompositeDevice {path} not configured, already 'deck-uhid' or custom state",); } + Ok(()) } } diff --git a/src/manager/user.rs b/src/manager/user.rs index 8572e52..fdfb053 100644 --- a/src/manager/user.rs +++ b/src/manager/user.rs @@ -1121,8 +1121,8 @@ mod test { use crate::daemon::user::UserContext; use crate::hardware::test::fake_model; use crate::hardware::{ - BatteryChargeLimitConfig, DeviceConfig, DeviceMatch, DmiMatch, PerformanceProfileConfig, - RangeConfig, SteamDeckVariant, TdpLimitConfig, + BatteryChargeLimitConfig, DeviceConfig, DeviceMatch, DmiMatch, InputPlumberConfig, + PerformanceProfileConfig, RangeConfig, SteamDeckVariant, TdpLimitConfig, }; use crate::platform::{ FormatDeviceConfig, PlatformConfig, ResetConfig, ScriptConfig, ServiceConfig, StorageConfig, @@ -1187,6 +1187,9 @@ mod test { platform_profile_name: String::from("power-driver"), suggested_default: String::from("balanced"), }), + inputplumber: Some(InputPlumberConfig { + target_devices: Some(vec![String::from("deck-uhid")]), + }), }) }