diff --git a/CHANGELOG.md b/CHANGELOG.md index 68a4bde9..5d794f42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ROGCC: Better handle the use of GPU MUX without supergfxd - ROGCC: Track if reboot required when not using supergfxd - Add env var for logging levels to daemon and gui (`RUST_LOG=`) - +- ROGCC: Very basic support for running a command on AC/Battery switching, this is in config at `~/.config/rog/rog-control-center.cfg`, and for now must be edited by hand and ROGCC restarted (run ROGCC in BG to use effectively) + ## [v4.5.5] ### Changed - remove an unwrap() causing panic on main ROGCC thread diff --git a/rog-control-center/src/config.rs b/rog-control-center/src/config.rs index 98614856..c74c6ced 100644 --- a/rog-control-center/src/config.rs +++ b/rog-control-center/src/config.rs @@ -4,7 +4,6 @@ use std::{ fs::{create_dir, OpenOptions}, io::{Read, Write}, }; -//use log::{error, info, warn}; use crate::{error::Error, update_and_notify::EnabledNotifications}; @@ -12,11 +11,13 @@ const CFG_DIR: &str = "rog"; const CFG_FILE_NAME: &str = "rog-control-center.cfg"; #[derive(Debug, Clone, Deserialize, Serialize)] -#[serde(default)] pub struct Config { pub run_in_background: bool, pub startup_in_background: bool, + pub ac_command: String, + pub bat_command: String, pub enable_notifications: bool, + // This field must be last pub enabled_notifications: EnabledNotifications, } @@ -27,6 +28,8 @@ impl Default for Config { startup_in_background: false, enable_notifications: true, enabled_notifications: EnabledNotifications::default(), + ac_command: String::new(), + bat_command: String::new(), } } } @@ -67,6 +70,9 @@ impl Config { } else if let Ok(data) = toml::from_str::(&buf) { info!("Loaded config file {path:?}"); return Ok(data); + } else if let Ok(data) = toml::from_str::(&buf) { + info!("Loaded old v4.5.5 config file {path:?}"); + return Ok(data.into()); } } Err(Error::ConfigLoadFail) @@ -100,3 +106,24 @@ impl Config { Ok(()) } } + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Config455 { + pub run_in_background: bool, + pub startup_in_background: bool, + pub enable_notifications: bool, + pub enabled_notifications: EnabledNotifications, +} + +impl From for Config { + fn from(c: Config455) -> Self { + Self { + run_in_background: c.run_in_background, + startup_in_background: c.startup_in_background, + enable_notifications: c.enable_notifications, + enabled_notifications: c.enabled_notifications, + ac_command: String::new(), + bat_command: String::new(), + } + } +} diff --git a/rog-control-center/src/main.rs b/rog-control-center/src/main.rs index 98da6909..edbe81b2 100644 --- a/rog-control-center/src/main.rs +++ b/rog-control-center/src/main.rs @@ -118,7 +118,7 @@ fn main() -> Result<()> { Err(_) => on_tmp_dir_exists().unwrap(), }; - let states = setup_page_state_and_notifs(layout, enabled_notifications, &supported)?; + let states = setup_page_state_and_notifs(layout, enabled_notifications, &config, &supported)?; init_tray(supported, states.clone()); @@ -153,6 +153,7 @@ fn main() -> Result<()> { fn setup_page_state_and_notifs( keyboard_layout: KeyLayout, enabled_notifications: Arc>, + config: &Config, supported: &SupportedFunctions, ) -> Result>> { let page_states = Arc::new(Mutex::new(SystemState::new( @@ -161,7 +162,7 @@ fn setup_page_state_and_notifs( supported, )?)); - start_notifications(page_states.clone(), enabled_notifications)?; + start_notifications(config, page_states.clone(), enabled_notifications)?; Ok(page_states) } diff --git a/rog-control-center/src/update_and_notify.rs b/rog-control-center/src/update_and_notify.rs index fc124ae0..22ec4bb1 100644 --- a/rog-control-center/src/update_and_notify.rs +++ b/rog-control-center/src/update_and_notify.rs @@ -24,6 +24,9 @@ use zbus::export::futures_util::{future, StreamExt}; const NOTIF_HEADER: &str = "ROG Control"; +static mut POWER_AC_CMD: Option = None; +static mut POWER_BAT_CMD: Option = None; + #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(default)] pub struct EnabledNotifications { @@ -131,11 +134,36 @@ macro_rules! recv_notif { type SharedHandle = Arc>>; pub fn start_notifications( + config: &Config, page_states: Arc>, enabled_notifications: Arc>, ) -> Result<()> { let last_notification: SharedHandle = Arc::new(Mutex::new(None)); + // Setup the AC/BAT commands that will run on poweer status change + unsafe { + let prog: Vec<&str> = config.ac_command.split_whitespace().collect(); + if prog.len() > 1 { + let mut cmd = Command::new(prog[0]); + + for arg in prog.iter().skip(1) { + cmd.arg(*arg); + } + POWER_AC_CMD = Some(cmd); + } + } + unsafe { + let prog: Vec<&str> = config.bat_command.split_whitespace().collect(); + if prog.len() > 1 { + let mut cmd = Command::new(prog[0]); + + for arg in prog.iter().skip(1) { + cmd.arg(*arg); + } + POWER_BAT_CMD = Some(cmd); + } + } + // BIOS notif recv_notif!( RogBiosProxy, @@ -426,8 +454,22 @@ where fn ac_power_notification(message: &str, on: &bool) -> Result { let data = if *on { + unsafe { + if let Some(cmd) = POWER_AC_CMD.as_mut() { + if let Err(e) = cmd.spawn() { + error!("AC power command error: {e}"); + } + } + } "plugged".to_owned() } else { + unsafe { + if let Some(cmd) = POWER_BAT_CMD.as_mut() { + if let Err(e) = cmd.spawn() { + error!("Battery power command error: {e}"); + } + } + } "unplugged".to_owned() }; Ok(base_notification(message, &data).show()?)