Fix: ROGCC: fix anime matrix settings

This commit is contained in:
Luke D. Jones
2025-01-18 21:27:57 +13:00
parent 9e84997cbf
commit ee9e0a1e31
8 changed files with 201 additions and 136 deletions

View File

@@ -5,6 +5,8 @@
### Changed ### Changed
- Bug fix: UI was setting incorrect value for FPPT - Bug fix: UI was setting incorrect value for FPPT
- Bug fix: Re-add callbacks for the throttle and epp settings in UI - Bug fix: Re-add callbacks for the throttle and epp settings in UI
- Bug fix: Fix UI settigns for AniMe Matrix display
- Bug fix: better handle missing tray (for example gnome)
- Strip out all outdated and unsafe tuning stuff - Strip out all outdated and unsafe tuning stuff
## [v6.1.0-rc3] ## [v6.1.0-rc3]

2
Cargo.lock generated
View File

@@ -179,7 +179,9 @@ name = "asusctl"
version = "6.1.0-rc3" version = "6.1.0-rc3"
dependencies = [ dependencies = [
"dmi_id", "dmi_id",
"env_logger",
"gumdrop", "gumdrop",
"log",
"rog_anime", "rog_anime",
"rog_aura", "rog_aura",
"rog_dbus", "rog_dbus",

View File

@@ -18,10 +18,12 @@ rog_profiles = { path = "../rog-profiles" }
rog_platform = { path = "../rog-platform" } rog_platform = { path = "../rog-platform" }
dmi_id = { path = "../dmi-id" } dmi_id = { path = "../dmi-id" }
log.workspace = true
env_logger.workspace = true
ron.workspace = true ron.workspace = true
gumdrop.workspace = true gumdrop.workspace = true
zbus.workspace = true zbus.workspace = true
[dev-dependencies] [dev-dependencies]
rog_dbus = { path = "../rog-dbus" } rog_dbus = { path = "../rog-dbus" }

View File

@@ -9,6 +9,7 @@ use aura_cli::{LedPowerCommand1, LedPowerCommand2};
use dmi_id::DMIID; use dmi_id::DMIID;
use fan_curve_cli::FanCurveCommand; use fan_curve_cli::FanCurveCommand;
use gumdrop::{Opt, Options}; use gumdrop::{Opt, Options};
use log::error;
use rog_anime::usb::get_anime_type; use rog_anime::usb::get_anime_type;
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2}; use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
use rog_aura::keyboard::{AuraPowerState, LaptopAuraPower}; use rog_aura::keyboard::{AuraPowerState, LaptopAuraPower};
@@ -42,6 +43,14 @@ mod scsi_cli;
mod slash_cli; mod slash_cli;
fn main() { fn main() {
let mut logger = env_logger::Builder::new();
logger
.parse_default_env()
.target(env_logger::Target::Stdout)
.format_timestamp(None)
.filter_level(log::LevelFilter::Debug)
.init();
let self_version = env!("CARGO_PKG_VERSION"); let self_version = env!("CARGO_PKG_VERSION");
println!("Starting version {self_version}"); println!("Starting version {self_version}");
let args: Vec<String> = args().skip(1).collect(); let args: Vec<String> = args().skip(1).collect();
@@ -163,7 +172,7 @@ where
return Ok(ctrl); return Ok(ctrl);
} }
Err("No Aura interface".into()) Err(format!("Did not find {iface_name}").into())
} }
fn do_parsed( fn do_parsed(
@@ -367,7 +376,12 @@ fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
println!("\n{}", lst); println!("\n{}", lst);
} }
} }
let animes = find_iface::<AnimeProxyBlocking>("xyz.ljones.Anime")?;
let animes = find_iface::<AnimeProxyBlocking>("xyz.ljones.Anime").map_err(|e| {
error!("Did not find any interface for xyz.ljones.Anime: {e:?}");
e
})?;
for proxy in animes { for proxy in animes {
if let Some(enable) = cmd.enable_display { if let Some(enable) = cmd.enable_display {
proxy.set_enable_display(enable)?; proxy.set_enable_display(enable)?;

View File

@@ -104,23 +104,28 @@ impl DeviceHandle {
/// Try AniMe Matrix HID. If one exists it is initialsed and returned. /// Try AniMe Matrix HID. If one exists it is initialsed and returned.
pub async fn maybe_anime_hid( pub async fn maybe_anime_hid(
device: Arc<Mutex<HidRaw>>, _device: Arc<Mutex<HidRaw>>,
prod_id: &str _prod_id: &str
) -> Result<Self, RogError> { ) -> Result<Self, RogError> {
debug!("Testing for HIDRAW AniMe"); // TODO: can't use HIDRAW for anime at the moment
let anime_type = AnimeType::from_dmi(); Err(RogError::NotFound(
dbg!(prod_id); "Can't use anime over hidraw yet. Skip.".to_string()
if matches!(anime_type, AnimeType::Unsupported) || prod_id != "193b" { ))
log::info!("Unknown or invalid AniMe: {prod_id:?}, skipping");
return Err(RogError::NotFound("No anime-matrix device".to_string()));
}
info!("Found AniMe Matrix HIDRAW {anime_type:?}: {prod_id}");
let mut config = AniMeConfig::new().load(); // debug!("Testing for HIDRAW AniMe");
config.anime_type = anime_type; // let anime_type = AnimeType::from_dmi();
let mut anime = AniMe::new(Some(device), None, Arc::new(Mutex::new(config))); // dbg!(prod_id);
anime.do_initialization().await?; // if matches!(anime_type, AnimeType::Unsupported) || prod_id != "193b"
Ok(Self::AniMe(anime)) // { log::info!("Unknown or invalid AniMe: {prod_id:?},
// skipping"); return Err(RogError::NotFound("No
// anime-matrix device".to_string())); }
// info!("Found AniMe Matrix HIDRAW {anime_type:?}: {prod_id}");
// let mut config = AniMeConfig::new().load();
// config.anime_type = anime_type;
// let mut anime = AniMe::new(Some(device), None,
// Arc::new(Mutex::new(config))); anime.do_initialization().
// await?; Ok(Self::AniMe(anime))
} }
pub async fn maybe_anime_usb() -> Result<Self, RogError> { pub async fn maybe_anime_usb() -> Result<Self, RogError> {

View File

@@ -24,7 +24,7 @@ struct Icons {
rog_red: Icon, rog_red: Icon,
rog_green: Icon, rog_green: Icon,
rog_white: Icon, rog_white: Icon,
gpu_integrated: Icon, gpu_integrated: Icon
} }
static ICONS: OnceLock<Icons> = OnceLock::new(); static ICONS: OnceLock<Icons> = OnceLock::new();
@@ -48,14 +48,14 @@ fn read_icon(file: &Path) -> Icon {
Icon { Icon {
width: width as i32, width: width as i32,
height: height as i32, height: height as i32,
data: img.into_raw(), data: img.into_raw()
} }
} }
struct AsusTray { struct AsusTray {
current_title: String, current_title: String,
current_icon: Icon, current_icon: Icon,
proxy: ROGCCZbusProxyBlocking<'static>, proxy: ROGCCZbusProxyBlocking<'static>
} }
impl ksni::Tray for AsusTray { impl ksni::Tray for AsusTray {
@@ -103,7 +103,7 @@ async fn set_tray_icon_and_tip(
mode: GfxMode, mode: GfxMode,
power: GfxPower, power: GfxPower,
tray: &mut Handle<AsusTray>, tray: &mut Handle<AsusTray>,
supergfx_active: bool, supergfx_active: bool
) { ) {
if let Some(icons) = ICONS.get() { if let Some(icons) = ICONS.get() {
let icon = match power { let icon = match power {
@@ -162,7 +162,7 @@ pub fn init_tray(_supported_properties: Vec<Properties>, config: Arc<Mutex<Confi
let tray_init = AsusTray { let tray_init = AsusTray {
current_title: TRAY_LABEL.to_string(), current_title: TRAY_LABEL.to_string(),
current_icon: rog_red.clone(), current_icon: rog_red.clone(),
proxy, proxy
}; };
// TODO: return an error to the UI // TODO: return an error to the UI
@@ -187,7 +187,7 @@ pub fn init_tray(_supported_properties: Vec<Properties>, config: Arc<Mutex<Confi
rog_red: rog_red.clone(), rog_red: rog_red.clone(),
rog_green, rog_green,
rog_white, rog_white,
gpu_integrated, gpu_integrated
}); });
let mut has_supergfx = false; let mut has_supergfx = false;
@@ -208,7 +208,7 @@ pub fn init_tray(_supported_properties: Vec<Properties>, config: Arc<Mutex<Confi
} }
} }
} }
Err(e) => warn!("Couldn't get mode form supergfxd: {e:?}"), Err(e) => warn!("Couldn't get mode form supergfxd: {e:?}")
} }
info!("Started ROGTray"); info!("Started ROGTray");

View File

@@ -1,7 +1,8 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use log::{error, info, warn}; use log::{error, info};
use rog_anime::Animations; use rog_anime::Animations;
use rog_dbus::find_iface_async;
use rog_dbus::zbus_anime::AnimeProxy; use rog_dbus::zbus_anime::AnimeProxy;
use slint::ComponentHandle; use slint::ComponentHandle;
@@ -12,124 +13,123 @@ use crate::{set_ui_callbacks, set_ui_props_async, AnimePageData, MainWindow};
pub fn setup_anime_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) { pub fn setup_anime_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
let handle = ui.as_weak(); let handle = ui.as_weak();
tokio::spawn(async move { tokio::spawn(async move {
let Ok(conn) = zbus::Connection::system().await.map_err(|e| warn!("{e:}")) else { let Ok(animes) = find_iface_async::<AnimeProxy>("xyz.ljones.Anime").await else {
return; info!("This device appears to have no aura interfaces");
};
let Ok(anime) = AnimeProxy::new(&conn).await.map_err(|e| warn!("{e:}")) else {
info!("This device may not have an AniMe. If not then the error can be ignored");
return; return;
}; };
set_ui_props_async!(handle, anime, AnimePageData, brightness); for anime in animes {
set_ui_props_async!(handle, anime, AnimePageData, builtins_enabled); set_ui_props_async!(handle, anime, AnimePageData, brightness);
set_ui_props_async!(handle, anime, AnimePageData, enable_display); set_ui_props_async!(handle, anime, AnimePageData, builtins_enabled);
set_ui_props_async!(handle, anime, AnimePageData, off_when_lid_closed); set_ui_props_async!(handle, anime, AnimePageData, enable_display);
set_ui_props_async!(handle, anime, AnimePageData, off_when_suspended); set_ui_props_async!(handle, anime, AnimePageData, off_when_lid_closed);
set_ui_props_async!(handle, anime, AnimePageData, off_when_unplugged); set_ui_props_async!(handle, anime, AnimePageData, off_when_suspended);
set_ui_props_async!(handle, anime, AnimePageData, off_when_unplugged);
let builtins = anime.builtin_animations().await.unwrap_or_default(); let builtins = anime.builtin_animations().await.unwrap_or_default();
handle handle
.upgrade_in_event_loop(move |handle| { .upgrade_in_event_loop(move |handle| {
{ {
let global = handle.global::<AnimePageData>(); let global = handle.global::<AnimePageData>();
global.set_boot_anim(builtins.boot as i32); global.set_boot_anim(builtins.boot as i32);
global.set_awake_anim(builtins.awake as i32); global.set_awake_anim(builtins.awake as i32);
global.set_sleep_anim(builtins.sleep as i32); global.set_sleep_anim(builtins.sleep as i32);
global.set_shutdown_anim(builtins.shutdown as i32); global.set_shutdown_anim(builtins.shutdown as i32);
let handle_copy = handle.as_weak(); let handle_copy = handle.as_weak();
let anime_copy = anime.clone(); let anime_copy = anime.clone();
global.on_cb_builtin_animations(move |boot, awake, sleep, shutdown| { global.on_cb_builtin_animations(move |boot, awake, sleep, shutdown| {
let handle_copy = handle_copy.clone(); let handle_copy = handle_copy.clone();
let anime_copy = anime_copy.clone(); let anime_copy = anime_copy.clone();
tokio::spawn(async move { tokio::spawn(async move {
show_toast( show_toast(
"Anime builtin animations changed".into(), "Anime builtin animations changed".into(),
"Failed to set Anime builtin animations".into(), "Failed to set Anime builtin animations".into(),
handle_copy, handle_copy,
anime_copy anime_copy
.set_builtin_animations(Animations { .set_builtin_animations(Animations {
boot: boot.into(), boot: boot.into(),
awake: awake.into(), awake: awake.into(),
sleep: sleep.into(), sleep: sleep.into(),
shutdown: shutdown.into() shutdown: shutdown.into()
}) })
.await .await
); );
});
}); });
});
let handle_copy = handle.as_weak(); let handle_copy = handle.as_weak();
let anime_copy = anime.clone(); let anime_copy = anime.clone();
tokio::spawn(async move { tokio::spawn(async move {
let mut x = anime_copy.receive_builtin_animations_changed().await; let mut x = anime_copy.receive_builtin_animations_changed().await;
use zbus::export::futures_util::StreamExt; use zbus::export::futures_util::StreamExt;
while let Some(e) = x.next().await { while let Some(e) = x.next().await {
if let Ok(out) = e.get().await { if let Ok(out) = e.get().await {
handle_copy handle_copy
.upgrade_in_event_loop(move |handle| { .upgrade_in_event_loop(move |handle| {
handle handle
.global::<AnimePageData>() .global::<AnimePageData>()
.set_boot_anim(out.boot.into()); .set_boot_anim(out.boot.into());
handle handle
.global::<AnimePageData>() .global::<AnimePageData>()
.set_awake_anim(out.awake.into()); .set_awake_anim(out.awake.into());
handle handle
.global::<AnimePageData>() .global::<AnimePageData>()
.set_sleep_anim(out.sleep.into()); .set_sleep_anim(out.sleep.into());
handle handle
.global::<AnimePageData>() .global::<AnimePageData>()
.set_shutdown_anim(out.shutdown.into()); .set_shutdown_anim(out.shutdown.into());
}) })
.ok(); .ok();
}
} }
} });
}); }
}
set_ui_callbacks!(handle, set_ui_callbacks!(handle,
AnimePageData(.into()), AnimePageData(.into()),
anime.brightness(.into()), anime.brightness(.into()),
"Anime LED brightness successfully set to {}", "Anime LED brightness successfully set to {}",
"Setting Anime LED brightness failed" "Setting Anime LED brightness failed"
); );
set_ui_callbacks!( set_ui_callbacks!(
handle, handle,
AnimePageData(), AnimePageData(),
anime.builtins_enabled(), anime.builtins_enabled(),
"Keyboard LED mode successfully set to {}", "Keyboard LED mode successfully set to {}",
"Setting keyboard LEDmode failed" "Setting keyboard LEDmode failed"
); );
set_ui_callbacks!( set_ui_callbacks!(
handle, handle,
AnimePageData(), AnimePageData(),
anime.enable_display(), anime.enable_display(),
"Anime display successfully set to {}", "Anime display successfully set to {}",
"Setting Anime display failed" "Setting Anime display failed"
); );
set_ui_callbacks!( set_ui_callbacks!(
handle, handle,
AnimePageData(), AnimePageData(),
anime.off_when_lid_closed(), anime.off_when_lid_closed(),
"Anime off_when_lid_closed successfully set to {}", "Anime off_when_lid_closed successfully set to {}",
"Setting Anime off_when_lid_closed failed" "Setting Anime off_when_lid_closed failed"
); );
set_ui_callbacks!( set_ui_callbacks!(
handle, handle,
AnimePageData(), AnimePageData(),
anime.off_when_suspended(), anime.off_when_suspended(),
"Anime off_when_suspended successfully set to {}", "Anime off_when_suspended successfully set to {}",
"Setting Anime off_when_suspended failed" "Setting Anime off_when_suspended failed"
); );
set_ui_callbacks!( set_ui_callbacks!(
handle, handle,
AnimePageData(), AnimePageData(),
anime.off_when_unplugged(), anime.off_when_unplugged(),
"Anime off_when_unplugged successfully set to {}", "Anime off_when_unplugged successfully set to {}",
"Setting Anime off_when_unplugged failed" "Setting Anime off_when_unplugged failed"
); );
}) })
.map_err(|e| error!("setup_anime_page: upgrade_in_event_loop: {e:?}")) .map_err(|e| error!("setup_anime_page: upgrade_in_event_loop: {e:?}"))
.ok(); .ok();
}
}); });
} }

View File

@@ -1,4 +1,5 @@
pub use asusd::{DBUS_IFACE, DBUS_NAME, DBUS_PATH}; pub use asusd::{DBUS_IFACE, DBUS_NAME, DBUS_PATH};
use zbus::proxy::ProxyImpl;
pub mod asus_armoury; pub mod asus_armoury;
pub mod scsi_aura; pub mod scsi_aura;
@@ -50,3 +51,42 @@ pub async fn has_iface(iface: &str) -> Result<bool, Box<dyn std::error::Error>>
} }
Ok(false) Ok(false)
} }
pub async fn find_iface_async<T>(iface_name: &str) -> Result<Vec<T>, Box<dyn std::error::Error>>
where
T: ProxyImpl<'static> + From<zbus::Proxy<'static>>
{
let conn = zbus::Connection::system().await?;
let f = zbus::fdo::ObjectManagerProxy::new(&conn, "xyz.ljones.Asusd", "/").await?;
let interfaces = f.get_managed_objects().await?;
let mut paths = Vec::new();
for v in interfaces.iter() {
// let o: Vec<zbus::names::OwnedInterfaceName> = v.1.keys().map(|e|
// e.to_owned()).collect(); println!("{}, {:?}", v.0, o);
for k in v.1.keys() {
if k.as_str() == iface_name {
// println!("Found {iface_name} device at {}, {}", v.0, k);
paths.push(v.0.clone());
}
}
}
if paths.len() > 1 {
println!("Multiple asusd interfaces devices found");
}
if !paths.is_empty() {
let mut ctrl = Vec::new();
paths.sort_by(|a, b| a.cmp(b));
for path in paths {
ctrl.push(
T::builder(&conn)
.path(path.clone())?
.destination("xyz.ljones.Asusd")?
.build()
.await?
);
}
return Ok(ctrl);
}
Err(format!("Did not find {iface_name}").into())
}