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.
This commit is contained in:
Matthew Schwartz 2025-06-12 22:39:42 -07:00
parent 631f30bc94
commit fcf10c393b
3 changed files with 48 additions and 7 deletions

View file

@ -71,6 +71,7 @@ pub(crate) struct DeviceConfig {
pub gpu_clocks: Option<RangeConfig<u32>>,
pub battery_charge_limit: Option<BatteryChargeLimitConfig>,
pub performance_profile: Option<PerformanceProfileConfig>,
pub inputplumber: Option<InputPlumberConfig>,
}
#[derive(Clone, Deserialize, Debug)]
@ -100,6 +101,11 @@ pub(crate) struct FirmwareAttributeConfig {
pub performance_profile: Option<String>,
}
#[derive(Clone, Deserialize, Debug)]
pub struct InputPlumberConfig {
pub target_devices: Option<Vec<String>>,
}
#[derive(Clone, Deserialize, Debug)]
pub(crate) struct PerformanceProfileConfig {
pub suggested_default: String,

View file

@ -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<Vec<String>> = 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(())
}
}

View file

@ -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")]),
}),
})
}