More updating to zbus 4.0.1

This commit is contained in:
Luke D. Jones
2024-02-22 23:49:35 +13:00
parent a44145f487
commit 8e4b7d53f4
50 changed files with 3151 additions and 2932 deletions

2628
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,39 @@
[workspace]
members = ["asusctl", "asusd", "asusd-user", "config-traits", "cpuctl", "dmi-id", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center", "simulators"]
default-members = ["asusctl", "asusd", "asusd-user", "cpuctl", "rog-control-center"]
members = [
"asusctl",
"asusd",
"asusd-user",
"config-traits",
"cpuctl",
"dmi-id",
"rog-platform",
"rog-dbus",
"rog-anime",
"rog-aura",
"rog-profiles",
"rog-control-center",
"simulators",
]
default-members = [
"asusctl",
"asusd",
"asusd-user",
"cpuctl",
"rog-control-center",
]
resolver = "2"
[workspace.package]
version = "5.0.8"
rust-version = "1.75"
rust-version = "1.76"
[workspace.dependencies]
tokio = { version = "^1.23.0", default-features = false, features = ["macros", "sync"]}
tokio = { version = "^1.23.0", default-features = false, features = [
"macros",
"sync",
"time",
"rt",
] }
concat-idents = "^1.1"
dirs = "^4.0"
smol = "^1.3"
@@ -39,7 +64,9 @@ gif = "^0.12.0"
versions = "4.1"
notify-rust = { git = "https://github.com/flukejones/notify-rust.git", rev = "54176413b81189a3e4edbdc20a0b4f7e2e35c063", default-features = false, features = ["z"] }
notify-rust = { git = "https://github.com/flukejones/notify-rust.git", rev = "54176413b81189a3e4edbdc20a0b4f7e2e35c063", default-features = false, features = [
"z",
] }
[profile.release]
# thin = 57s, asusd = 9.0M
@@ -61,4 +88,4 @@ opt-level = 3
[workspace.dependencies.cargo-husky]
version = "1"
default-features = false
features = ["user-hooks"]
features = ["user-hooks"]

View File

@@ -16,12 +16,13 @@ dmi_id = { path = "../dmi-id" }
gumdrop.workspace = true
toml.workspace = true
zbus.workspace = true
[dev-dependencies]
gif.workspace = true
tinybmp.workspace = true
glam.workspace = true
rog_dbus = { path = "../rog-dbus" }
tokio = { version = "^1.23.0", default-features = false, features = ["macros", "sync", "rt", "time"]}
tokio.workspace = true
cargo-husky.workspace = true

View File

@@ -9,7 +9,7 @@ use rog_anime::error::AnimeError;
use rog_anime::{ActionData, ActionLoader, AnimTime, Fade, Sequences, Vec2};
use rog_dbus::RogDbusClientBlocking;
use serde_derive::{Deserialize, Serialize};
use zbus::dbus_interface;
use zbus::interface;
use zbus::zvariant::{ObjectPath, Type};
use crate::config::ConfigAnime;
@@ -175,7 +175,7 @@ impl CtrlAnime<'static> {
// - Do actions
// - Write config if required
// - Unset inner_early_return
#[dbus_interface(name = "org.asuslinux.Daemon")]
#[interface(name = "org.asuslinux.Daemon")]
impl CtrlAnime<'static> {
pub fn insert_asus_gif(
&mut self,

View File

@@ -21,9 +21,9 @@
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
#![allow(clippy::too_many_arguments)]
use zbus::dbus_proxy;
use zbus::proxy;
#[dbus_proxy(
#[proxy(
interface = "org.asuslinux.Daemon",
default_path = "/org/asuslinux/Anime"
)]

View File

@@ -10,7 +10,7 @@ use rog_anime::usb::{
};
use rog_anime::{Animations, AnimeDataBuffer, DeviceState};
use zbus::export::futures_util::lock::Mutex;
use zbus::{dbus_interface, CacheProperties, Connection, SignalContext};
use zbus::{interface, CacheProperties, Connection, SignalContext};
use super::CtrlAnime;
use crate::error::RogError;
@@ -43,7 +43,7 @@ impl crate::ZbusRun for CtrlAnimeZbus {
// None of these calls can be guarnateed to succeed unless we loop until okay
// If the try_lock *does* succeed then any other thread trying to lock will not
// grab it until we finish.
#[dbus_interface(name = "org.asuslinux.Daemon")]
#[interface(name = "org.asuslinux.Daemon")]
impl CtrlAnimeZbus {
/// Writes a data stream of length. Will force system thread to exit until
/// it is restarted
@@ -58,14 +58,14 @@ impl CtrlAnimeZbus {
}
/// Set base brightness level
#[dbus_interface(property)]
#[zbus(property)]
async fn brightness(&self) -> Brightness {
let lock = self.0.lock().await;
lock.config.display_brightness
}
/// Set base brightness level
#[dbus_interface(property)]
#[zbus(property)]
async fn set_brightness(&self, brightness: Brightness) {
let mut lock = self.0.lock().await;
lock.node
@@ -86,7 +86,7 @@ impl CtrlAnimeZbus {
lock.config.write();
}
#[dbus_interface(property)]
#[zbus(property)]
async fn builtins_enabled(&self) -> bool {
let lock = self.0.lock().await;
lock.config.builtin_anims_enabled
@@ -94,7 +94,7 @@ impl CtrlAnimeZbus {
/// Enable the builtin animations or not. This is quivalent to "Powersave
/// animations" in Armory crate
#[dbus_interface(property)]
#[zbus(property)]
async fn set_builtins_enabled(&self, enabled: bool) {
let mut lock = self.0.lock().await;
lock.node
@@ -125,14 +125,14 @@ impl CtrlAnimeZbus {
}
}
#[dbus_interface(property)]
#[zbus(property)]
async fn builtin_animations(&self) -> Animations {
let lock = self.0.lock().await;
lock.config.builtin_anims
}
/// Set which builtin animation is used for each stage
#[dbus_interface(property)]
#[zbus(property)]
async fn set_builtin_animations(&self, settings: Animations) {
let mut lock = self.0.lock().await;
lock.node
@@ -157,14 +157,14 @@ impl CtrlAnimeZbus {
lock.config.write();
}
#[dbus_interface(property)]
#[zbus(property)]
async fn enable_display(&self) -> bool {
let lock = self.0.lock().await;
lock.config.display_enabled
}
/// Set whether the AniMe is enabled at all
#[dbus_interface(property)]
#[zbus(property)]
async fn set_enable_display(&self, enabled: bool) {
let mut lock = self.0.lock().await;
lock.node
@@ -177,14 +177,14 @@ impl CtrlAnimeZbus {
lock.config.write();
}
#[dbus_interface(property)]
#[zbus(property)]
async fn off_when_unplugged(&self) -> bool {
let lock = self.0.lock().await;
lock.config.off_when_unplugged
}
/// Set if to turn the AniMe Matrix off when external power is unplugged
#[dbus_interface(property)]
#[zbus(property)]
async fn set_off_when_unplugged(&self, enabled: bool) {
let mut lock = self.0.lock().await;
let manager = get_logind_manager().await;
@@ -201,28 +201,28 @@ impl CtrlAnimeZbus {
lock.config.write();
}
#[dbus_interface(property)]
#[zbus(property)]
async fn off_when_suspended(&self) -> bool {
let lock = self.0.lock().await;
lock.config.off_when_suspended
}
/// Set if to turn the AniMe Matrix off when the laptop is suspended
#[dbus_interface(property)]
#[zbus(property)]
async fn set_off_when_suspended(&self, enabled: bool) {
let mut lock = self.0.lock().await;
lock.config.off_when_suspended = enabled;
lock.config.write();
}
#[dbus_interface(property)]
#[zbus(property)]
async fn off_when_lid_closed(&self) -> bool {
let lock = self.0.lock().await;
lock.config.off_when_lid_closed
}
/// Set if to turn the AniMe Matrix off when the lid is closed
#[dbus_interface(property)]
#[zbus(property)]
async fn set_off_when_lid_closed(&self, enabled: bool) {
let mut lock = self.0.lock().await;
let manager = get_logind_manager().await;
@@ -250,7 +250,7 @@ impl CtrlAnimeZbus {
}
/// Get the device state as stored by asusd
// #[dbus_interface(property)]
// #[zbus(property)]
async fn device_state(&self) -> DeviceState {
let lock = self.0.lock().await;
DeviceState::from(&lock.config)

View File

@@ -10,7 +10,7 @@ use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness};
use zbus::export::futures_util::lock::{Mutex, MutexGuard};
use zbus::export::futures_util::StreamExt;
use zbus::fdo::Error as ZbErr;
use zbus::{dbus_interface, Connection, SignalContext};
use zbus::{interface, Connection, SignalContext};
use super::controller::CtrlKbdLed;
use crate::error::RogError;
@@ -41,31 +41,31 @@ impl crate::ZbusRun for CtrlAuraZbus {
/// The main interface for changing, reading, or notfying signals
///
/// LED commands are split between Brightness, Modes, Per-Key
#[dbus_interface(name = "org.asuslinux.Daemon")]
#[interface(name = "org.asuslinux.Daemon")]
impl CtrlAuraZbus {
/// Return the device type for this Aura keyboard
#[dbus_interface(property)]
#[zbus(property)]
async fn device_type(&self) -> AuraDevice {
let ctrl = self.0.lock().await;
ctrl.led_prod
}
/// Return the current LED brightness
#[dbus_interface(property)]
#[zbus(property)]
async fn brightness(&self) -> Result<LedBrightness, ZbErr> {
let ctrl = self.0.lock().await;
Ok(ctrl.sysfs_node.get_brightness().map(|n| n.into())?)
}
/// Set the keyboard brightness level (0-3)
#[dbus_interface(property)]
#[zbus(property)]
async fn set_brightness(&mut self, brightness: LedBrightness) -> Result<(), ZbErr> {
let ctrl = self.0.lock().await;
Ok(ctrl.sysfs_node.set_brightness(brightness.into())?)
}
/// Total levels of brightness available
#[dbus_interface(property)]
#[zbus(property)]
async fn supported_brightness(&self) -> Vec<LedBrightness> {
vec![
LedBrightness::Off,
@@ -76,26 +76,26 @@ impl CtrlAuraZbus {
}
/// The total available modes
#[dbus_interface(property)]
#[zbus(property)]
async fn supported_basic_modes(&self) -> Result<Vec<AuraModeNum>, ZbErr> {
let ctrl = self.0.lock().await;
Ok(ctrl.config.builtins.keys().cloned().collect())
}
#[dbus_interface(property)]
#[zbus(property)]
async fn supported_basic_zones(&self) -> Result<Vec<AuraZone>, ZbErr> {
let ctrl = self.0.lock().await;
Ok(ctrl.supported_data.basic_zones.clone())
}
#[dbus_interface(property)]
#[zbus(property)]
async fn supported_power_zones(&self) -> Result<Vec<PowerZones>, ZbErr> {
let ctrl = self.0.lock().await;
Ok(ctrl.supported_data.power_zones.clone())
}
/// The current mode data
#[dbus_interface(property)]
#[zbus(property)]
async fn led_mode(&self) -> Result<AuraModeNum, ZbErr> {
let ctrl = self.0.lock().await;
Ok(ctrl.config.current_mode)
@@ -105,7 +105,7 @@ impl CtrlAuraZbus {
///
/// On success the aura config file is read to refresh cached values, then
/// the effect is stored and config written to disk.
#[dbus_interface(property)]
#[zbus(property)]
async fn set_led_mode(&mut self, num: AuraModeNum) -> Result<(), ZbErr> {
let mut ctrl = self.0.lock().await;
ctrl.config.current_mode = num;
@@ -120,7 +120,7 @@ impl CtrlAuraZbus {
}
/// The current mode data
#[dbus_interface(property)]
#[zbus(property)]
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
let ctrl = self.0.lock().await;
let mode = ctrl.config.current_mode;
@@ -134,7 +134,7 @@ impl CtrlAuraZbus {
///
/// On success the aura config file is read to refresh cached values, then
/// the effect is stored and config written to disk.
#[dbus_interface(property)]
#[zbus(property)]
async fn set_led_mode_data(&mut self, effect: AuraEffect) -> Result<(), ZbErr> {
let mut ctrl = self.0.lock().await;
if !ctrl.supported_data.basic_modes.contains(&effect.mode)
@@ -164,7 +164,7 @@ impl CtrlAuraZbus {
}
// As property doesn't work for AuraPowerDev (complexity of serialization?)
#[dbus_interface(property)]
#[zbus(property)]
async fn led_power(&self) -> AuraPowerDev {
let ctrl = self.0.lock().await;
AuraPowerDev::from(&ctrl.config.enabled)
@@ -174,7 +174,7 @@ impl CtrlAuraZbus {
/// `enabled` sets if the sent array should be disabled or enabled
///
/// For Modern ROG devices the "enabled" flag is ignored.
#[dbus_interface(property)]
#[zbus(property)]
async fn set_led_power(&mut self, options: (AuraPowerDev, bool)) -> Result<(), ZbErr> {
let enabled = options.1;
let options = options.0;

View File

@@ -10,7 +10,7 @@ use rog_profiles::fan_curve_set::CurveData;
use rog_profiles::{find_fan_curve_node, FanCurvePU, FanCurveProfiles};
use serde_derive::{Deserialize, Serialize};
use tokio::sync::Mutex;
use zbus::{dbus_interface, Connection, SignalContext};
use zbus::{interface, Connection, SignalContext};
use crate::error::RogError;
use crate::{CtrlTask, CONFIG_PATH_BASE};
@@ -123,7 +123,7 @@ impl CtrlFanCurveZbus {
}
}
#[dbus_interface(name = "org.asuslinux.Daemon")]
#[interface(name = "org.asuslinux.Daemon")]
impl CtrlFanCurveZbus {
/// Set all fan curves for a profile to enabled status. Will also activate a
/// fan curve if in the same profile mode

View File

@@ -9,7 +9,7 @@ use rog_platform::platform::{GpuMode, Properties, RogPlatform, ThrottlePolicy};
use rog_platform::power::AsusPower;
use zbus::export::futures_util::lock::Mutex;
use zbus::fdo::Error as FdoErr;
use zbus::{dbus_interface, Connection, ObjectServer, SignalContext};
use zbus::{interface, Connection, ObjectServer, SignalContext};
use crate::config::Config;
use crate::ctrl_anime::trait_impls::{CtrlAnimeZbus, ANIME_ZBUS_NAME, ANIME_ZBUS_PATH};
@@ -285,7 +285,7 @@ impl CtrlPlatform {
}
}
#[dbus_interface(name = "org.asuslinux.Daemon")]
#[interface(name = "org.asuslinux.Daemon")]
impl CtrlPlatform {
/// Returns a list of property names that this system supports
async fn supported_properties(&self) -> Vec<Properties> {
@@ -372,13 +372,13 @@ impl CtrlPlatform {
interfaces
}
#[dbus_interface(property)]
#[zbus(property)]
fn charge_control_end_threshold(&self) -> Result<u8, FdoErr> {
let limit = self.power.get_charge_control_end_threshold()?;
Ok(limit)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_charge_control_end_threshold(&mut self, limit: u8) -> Result<(), FdoErr> {
if !(20..=100).contains(&limit) {
return Err(RogError::ChargeLimit(limit))?;
@@ -388,7 +388,7 @@ impl CtrlPlatform {
Ok(())
}
#[dbus_interface(property)]
#[zbus(property)]
fn gpu_mux_mode(&self) -> Result<u8, FdoErr> {
self.platform.get_gpu_mux_mode().map_err(|err| {
warn!("RogPlatform: set_gpu_mux_mode {err}");
@@ -396,7 +396,7 @@ impl CtrlPlatform {
})
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_gpu_mux_mode(&mut self, mode: u8) -> Result<(), FdoErr> {
if self.platform.has_gpu_mux_mode() {
self.set_gfx_mode(mode.into()).map_err(|err| {
@@ -439,13 +439,13 @@ impl CtrlPlatform {
}
}
#[dbus_interface(property)]
#[zbus(property)]
fn throttle_thermal_policy(&self) -> Result<ThrottlePolicy, FdoErr> {
platform_get_value!(self, throttle_thermal_policy, "throttle_thermal_policy")
.map(|n| n.into())
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_throttle_thermal_policy(&mut self, policy: ThrottlePolicy) -> Result<(), FdoErr> {
// TODO: watch for external changes
if self.platform.has_throttle_thermal_policy() {
@@ -465,23 +465,23 @@ impl CtrlPlatform {
}
}
#[dbus_interface(property)]
#[zbus(property)]
async fn throttle_policy_linked_epp(&self) -> Result<bool, FdoErr> {
Ok(self.config.lock().await.throttle_policy_linked_epp)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_throttle_policy_linked_epp(&self, linked: bool) -> Result<(), zbus::Error> {
self.config.lock().await.throttle_policy_linked_epp = linked;
Ok(())
}
#[dbus_interface(property)]
#[zbus(property)]
async fn throttle_policy_on_battery(&self) -> Result<ThrottlePolicy, FdoErr> {
Ok(self.config.lock().await.throttle_policy_on_battery)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_throttle_policy_on_battery(
&mut self,
policy: ThrottlePolicy,
@@ -491,12 +491,12 @@ impl CtrlPlatform {
Ok(())
}
#[dbus_interface(property)]
#[zbus(property)]
async fn throttle_policy_on_ac(&self) -> Result<ThrottlePolicy, FdoErr> {
Ok(self.config.lock().await.throttle_policy_on_ac)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_throttle_policy_on_ac(&mut self, policy: ThrottlePolicy) -> Result<(), FdoErr> {
self.config.lock().await.throttle_policy_on_ac = policy;
self.set_throttle_thermal_policy(policy).await?;
@@ -505,12 +505,12 @@ impl CtrlPlatform {
/// The energy_performance_preference for the quiet throttle/platform
/// profile
#[dbus_interface(property)]
#[zbus(property)]
async fn throttle_quiet_epp(&self) -> Result<CPUEPP, FdoErr> {
Ok(self.config.lock().await.throttle_quiet_epp)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_throttle_quiet_epp(&mut self, epp: CPUEPP) -> Result<(), FdoErr> {
let change_pp = self.config.lock().await.throttle_policy_linked_epp;
self.config.lock().await.throttle_quiet_epp = epp;
@@ -520,12 +520,12 @@ impl CtrlPlatform {
/// The energy_performance_preference for the balanced throttle/platform
/// profile
#[dbus_interface(property)]
#[zbus(property)]
async fn throttle_balanced_epp(&self) -> Result<CPUEPP, FdoErr> {
Ok(self.config.lock().await.throttle_balanced_epp)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_throttle_balanced_epp(&mut self, epp: CPUEPP) -> Result<(), FdoErr> {
let change_pp = self.config.lock().await.throttle_policy_linked_epp;
self.config.lock().await.throttle_balanced_epp = epp;
@@ -535,12 +535,12 @@ impl CtrlPlatform {
/// The energy_performance_preference for the performance throttle/platform
/// profile
#[dbus_interface(property)]
#[zbus(property)]
async fn throttle_performance_epp(&self) -> Result<CPUEPP, FdoErr> {
Ok(self.config.lock().await.throttle_performance_epp)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_throttle_performance_epp(&mut self, epp: CPUEPP) -> Result<(), FdoErr> {
let change_pp = self.config.lock().await.throttle_policy_linked_epp;
self.config.lock().await.throttle_performance_epp = epp;
@@ -550,12 +550,12 @@ impl CtrlPlatform {
/// ***********************************************************************
#[dbus_interface(property)]
#[zbus(property)]
fn post_animation_sound(&self) -> Result<bool, FdoErr> {
platform_get_value!(self, post_animation_sound, "post_animation_sound")
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_post_animation_sound(&mut self, on: bool) -> Result<(), FdoErr> {
if self.platform.has_post_animation_sound() {
self.platform.set_post_animation_sound(on).map_err(|err| {
@@ -571,34 +571,34 @@ impl CtrlPlatform {
/// Get the `panel_od` value from platform. Updates the stored value in
/// internal config also.
#[dbus_interface(property)]
#[zbus(property)]
fn panel_od(&self) -> Result<bool, FdoErr> {
platform_get_value!(self, panel_od, "panel_od")
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_panel_od(&mut self, overdrive: bool) -> Result<(), FdoErr> {
platform_set_bool!(self, panel_od, "panel_od", overdrive)
}
/// Get the `panel_od` value from platform. Updates the stored value in
/// internal config also.
#[dbus_interface(property)]
#[zbus(property)]
fn mini_led_mode(&self) -> Result<bool, FdoErr> {
platform_get_value!(self, mini_led_mode, "mini_led_mode")
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_mini_led_mode(&mut self, on: bool) -> Result<(), FdoErr> {
platform_set_bool!(self, mini_led_mode, "mini_led_mode", on)
}
#[dbus_interface(property)]
#[zbus(property)]
fn dgpu_disable(&self) -> Result<bool, FdoErr> {
platform_get_value!(self, dgpu_disable, "dgpu_disable")
}
#[dbus_interface(property)]
#[zbus(property)]
fn egpu_enable(&self) -> Result<bool, FdoErr> {
platform_get_value!(self, egpu_enable, "egpu_enable")
}
@@ -607,12 +607,12 @@ impl CtrlPlatform {
/// Set the Package Power Target total of CPU: PL1 on Intel, SPL on AMD.
/// Shown on Intel+Nvidia or AMD+Nvidia based systems:
/// * min=5, max=250
#[dbus_interface(property)]
#[zbus(property)]
async fn ppt_pl1_spl(&self) -> Result<u8, FdoErr> {
platform_get_value_if_some!(self, ppt_pl1_spl, "ppt_pl1_spl", 5)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_ppt_pl1_spl(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, ppt_pl1_spl, "ppt_pl1_spl", value, 5, 250)
}
@@ -620,72 +620,72 @@ impl CtrlPlatform {
/// Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT,
/// on AMD. Shown on Intel+Nvidia or AMD+Nvidia based systems:
/// * min=5, max=250
#[dbus_interface(property)]
#[zbus(property)]
async fn ppt_pl2_sppt(&self) -> Result<u8, FdoErr> {
platform_get_value_if_some!(self, ppt_pl2_sppt, "ppt_pl2_sppt", 5)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_ppt_pl2_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, ppt_pl2_sppt, "ppt_pl2_sppt", value, 5, 250)
}
/// Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only:
/// * min=5, max=250
#[dbus_interface(property)]
#[zbus(property)]
async fn ppt_fppt(&self) -> Result<u8, FdoErr> {
platform_get_value_if_some!(self, ppt_fppt, "ppt_fppt", 5)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_ppt_fppt(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, ppt_fppt, "ppt_fppt", value, 5, 250)
}
/// Set the APU SPPT limit. Shown on full AMD systems only:
/// * min=5, max=130
#[dbus_interface(property)]
#[zbus(property)]
async fn ppt_apu_sppt(&self) -> Result<u8, FdoErr> {
platform_get_value_if_some!(self, ppt_apu_sppt, "ppt_apu_sppt", 5)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_ppt_apu_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, ppt_apu_sppt, "ppt_apu_sppt", value, 5, 130)
}
/// Set the platform SPPT limit. Shown on full AMD systems only:
/// * min=5, max=130
#[dbus_interface(property)]
#[zbus(property)]
async fn ppt_platform_sppt(&self) -> Result<u8, FdoErr> {
platform_get_value_if_some!(self, ppt_platform_sppt, "ppt_platform_sppt", 5)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_ppt_platform_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, ppt_platform_sppt, "ppt_platform_sppt", value, 5, 130)
}
/// Set the dynamic boost limit of the Nvidia dGPU:
/// * min=5, max=25
#[dbus_interface(property)]
#[zbus(property)]
async fn nv_dynamic_boost(&self) -> Result<u8, FdoErr> {
platform_get_value_if_some!(self, nv_dynamic_boost, "nv_dynamic_boost", 5)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_nv_dynamic_boost(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, nv_dynamic_boost, "nv_dynamic_boost", value, 5, 25)
}
/// Set the target temperature limit of the Nvidia dGPU:
/// * min=75, max=87
#[dbus_interface(property)]
#[zbus(property)]
async fn nv_temp_target(&self) -> Result<u8, FdoErr> {
platform_get_value_if_some!(self, nv_temp_target, "nv_temp_target", 5)
}
#[dbus_interface(property)]
#[zbus(property)]
async fn set_nv_temp_target(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, nv_temp_target, "nv_temp_target", value, 5, 87)
}

View File

@@ -123,7 +123,7 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
loop {
// This is just a blocker to idle and ensure the reator reacts
sleep(Duration::from_millis(1000)).await;
connection.executor().tick().await;
}
}

View File

@@ -10,15 +10,9 @@ edition = "2021"
#mocking = []
[dependencies]
# egui = "0.24.1"
# eframe = "0.24.1"
# egui_plot = "0.24.1"
# Stuck on this revision due to crash issues on app close
egui = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"}
eframe = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"}
libappindicator = "0.8" # Tray icon
gtk = "0.16"
libappindicator = "0.9" # Tray icon
gtk = "0.18"
asusd = { path = "../asusd" }
rog_anime = { path = "../rog-anime" }
@@ -48,9 +42,18 @@ versions.workspace = true
nix = "^0.26.1"
tempfile = "3.3.0"
# [patch.crates-io]
# egui = { git = "https://github.com/flukejones/egui" }
# eframe = { git = "https://github.com/flukejones/egui" }
i-slint-backend-selector = { git = "https://github.com/slint-ui/slint.git" }
i-slint-core = { git = "https://github.com/slint-ui/slint.git" }
i-slint-backend-winit = { git = "https://github.com/slint-ui/slint.git" }
winit = "*"
[dependencies.slint]
git = "https://github.com/slint-ui/slint.git"
default-features = false
features = ["std", "compat-1-0", "backend-winit-wayland", "backend-linuxkms", "renderer-femtovg"]
[build-dependencies.slint-build]
git = "https://github.com/slint-ui/slint.git"
[dev-dependencies]
cargo-husky.workspace = true

View File

@@ -0,0 +1,39 @@
use std::path::PathBuf;
use std::str::FromStr;
// use std::fs::OpenOptions;
// use std::io::Write;
// use diter_protocol::ParameterDefinitions;
// use ron::ser::PrettyConfig;
// const LOCALE_EN: &str =
// include_str!("../data/localization/en/parameters.json"); const LOCALE_IT:
// &str = include_str!("../data/localization/it/parameters.json");
// const LOCALE_ZH: &str =
// include_str!("../data/localization/zh/parameters.json");
// fn write_locales() {
// let root = env!("CARGO_MANIFEST_DIR");
// let mut path = PathBuf::from_str(root).unwrap();
// path.push("src/locales.ron");
// let mut file = OpenOptions::new();
// file.truncate(true).create(true).write(true);
// let en: ParameterDefinitions = serde_json::from_str(LOCALE_EN).unwrap();
// let mut writer = file.open(path).unwrap();
// let en = ron::ser::to_string_pretty(&en,
// PrettyConfig::new().depth_limit(4)).unwrap(); writer.write_all(en.
// to_string().as_bytes()).unwrap();
// // let it: ParameterDefinitions =
// serde_json::from_str(LOCALE_IT).unwrap(); // let zh: ParameterDefinitions
// = serde_json::from_str(LOCALE_ZH).unwrap(); }
fn main() {
// write_locales();
let root = env!("CARGO_MANIFEST_DIR");
let mut path = PathBuf::from_str(root).unwrap();
path.push("ui/main_window.slint");
slint_build::compile(path).unwrap();
}

View File

@@ -1,178 +0,0 @@
use std::f64::consts::PI;
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use egui::{Button, RichText};
use rog_aura::layouts::KeyLayout;
use rog_platform::platform::Properties;
use crate::config::Config;
use crate::error::Result;
use crate::system_state::SystemState;
use crate::{Page, RogDbusClientBlocking};
pub struct RogApp {
pub page: Page,
pub states: Arc<Mutex<SystemState>>,
// TODO: can probably just open and read whenever
pub config: Config,
/// Oscillator in percentage
pub oscillator1: Arc<AtomicU8>,
pub oscillator2: Arc<AtomicU8>,
pub oscillator3: Arc<AtomicU8>,
/// Frequency of oscillation
pub oscillator_freq: Arc<AtomicU8>,
/// A toggle that toggles true/false when the oscillator reaches 0
pub oscillator_toggle: Arc<AtomicBool>,
pub supported_interfaces: Vec<String>,
pub supported_properties: Vec<Properties>,
}
impl RogApp {
/// Called once before the first frame.
pub fn new(
config: Config,
states: Arc<Mutex<SystemState>>,
_cc: &eframe::CreationContext<'_>,
) -> Result<Self> {
let (dbus, _) = RogDbusClientBlocking::new()?;
let supported_interfaces = dbus.proxies().platform().supported_interfaces()?;
let supported_properties = dbus.proxies().platform().supported_properties()?;
// Set up an oscillator to run on a thread.
// Helpful for visual effects like colour pulse.
let oscillator1 = Arc::new(AtomicU8::new(0));
let oscillator2 = Arc::new(AtomicU8::new(0));
let oscillator3 = Arc::new(AtomicU8::new(0));
let oscillator1_1 = oscillator1.clone();
let oscillator1_2 = oscillator2.clone();
let oscillator1_3 = oscillator3.clone();
let oscillator_freq = Arc::new(AtomicU8::new(5));
let oscillator_freq1 = oscillator_freq.clone();
let oscillator_toggle = Arc::new(AtomicBool::new(false));
let oscillator_toggle1 = oscillator_toggle.clone();
std::thread::spawn(move || {
let started = Instant::now();
let mut toggled = false;
loop {
let time = started.elapsed();
// 32 = slow, 16 = med, 8 = fast
let scale = oscillator_freq1.load(Ordering::SeqCst) as f64;
let elapsed1 = (time.as_millis() as f64 + 333.0) / 10000.0;
let elapsed2 = (time.as_millis() as f64 + 666.0) / 10000.0;
let elapsed3 = (time.as_millis() as f64 + 999.0) / 10000.0;
let tmp1 = ((scale * elapsed1 * PI).cos()).abs();
let tmp2 = ((scale * 0.85 * elapsed2 * PI).cos()).abs();
let tmp3 = ((scale * 0.7 * elapsed3 * PI).cos()).abs();
if tmp1 <= 0.1 && !toggled {
let s = oscillator_toggle1.load(Ordering::SeqCst);
oscillator_toggle1.store(!s, Ordering::SeqCst);
toggled = true;
} else if tmp1 > 0.9 {
toggled = false;
}
let tmp1 = (255.0 * tmp1 * 100.0 / 255.0) as u8;
let tmp2 = (255.0 * tmp2 * 100.0 / 255.0) as u8;
let tmp3 = (255.0 * tmp3 * 100.0 / 255.0) as u8;
oscillator1_1.store(tmp1, Ordering::SeqCst);
oscillator1_2.store(tmp2, Ordering::SeqCst);
oscillator1_3.store(tmp3, Ordering::SeqCst);
std::thread::sleep(Duration::from_millis(33));
}
});
Ok(Self {
supported_interfaces,
supported_properties,
states,
page: Page::System,
config,
oscillator1,
oscillator2,
oscillator3,
oscillator_toggle,
oscillator_freq,
})
}
}
impl eframe::App for RogApp {
/// Called each time the UI needs repainting, which may be many times per
/// second. Put your widgets into a `SidePanel`, `TopPanel`,
/// `CentralPanel`, `Window` or `Area`.
fn update(&mut self, ctx: &eframe::egui::Context, frame: &mut eframe::Frame) {
let states = self.states.clone();
if let Ok(mut states) = states.try_lock() {
if states.app_should_update {
states.app_should_update = false;
ctx.request_repaint();
}
}
// Shortcut typical display stuff
if let Ok(mut states) = states.try_lock() {
let layout_testing = states.aura_creation.layout_testing.clone();
if let Some(path) = &layout_testing {
let modified = path.metadata().unwrap().modified().unwrap();
if states.aura_creation.layout_last_modified < modified {
states.aura_creation.layout_last_modified = modified;
// time to reload the config
states.aura_creation.keyboard_layout = KeyLayout::from_file(path).unwrap();
}
self.aura_page(&mut states, ctx);
return;
}
self.top_bar(ctx, frame);
self.side_panel(ctx);
}
let page = self.page;
let mut was_error = false;
if let Ok(mut states) = states.try_lock() {
if let Some(err) = states.error.clone() {
was_error = true;
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading(RichText::new("Error!").size(28.0));
ui.centered_and_justified(|ui| {
ui.label(RichText::new(format!("The error was: {:?}", err)).size(22.0));
});
});
egui::TopBottomPanel::bottom("error_bar")
.default_height(26.0)
.show(ctx, |ui| {
ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
if ui
.add(Button::new(RichText::new("Okay").size(20.0)))
.clicked()
{
states.error = None;
}
});
});
}
}
if !was_error {
if let Ok(mut states) = states.try_lock() {
match page {
Page::AppSettings => self.app_settings_page(&mut states, ctx),
Page::System => self.system_page(&mut states, ctx),
Page::AuraEffects => self.aura_page(&mut states, ctx),
Page::AnimeMatrix => self.anime_page(ctx),
Page::FanCurves => self.fan_curve_page(&mut states, ctx),
};
}
}
}
}

View File

@@ -11,7 +11,6 @@ pub enum Error {
XdgVars,
Zbus(zbus::Error),
Notification(notify_rust::error::Error),
Eframe(eframe::Error),
}
impl fmt::Display for Error {
@@ -25,7 +24,6 @@ impl fmt::Display for Error {
Error::XdgVars => write!(f, "XDG environment vars appear unset"),
Error::Zbus(err) => write!(f, "Error: {}", err),
Error::Notification(err) => write!(f, "Notification Error: {}", err),
Error::Eframe(err) => write!(f, "Eframe Error: {}", err),
}
}
}
@@ -55,9 +53,3 @@ impl From<notify_rust::error::Error> for Error {
Error::Notification(err)
}
}
impl From<eframe::Error> for Error {
fn from(err: eframe::Error) -> Self {
Error::Eframe(err)
}
}

View File

@@ -1,23 +1,25 @@
pub mod app;
// These lints need to be allowed due to the generated sources
#![allow(clippy::redundant_clone, clippy::cmp_owned)]
slint::include_modules!();
// Intentionally reexport slint so that GUI consumers don't need to add to
// `Cargo.toml`
use std::fs::{remove_dir_all, File, OpenOptions};
use std::io::{Read, Write};
use std::process::exit;
use std::thread::sleep;
use std::time::Duration;
pub use app::RogApp;
pub use slint;
pub mod cli_options;
pub mod config;
pub mod error;
#[cfg(feature = "mocking")]
pub mod mocking;
pub mod pages;
pub mod startup_error;
pub mod system_state;
pub mod tray;
pub mod update_and_notify;
pub mod widgets;
#[cfg(feature = "mocking")]
pub use mocking::RogDbusClientBlocking;
@@ -44,6 +46,7 @@ pub fn print_versions() {
pub const SHOWING_GUI: u8 = 1;
pub const SHOW_GUI: u8 = 2;
pub const QUIT_APP: u8 = 3;
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum Page {

View File

@@ -1,30 +1,29 @@
use std::borrow::BorrowMut;
use std::env::args;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::thread;
use std::thread::{self, sleep, spawn};
use std::time::Duration;
use eframe::HardwareAcceleration;
use gumdrop::Options;
use log::{debug, error, warn, LevelFilter};
use log::{warn, LevelFilter};
use rog_aura::aura_detection::{LaptopLedData, LedSupportFile};
use rog_aura::layouts::KeyLayout;
use rog_control_center::cli_options::CliStart;
use rog_control_center::config::Config;
use rog_control_center::error::Result;
use rog_control_center::startup_error::AppErrorShow;
use rog_control_center::slint::ComponentHandle;
use rog_control_center::system_state::SystemState;
use rog_control_center::tray::init_tray;
use rog_control_center::update_and_notify::{start_notifications, EnabledNotifications};
use rog_control_center::{
get_ipc_file, on_tmp_dir_exists, print_versions, RogApp, RogDbusClientBlocking, SHOWING_GUI,
SHOW_GUI,
get_ipc_file, on_tmp_dir_exists, print_versions, MainWindow, RogDbusClientBlocking, QUIT_APP,
SHOWING_GUI, SHOW_GUI,
};
#[cfg(not(feature = "mocking"))]
use supergfxctl::zbus_proxy::DaemonProxyBlocking as GfxProxyBlocking;
use tokio::runtime::Runtime;
// use winit::monitor::VideoMode;
// use winit::window::{Fullscreen, WindowLevel};
#[cfg(not(feature = "mocking"))]
const DATA_DIR: &str = "/usr/share/rog-gui/";
@@ -61,44 +60,22 @@ fn main() -> Result<()> {
// Enter the runtime so that `tokio::spawn` is available immediately.
let _enter = rt.enter();
let native_options = eframe::NativeOptions {
vsync: true,
hardware_acceleration: HardwareAcceleration::Preferred,
min_window_size: Some(egui::vec2(980.0, 670.0)),
max_window_size: Some(egui::vec2(980.0, 670.0)),
run_and_return: true,
..Default::default()
};
let (dbus, _) = RogDbusClientBlocking::new()
.map_err(|e| {
eframe::run_native(
"ROG Control Center",
native_options.clone(),
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
)
.map_err(|e| error!("{e}"))
.ok();
.map_err(|_| {
// TODO: show an error window
})
.unwrap();
let supported_properties = match dbus.proxies().platform().supported_properties() {
Ok(s) => s,
Err(e) => {
eframe::run_native(
"ROG Control Center",
native_options.clone(),
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
)
.map_err(|e| error!("{e}"))
.ok();
vec![]
Err(_e) => {
// TODO: show an error window
Vec::default()
}
};
// Startup
let mut config = Config::load()?;
let running_in_bg = Arc::new(AtomicBool::new(config.startup_in_background));
if config.startup_in_background {
config.run_in_background = true;
@@ -179,6 +156,7 @@ fn main() -> Result<()> {
Ok(tmp) => tmp,
Err(_) => on_tmp_dir_exists().unwrap(),
};
dbg!();
let states = setup_page_state_and_notifs(
layout_name,
@@ -188,77 +166,107 @@ fn main() -> Result<()> {
&config,
)?;
if cli_parsed.board_name.is_some() || cli_parsed.layout_viewing {
if let Ok(mut lock) = states.lock() {
lock.run_in_bg = false;
running_in_bg.store(false, Ordering::Release);
}
}
if config.enable_tray_icon {
init_tray(supported_properties, states.clone());
}
dbg!();
if let Ok(mut states) = states.lock() {
// For some reason the gui is causing a broke pipe error on dbus send, so
// replace it.
let (asus_dbus, conn) =
rog_dbus::RogDbusClientBlocking::new().expect("Couldn't connect to asusd");
states.asus_dbus = asus_dbus;
let gfx_dbus = GfxProxyBlocking::new(&conn).expect("Couldn't connect to supergfxd");
states.gfx_dbus = gfx_dbus;
}
thread_local! { pub static UI: std::cell::RefCell<Option<MainWindow>> = Default::default()};
i_slint_backend_selector::with_platform(|_| Ok(())).unwrap();
let mut bg_check_spawned = false;
loop {
if !running_in_bg.load(Ordering::Relaxed) {
// blocks until window is closed
let states = states.clone();
let mut ipc_file = get_ipc_file()?;
ipc_file.write_all(&[SHOWING_GUI])?;
eframe::run_native(
"ROG Control Center",
native_options.clone(),
Box::new(move |cc| {
let cfg = Config::load().unwrap();
let app = RogApp::new(cfg, states, cc);
Box::new(app.unwrap())
}),
)?;
dbg!();
thread::spawn(move || {
let mut buf = [0u8; 2];
// blocks until it is read, typically the read will happen after a second
// process writes to the IPC (so there is data to actually read)
loop {
get_ipc_file().unwrap().read_exact(&mut buf).unwrap();
if buf[0] == SHOW_GUI {
println!("Should show window {buf:?}");
let mut ipc_file = get_ipc_file().unwrap();
ipc_file.write_all(&[SHOWING_GUI, 0]).unwrap();
running_in_bg.store(true, Ordering::SeqCst);
bg_check_spawned = false;
}
if let Ok(lock) = states.try_lock() {
if !lock.run_in_bg {
break;
}
if lock.run_in_bg && running_in_bg.load(Ordering::Acquire) && !bg_check_spawned {
let running_in_bg = running_in_bg.clone();
thread::spawn(move || {
let mut buf = [0u8; 4];
// blocks until it is read, typically the read will happen after a second
// process writes to the IPC (so there is data to actually read)
loop {
if get_ipc_file().unwrap().read(&mut buf).is_ok() && buf[0] == SHOW_GUI {
running_in_bg.store(false, Ordering::Release);
debug!("Wait thread got from tray {buf:#?}");
break;
let states = states.clone();
i_slint_core::api::invoke_from_event_loop(move || {
UI.with(|ui| {
let mut ui = ui.borrow_mut();
if let Some(ui) = ui.as_mut() {
ui.window().show().unwrap();
ui.window().on_close_requested(|| {
let mut ipc_file = get_ipc_file().unwrap();
ipc_file.write_all(&[0, 0]).unwrap();
slint::CloseRequestResponse::HideWindow
});
} else {
let newui = setup_window(states.clone());
newui.window().show().unwrap();
println!("New window should be showing now"); // but it isn't
newui.window().on_close_requested(|| {
let mut ipc_file = get_ipc_file().unwrap();
ipc_file.write_all(&[0, 0]).unwrap();
slint::CloseRequestResponse::HideWindow
});
ui.replace(newui);
}
}
});
bg_check_spawned = true;
});
})
.unwrap();
} else if buf[1] == QUIT_APP {
slint::quit_event_loop().unwrap();
} else if buf[0] != SHOWING_GUI {
println!("Should hide window {buf:?}");
i_slint_core::api::invoke_from_event_loop(move || {
UI.with(|ui| {
let mut ui = ui.take();
if let Some(ui) = ui.borrow_mut() {
ui.window().hide().unwrap();
}
});
})
.unwrap();
}
}
});
// Prevent hogging CPU
thread::sleep(Duration::from_millis(500));
}
slint::run_event_loop_until_quit().unwrap();
Ok(())
}
fn setup_window(_states: Arc<Mutex<SystemState>>) -> MainWindow {
// slint::platform::set_platform(Box::new(i_slint_backend_winit::Backend::new().
// unwrap())).unwrap();
let ui = MainWindow::new().unwrap();
// Example of how to do work in another thread.
// The thread itself can keep its own state, and then update vars in the UI
// when required.
let ui_handle = ui.as_weak();
spawn(move || loop {
sleep(Duration::from_secs(1));
// This is where the actual update happens
ui_handle
.upgrade_in_event_loop(move |handle| {
// handle.set_counter(handle.get_counter() + 1);
use i_slint_backend_winit::WinitWindowAccessor;
handle
.window()
.with_winit_window(|winit_window: &winit::window::Window| {
// winit_window.set_fullscreen(Some(Fullscreen::Borderless(None)));
if !winit_window.has_focus() {
// slint::quit_event_loop().unwrap();
// handle.hide().unwrap();
}
});
})
.ok();
});
ui.on_exit_app(move || {
slint::quit_event_loop().unwrap();
});
ui
}
fn setup_page_state_and_notifs(
layout_testing: Option<PathBuf>,
keyboard_layout: KeyLayout,

View File

@@ -1,9 +0,0 @@
use crate::RogApp;
impl RogApp {
pub fn anime_page(&mut self, ctx: &eframe::egui::Context) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.label("In progress");
});
}
}

View File

@@ -1,24 +0,0 @@
use crate::system_state::SystemState;
use crate::widgets::app_settings;
use crate::RogApp;
impl RogApp {
pub fn app_settings_page(&mut self, states: &mut SystemState, ctx: &eframe::egui::Context) {
let Self { config, .. } = self;
egui::CentralPanel::default().show(ctx, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
ui.spacing_mut().item_spacing = egui::vec2(8.0, 10.0);
let rect = ui.available_rect_before_wrap();
egui::Grid::new("grid_of_bits")
.min_col_width(rect.width() / 2.0)
.show(ui, |ui| {
ui.vertical(|ui| {
ui.separator();
app_settings(config, states, ui);
});
});
})
});
}
}

View File

@@ -1,83 +0,0 @@
use std::sync::atomic::Ordering;
use std::time::Duration;
use egui::Color32;
use rog_aura::{AuraEffect, AuraModeNum};
use crate::system_state::SystemState;
use crate::widgets::{aura_modes_group, keyboard};
use crate::RogApp;
impl RogApp {
pub fn aura_page(&mut self, states: &mut SystemState, ctx: &eframe::egui::Context) {
let Self {
oscillator1,
oscillator2,
oscillator3,
oscillator_freq,
..
} = self;
let red = oscillator1.load(Ordering::SeqCst) as u32;
let green = oscillator2.load(Ordering::SeqCst) as u32;
let blue = oscillator3.load(Ordering::SeqCst) as u32;
states.aura.nudge_wave(red as u8, green as u8, blue as u8);
// let osc = c.r * 255 / osc;
let c1 = states
.aura
.modes
.get(&states.aura.current_mode)
.unwrap_or(&AuraEffect::default())
.colour1;
let c2 = states
.aura
.modes
.get(&states.aura.current_mode)
.unwrap_or(&AuraEffect::default())
.colour2;
let mut colour = Color32::from_rgb(c1.r, c1.g, c1.b);
if states.aura.current_mode == AuraModeNum::Pulse {
colour = Color32::from_rgb(
(red * c1.r as u32 / 100) as u8,
(red * c1.g as u32 / 100) as u8,
(red * c1.b as u32 / 100) as u8,
);
} else if states.aura.current_mode == AuraModeNum::Breathe {
if self.oscillator_toggle.load(Ordering::SeqCst) {
colour = Color32::from_rgb(
(red * c2.r as u32 / 100) as u8,
(red * c2.g as u32 / 100) as u8,
(red * c2.b as u32 / 100) as u8,
);
} else {
colour = Color32::from_rgb(
(red * c1.r as u32 / 100) as u8,
(red * c1.g as u32 / 100) as u8,
(red * c1.b as u32 / 100) as u8,
);
}
} else if states.aura.current_mode == AuraModeNum::Strobe {
colour = Color32::from_rgb(
(red * 255 / 100) as u8,
(green * 255 / 100) as u8,
(blue * 255 / 100) as u8,
);
}
// TODO: animation of colour changes/periods/blending
egui::CentralPanel::default().show(ctx, |ui| {
aura_modes_group(states, oscillator_freq, ui);
keyboard(
ui,
&states.aura_creation.keyboard_layout,
&mut states.aura,
colour,
);
});
// Only do repaint request if on this page
ctx.request_repaint_after(Duration::from_millis(33));
}
}

View File

@@ -1,92 +0,0 @@
use egui::{RichText, Ui};
use rog_platform::platform::ThrottlePolicy;
use crate::system_state::{FanCurvesState, SystemState};
use crate::widgets::fan_graphs;
use crate::{RogApp, RogDbusClientBlocking};
impl RogApp {
pub fn fan_curve_page(&mut self, states: &mut SystemState, ctx: &eframe::egui::Context) {
if let Some(mut throttle) = states.bios.throttle {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Custom fan curves");
Self::fan_curve(
&mut throttle,
&mut states.fan_curves,
&states.asus_dbus,
&mut states.error,
ui,
);
fan_graphs(
&mut states.fan_curves,
&states.asus_dbus,
&mut states.error,
ui,
);
});
}
}
fn fan_curve(
current: &mut ThrottlePolicy,
curves: &mut FanCurvesState,
dbus: &RogDbusClientBlocking<'_>,
do_error: &mut Option<String>,
ui: &mut Ui,
) {
ui.separator();
let mut changed = false;
ui.horizontal(|ui| {
ui.label("Current profile: ");
ui.label(RichText::new(format!("{}", current)).strong());
});
ui.horizontal(|ui| {
ui.label("Enabled fan-curves: ");
let mut checked = false;
let mut label = String::default();
if let Some(curves) = curves.curves.get_mut(current) {
for curve in curves.iter() {
label.push_str(&<&str>::from(curve.fan).to_ascii_uppercase());
label.push(' ');
if curve.enabled {
// TODO: it's possible to set just one fan to active
checked = true;
}
}
}
if ui
.add(egui::Checkbox::new(
&mut checked,
RichText::new(label).strong(),
))
.changed()
{
dbus.proxies()
.fan_curves()
.set_fan_curves_enabled(*current, checked)
.map_err(|err| {
*do_error = Some(err.to_string());
})
.ok();
changed = true;
}
});
if changed {
let selected_profile = curves.show_curve;
let selected_pu = curves.show_graph;
match FanCurvesState::new(dbus) {
Ok(f) => *curves = f,
Err(e) => *do_error = Some(e.to_string()),
}
curves.show_curve = selected_profile;
curves.show_graph = selected_pu;
}
}
}

View File

@@ -1,5 +0,0 @@
mod anime_page;
mod app_settings;
mod aura_page;
mod fan_curve_page;
mod system_page;

View File

@@ -1,50 +0,0 @@
use crate::system_state::SystemState;
use crate::widgets::{anime_power_group, aura_power_group, platform_profile, rog_bios_group};
use crate::RogApp;
impl RogApp {
pub fn system_page(&mut self, states: &mut SystemState, ctx: &eframe::egui::Context) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Laptop settings");
egui::ScrollArea::vertical().show(ui, |ui| {
ui.spacing_mut().item_spacing = egui::vec2(8.0, 10.0);
let rect = ui.available_rect_before_wrap();
egui::Grid::new("grid_of_bits")
.min_col_width(rect.width() / 2.0)
.show(ui, |ui| {
ui.vertical(|ui| {
ui.separator();
// if self.supported_interfaces {
platform_profile(states, ui);
// }
});
ui.vertical(|ui| {
ui.separator();
if self.supported_interfaces.contains(&"Aura".to_string()) {
aura_power_group(states, ui);
}
});
ui.end_row();
ui.vertical(|ui| {
ui.separator();
rog_bios_group(states, ui);
});
ui.end_row();
ui.vertical(|ui| {
ui.separator();
if self.supported_interfaces.contains(&"Anime".to_string()) {
anime_power_group(states, ui);
}
});
ui.vertical(|ui| {
ui.separator();
});
ui.end_row();
});
});
});
}
}

View File

@@ -1,38 +0,0 @@
use egui::RichText;
pub struct AppErrorShow {
error: String,
}
impl AppErrorShow {
pub fn new(error: String) -> Self {
Self { error }
}
}
impl eframe::App for AppErrorShow {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("ROG ERROR");
ui.centered_and_justified(|ui| {
ui.label(RichText::new(format!("The error was: {:?}", self.error)).size(22.0));
});
// egui::TopBottomPanel::bottom("error_bar_2")
// .default_height(26.0)
// .show(ctx, |ui| {
// ui.
// with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
// if ui
// .add(Button::new(RichText::new("Okay").size(20.0)))
// .clicked()
// {
// // frame.close();
// // ui.close_menu();
// }
// });
// });
});
}
}

View File

@@ -3,13 +3,11 @@ use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::time::SystemTime;
use egui::Vec2;
use log::error;
use rog_anime::{Animations, DeviceState};
use rog_aura::aura_detection::PowerZones;
use rog_aura::layouts::KeyLayout;
use rog_aura::usb::{AuraDevice, AuraPowerDev};
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness};
use rog_aura::usb::AuraPowerDev;
use rog_aura::{AuraEffect, AuraModeNum, LedBrightness};
use rog_platform::platform::{GpuMode, ThrottlePolicy};
use rog_profiles::fan_curve_set::CurveData;
use rog_profiles::FanCurvePU;
@@ -69,7 +67,7 @@ pub struct FanCurvesState {
pub show_graph: FanCurvePU,
pub curves: BTreeMap<ThrottlePolicy, Vec<CurveData>>,
pub available_fans: HashSet<FanCurvePU>,
pub drag_delta: Vec2,
// pub drag_delta: Vec2,
}
impl FanCurvesState {
@@ -102,7 +100,7 @@ impl FanCurvesState {
show_graph: FanCurvePU::CPU,
curves,
available_fans,
drag_delta: Vec2::default(),
// drag_delta: Vec2::default(),
})
}
}
@@ -112,9 +110,6 @@ pub struct AuraState {
pub current_mode: AuraModeNum,
pub modes: BTreeMap<AuraModeNum, AuraEffect>,
pub enabled: AuraPowerDev,
pub dev_type: AuraDevice,
pub supported_basic_zones: Vec<AuraZone>,
pub supported_power_zones: Vec<PowerZones>,
/// Brightness from 0-3
pub bright: LedBrightness,
pub wave_red: [u8; 22],
@@ -126,7 +121,10 @@ impl AuraState {
pub fn new(layout: &KeyLayout, dbus: &RogDbusClientBlocking<'_>) -> Result<Self> {
Ok(Self {
current_mode: if !layout.basic_modes().is_empty() {
dbus.proxies().aura().led_mode().unwrap_or_default()
dbg!();
let x = dbus.proxies().aura().led_mode().unwrap_or_default();
dbg!();
x
} else {
AuraModeNum::Static
},
@@ -137,18 +135,7 @@ impl AuraState {
BTreeMap::new()
},
enabled: dbus.proxies().aura().led_power().unwrap_or_default(),
supported_basic_zones: dbus
.proxies()
.aura()
.supported_basic_zones()
.unwrap_or_default(),
supported_power_zones: dbus
.proxies()
.aura()
.supported_power_zones()
.unwrap_or_default(),
dev_type: dbus.proxies().aura().device_type().unwrap_or_default(),
bright: dbus.proxies().aura().brightness().unwrap_or_default(),
bright: Default::default(),
wave_red: [0u8; 22],
wave_green: [0u8; 22],
wave_blue: [0u8; 22],
@@ -291,9 +278,9 @@ impl SystemState {
tray_enabled: bool,
run_in_bg: bool,
) -> Result<Self> {
dbg!();
let (asus_dbus, conn) = RogDbusClientBlocking::new()?;
let gfx_dbus = GfxProxyBlocking::new(&conn).expect("Couldn't connect to supergfxd");
dbg!();
let aura = AuraState::new(&keyboard_layout, &asus_dbus)
.map_err(|e| {
let e = format!("Could not get AuraState state: {e}");
@@ -301,6 +288,12 @@ impl SystemState {
})
.unwrap_or_default();
dbg!();
let gfx_dbus = GfxProxyBlocking::builder(&conn)
.destination(":org.supergfxctl.Daemon")?
.build()
.expect("Couldn't connect to supergfxd");
dbg!();
Ok(Self {
aura_creation: AuraCreation::new(layout_testing, keyboard_layout, keyboard_layouts),
enabled_notifications,
@@ -348,7 +341,9 @@ impl SystemState {
impl Default for SystemState {
fn default() -> Self {
let (asus_dbus, conn) = RogDbusClientBlocking::new().expect("Couldn't connect to asusd");
let gfx_dbus = GfxProxyBlocking::new(&conn).expect("Couldn't connect to supergfxd");
let gfx_dbus = GfxProxyBlocking::builder(&conn)
.build()
.expect("Couldn't connect to supergfxd");
Self {
aura_creation: AuraCreation {

View File

@@ -86,7 +86,7 @@ impl ROGTray {
e
})?;
let gfx_proxy = GfxProxyBlocking::new(&conn).map_err(|e| {
let gfx_proxy = GfxProxyBlocking::builder(&conn).build().map_err(|e| {
error!("ROGTray: {e}");
e
})?;

View File

@@ -98,7 +98,7 @@ macro_rules! recv_notif {
log::error!("zbus signal: {}: {e}", stringify!($signal));
e
}).unwrap();
let proxy = $proxy::new(&conn).await.map_err(|e| {
let proxy = $proxy::builder(&conn).build().await.map_err(|e| {
log::error!("zbus signal: {}: {e}", stringify!($signal));
e
}).unwrap();
@@ -446,7 +446,8 @@ pub fn start_notifications(
e
})
.unwrap();
let proxy = SuperProxy::new(&conn)
let proxy = SuperProxy::builder(&conn)
.build()
.await
.map_err(|e| {
error!("zbus signal: receive_notify_action: {e}");

View File

@@ -1,83 +0,0 @@
use egui::{RichText, Ui};
use rog_anime::usb::Brightness;
use crate::system_state::SystemState;
pub fn anime_power_group(states: &mut SystemState, ui: &mut Ui) {
ui.heading("AniMe Matrix Settings");
ui.label("Options are incomplete. Awake + Boot should work");
ui.horizontal_wrapped(|ui| {
ui.vertical(|ui| {
let h = 16.0;
ui.set_row_height(22.0);
ui.horizontal_wrapped(|ui| {
ui.label(RichText::new("Display brightness").size(h));
});
ui.horizontal_wrapped(|ui| {
ui.label(RichText::new("Display enabled").size(h));
});
ui.horizontal_wrapped(|ui| {
ui.label(RichText::new("Animations enabled").size(h));
});
// ui.horizontal_wrapped(|ui| {
// ui.label(RichText::new("Sleep").size(h));
// });
});
ui.vertical(|ui| {
ui.set_row_height(22.0);
ui.horizontal_wrapped(|ui| {
let slider =
egui::Slider::new(&mut states.anime.display_brightness, 0..=3).step_by(1.0);
if ui.add(slider).drag_released() {
states
.asus_dbus
.proxies()
.anime()
.set_brightness(Brightness::from(states.anime.display_brightness))
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
}
});
ui.horizontal_wrapped(|ui| {
if ui
.checkbox(&mut states.anime.display_enabled, "Enable")
.changed()
{
states
.asus_dbus
.proxies()
.anime()
.set_enable_display(states.anime.display_enabled)
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
}
});
ui.horizontal_wrapped(|ui| {
if ui
.checkbox(&mut states.anime.builtin_anims_enabled, "Enable")
.changed()
{
states
.asus_dbus
.proxies()
.anime()
.set_builtins_enabled(states.anime.builtin_anims_enabled)
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
}
});
// ui.horizontal_wrapped(|ui| {
// if ui.checkbox(&mut states.anime.sleep, "Enable").changed() {
// changed = true;
// }
// });
});
});
}

View File

@@ -1,117 +0,0 @@
use egui::Ui;
use crate::config::Config;
use crate::system_state::SystemState;
pub fn app_settings(config: &mut Config, states: &mut SystemState, ui: &mut Ui) {
ui.heading("App Settings");
let mut enabled_notifications = if let Ok(lock) = states.enabled_notifications.lock() {
lock.clone()
} else {
Default::default()
};
ui.label("Application settings");
let app_changed = ui
.checkbox(
&mut config.enable_tray_icon,
"Enable Tray Icon (restart required)",
)
.clicked()
|| ui
.checkbox(&mut config.run_in_background, "Run in Background")
.clicked()
|| ui
.checkbox(&mut config.startup_in_background, "Startup Hidden")
.clicked()
|| ui
.checkbox(
&mut enabled_notifications.all_enabled,
"Enable Notifications",
)
.clicked();
// if ui.button("Quit").clicked() {
// states.run_in_bg = false;
// }
ui.label("Notification settings");
let notif_changed = ui
.checkbox(
&mut enabled_notifications.receive_notify_gfx_status,
"Enable dGPU status notification",
)
.clicked()
|| ui
.checkbox(
&mut enabled_notifications.receive_led_mode_data_changed,
"Enable LED mode change notification",
)
.clicked()
|| ui
.checkbox(
&mut enabled_notifications.receive_dgpu_disable_changed,
"Enable dGPU disablement notification",
)
.clicked()
|| ui
.checkbox(
&mut enabled_notifications.receive_egpu_enable_changed,
"Enable eGPU enablement notification",
)
.clicked()
|| ui
.checkbox(
&mut enabled_notifications.receive_notify_mains_online,
"Enable mains (AC) power notification",
)
.clicked()
|| ui
.checkbox(
&mut enabled_notifications.receive_charge_control_end_threshold_changed,
"Enable charge threshold notification",
)
.clicked()
|| ui
.checkbox(
&mut enabled_notifications.receive_throttle_thermal_policy_changed,
"Enable profile change notification",
)
.clicked()
|| ui
.checkbox(
&mut enabled_notifications.receive_panel_od_changed,
"Enable panel overdrive notification",
)
.clicked()
|| ui
.checkbox(
&mut enabled_notifications.receive_mini_led_mode_changed,
"Enable MiniLED mode notification",
)
.clicked()
|| ui
.checkbox(
&mut enabled_notifications.receive_post_animation_sound_changed,
"Enable BIOS post sound notification",
)
.clicked();
if app_changed || notif_changed {
if let Ok(mut lock) = states.enabled_notifications.lock() {
// Replace inner content before save
*lock = enabled_notifications;
config
.save(&lock)
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
states.tray_enabled = config.enable_tray_icon;
states.run_in_bg = config.run_in_background;
}
}
}

View File

@@ -1,237 +0,0 @@
use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::Arc;
use egui::{RichText, Ui};
use rog_aura::layouts::KeyLayout;
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour, Speed};
use crate::system_state::SystemState;
pub fn aura_modes_group(states: &mut SystemState, freq: &mut Arc<AtomicU8>, ui: &mut Ui) {
let mut changed = false;
let mut selected = states.aura.current_mode;
let allowed = AuraEffect::allowed_parameters(selected);
let SystemState { aura_creation, .. } = states;
let has_keyzones = aura_creation
.keyboard_layout
.basic_zones()
.contains(&AuraZone::Key2);
let has_logo = aura_creation
.keyboard_layout
.basic_zones()
.contains(&AuraZone::Logo);
let has_lightbar = aura_creation
.keyboard_layout
.basic_zones()
.contains(&AuraZone::BarLeft)
|| aura_creation
.keyboard_layout
.basic_zones()
.contains(&AuraZone::BarRight);
if let Some(p) = aura_creation.layout_testing.as_ref() {
ui.heading(format!("{p:?}"));
} else {
ui.heading("Aura modes");
ui.label(
"Please note that this section is incomplete and the displayed effects won't match \
actual effect",
);
}
let mut item = |a: AuraModeNum, ui: &mut Ui| {
if ui
.selectable_value(&mut selected, a, format!("{:?}", a))
.clicked()
{
changed = true;
}
};
ui.horizontal_wrapped(|ui| {
for a in states.aura.modes.keys() {
item(*a, ui);
}
});
if let Some(effect) = states.aura.modes.get_mut(&selected) {
let mut zone_button = |a: AuraZone, ui: &mut Ui| {
ui.selectable_value(&mut effect.zone, a, format!("{:?}", a));
};
let mut speed_button = |a: Speed, ui: &mut Ui| -> bool {
if ui
.selectable_value(&mut effect.speed, a, format!("{:?}", a))
.clicked()
{
let val = match effect.speed {
Speed::Low => 6,
Speed::Med => 8,
Speed::High => 10,
};
freq.store(val, Ordering::SeqCst);
return true;
}
false
};
let mut dir_button = |a: rog_aura::Direction, ui: &mut Ui| -> bool {
ui.selectable_value(&mut effect.direction, a, format!("{:?}", a))
.clicked()
};
let mut c1: [u8; 3] = effect.colour1.into();
let mut c2: [u8; 3] = effect.colour2.into();
ui.separator();
ui.horizontal_wrapped(|ui| {
ui.vertical(|ui| {
let h = 16.0;
ui.set_row_height(22.0);
ui.add_enabled_ui(allowed.zone, |ui| {
if has_keyzones || has_lightbar || has_logo {
ui.horizontal_wrapped(|ui| {
ui.label(RichText::new("Zone").size(h));
});
}
});
ui.add_enabled_ui(allowed.colour1, |ui| {
ui.horizontal_wrapped(|ui| {
ui.label(RichText::new("Colour 1").size(h));
});
});
ui.add_enabled_ui(allowed.colour2, |ui| {
ui.horizontal_wrapped(|ui| {
ui.label(RichText::new("Colour 2").size(h));
});
});
ui.add_enabled_ui(allowed.speed, |ui| {
ui.horizontal_wrapped(|ui| {
ui.set_enabled(allowed.speed);
ui.label(RichText::new("Speed").size(h));
});
});
ui.add_enabled_ui(allowed.direction, |ui| {
ui.horizontal_wrapped(|ui| {
ui.set_enabled(allowed.direction);
ui.label(RichText::new("Direction").size(h));
});
});
ui.set_enabled(true);
});
ui.vertical(|ui| {
ui.set_row_height(22.0);
ui.add_enabled_ui(allowed.zone, |ui| {
if has_keyzones || has_lightbar || has_logo {
ui.horizontal_wrapped(|ui| {
zone_button(AuraZone::None, ui);
if has_keyzones {
zone_button(AuraZone::Key1, ui);
zone_button(AuraZone::Key2, ui);
zone_button(AuraZone::Key3, ui);
zone_button(AuraZone::Key4, ui);
}
if has_logo {
zone_button(AuraZone::Logo, ui);
}
if has_lightbar {
zone_button(AuraZone::BarLeft, ui);
zone_button(AuraZone::BarRight, ui);
}
});
}
});
ui.add_enabled_ui(allowed.colour1, |ui| {
if egui::color_picker::color_edit_button_srgb(ui, &mut c1).changed() {
changed = true;
}
});
ui.add_enabled_ui(allowed.colour2, |ui| {
if egui::color_picker::color_edit_button_srgb(ui, &mut c2).changed() {
changed = true;
}
});
ui.add_enabled_ui(allowed.speed, |ui| {
ui.horizontal_wrapped(|ui| {
if speed_button(Speed::Low, ui)
|| speed_button(Speed::Med, ui)
|| speed_button(Speed::High, ui)
{
changed = true;
}
});
});
ui.add_enabled_ui(allowed.direction, |ui| {
ui.horizontal_wrapped(|ui| {
if dir_button(rog_aura::Direction::Left, ui)
|| dir_button(rog_aura::Direction::Down, ui)
|| dir_button(rog_aura::Direction::Right, ui)
|| dir_button(rog_aura::Direction::Up, ui)
{
changed = true;
}
});
});
});
});
effect.colour1 = Colour::from(&c1);
effect.colour2 = Colour::from(&c2);
}
ui.separator();
ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
// if ui.add(egui::Button::new("Cancel")).clicked() {
// match AuraState::new(&aura_creation.keyboard_layout, &states.asus_dbus) {
// Ok(a) => states.aura.modes = a.modes,
// Err(e) => states.error = Some(e.to_string()),
// }
// }
// if ui.add(egui::Button::new("Apply")).clicked() {
// changed = true;
// }
if aura_creation.layout_testing.is_some() {
if ui.add(egui::Button::new("Next layout")).clicked() {
if aura_creation.keyboard_layout_index < aura_creation.keyboard_layouts.len() - 1 {
aura_creation.keyboard_layout_index += 1;
}
aura_creation.layout_testing = Some(
aura_creation.keyboard_layouts[aura_creation.keyboard_layout_index].clone(),
);
aura_creation.keyboard_layout =
KeyLayout::from_file(aura_creation.layout_testing.as_ref().unwrap().as_path())
.unwrap();
}
if ui.add(egui::Button::new("Prev layout")).clicked() {
if aura_creation.keyboard_layout_index > 0 {
aura_creation.keyboard_layout_index -= 1;
}
aura_creation.layout_testing = Some(
aura_creation.keyboard_layouts[aura_creation.keyboard_layout_index].clone(),
);
aura_creation.keyboard_layout =
KeyLayout::from_file(aura_creation.layout_testing.as_ref().unwrap().as_path())
.unwrap();
}
}
});
if changed {
states.aura.current_mode = selected;
states
.asus_dbus
.proxies()
.aura()
.set_led_mode_data(states.aura.modes.get(&selected).unwrap().clone())
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
}
}

View File

@@ -1,266 +0,0 @@
use egui::{RichText, Ui};
use rog_aura::power::{AuraPower, KbAuraPowerState};
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, AuraDevice, AuraPowerDev};
use crate::system_state::SystemState;
pub fn aura_power_group(states: &mut SystemState, ui: &mut Ui) {
ui.heading("Keyboard LED power settings");
if states.aura.dev_type.is_old_style() || states.aura.dev_type.is_tuf_style() {
aura_power1(states, ui);
} else if states.aura.dev_type.is_new_style() {
aura_power2(states, ui);
}
}
fn aura_power1(states: &mut SystemState, ui: &mut Ui) {
let enabled_states = &mut states.aura.enabled;
let mut boot = enabled_states.old_rog.contains(&AuraDevRog1::Boot);
let mut sleep = enabled_states.old_rog.contains(&AuraDevRog1::Sleep);
let mut keyboard = enabled_states.old_rog.contains(&AuraDevRog1::Keyboard);
let mut lightbar = enabled_states.old_rog.contains(&AuraDevRog1::Lightbar);
if states.aura.dev_type == AuraDevice::Tuf {
boot = enabled_states.tuf.contains(&AuraDevTuf::Boot);
sleep = enabled_states.tuf.contains(&AuraDevTuf::Sleep);
keyboard = enabled_states.tuf.contains(&AuraDevTuf::Awake);
}
let mut changed = false;
ui.horizontal_wrapped(|ui| {
ui.vertical(|ui| {
let h = 16.0;
ui.set_row_height(22.0);
ui.horizontal_wrapped(|ui| {
ui.label(RichText::new("Boot").size(h));
});
ui.horizontal_wrapped(|ui| {
ui.label(RichText::new("Awake").size(h));
});
ui.horizontal_wrapped(|ui| {
ui.label(RichText::new("Sleep").size(h));
});
// if supported.keyboard_led.brightness_set {
// ui.horizontal_wrapped(|ui| {
// ui.label(RichText::new("Brightness").size(h));
// });
// }
});
ui.vertical(|ui| {
ui.set_row_height(22.0);
ui.horizontal_wrapped(|ui| {
if ui.checkbox(&mut boot, "Enable").changed() {
changed = true;
}
});
ui.horizontal_wrapped(|ui| {
if ui.toggle_value(&mut keyboard, "Keyboard").changed() {
changed = true;
}
if !states.aura.supported_basic_zones.is_empty()
&& ui.toggle_value(&mut lightbar, "Lightbar").changed()
{
changed = true;
}
});
ui.horizontal_wrapped(|ui| {
if ui.checkbox(&mut sleep, "Enable").changed() {
changed = true;
}
});
// We currently don't have a watch for system changes here
// if supported.keyboard_led.brightness_set {
// if ui
// .add(egui::Slider::new(
// &mut states.aura.bright,
// 0..=3,
// ))
// .changed()
// {
// let bright = LedBrightness::from(states.aura.bright as
// u32); dbus.proxies()
// .led()
// .set_brightness(bright)
// .map_err(|err| {
// states.error = Some(err.to_string());
// })
// .ok();
// }
// }
});
});
if changed {
if states.aura.dev_type == AuraDevice::Tuf {
let mut enabled = Vec::new();
let mut disabled = Vec::new();
let mut modify_tuf = |b: bool, a: AuraDevTuf| {
if b {
enabled.push(a);
if !enabled_states.tuf.contains(&a) {
enabled_states.tuf.push(a);
}
} else {
disabled.push(a);
// This would be so much better as a hashset
if enabled_states.tuf.contains(&a) {
let mut idx = 0;
for (i, n) in enabled_states.tuf.iter().enumerate() {
if *n == a {
idx = i;
break;
}
}
enabled_states.tuf.remove(idx);
}
}
};
modify_tuf(boot, AuraDevTuf::Boot);
modify_tuf(sleep, AuraDevTuf::Sleep);
modify_tuf(keyboard, AuraDevTuf::Awake);
let mut send = |enable: bool, data: Vec<AuraDevTuf>| {
let options = AuraPowerDev {
tuf: data,
..Default::default()
};
// build data to send
states
.asus_dbus
.proxies()
.aura()
.set_led_power((options, enable))
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
};
send(true, enabled);
send(false, disabled);
} else {
let mut enabled = Vec::new();
let mut disabled = Vec::new();
let mut modify_x1866 = |b: bool, a: AuraDevRog1| {
if b {
enabled.push(a);
if !enabled_states.old_rog.contains(&a) {
enabled_states.old_rog.push(a);
}
} else {
disabled.push(a);
// This would be so much better as a hashset
if enabled_states.old_rog.contains(&a) {
let mut idx = 0;
for (i, n) in enabled_states.old_rog.iter().enumerate() {
if *n == a {
idx = i;
break;
}
}
enabled_states.old_rog.remove(idx);
}
}
};
modify_x1866(boot, AuraDevRog1::Boot);
modify_x1866(sleep, AuraDevRog1::Sleep);
modify_x1866(keyboard, AuraDevRog1::Keyboard);
if !states.aura.supported_basic_zones.is_empty() {
modify_x1866(lightbar, AuraDevRog1::Lightbar);
}
let mut send = |enable: bool, data: Vec<AuraDevRog1>| {
let options = AuraPowerDev {
old_rog: data,
..Default::default()
};
// build data to send
states
.asus_dbus
.proxies()
.aura()
.set_led_power((options, enable))
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
};
send(true, enabled);
send(false, disabled);
}
}
}
fn aura_power2(states: &mut SystemState, ui: &mut Ui) {
let AuraPower {
keyboard,
logo,
lightbar,
lid,
rear_glow,
} = &mut states.aura.enabled.rog;
const LABELS: [&str; 4] = ["Boot", "Awake", "Sleep", "Shutdown"];
let mut changed = false;
let mut item = |power: &mut KbAuraPowerState, ui: &mut Ui| {
ui.vertical(|ui| {
if states.aura.supported_power_zones.contains(&power.zone) {
ui.horizontal_wrapped(|ui| {
ui.label(RichText::new(format!("{:?}", power.zone)).size(14.0));
});
if ui.checkbox(&mut power.boot, LABELS[0]).changed() {
changed = true;
}
if ui.checkbox(&mut power.awake, LABELS[1]).changed() {
changed = true;
}
if ui.checkbox(&mut power.sleep, LABELS[2]).changed() {
changed = true;
}
if ui.checkbox(&mut power.shutdown, LABELS[3]).changed() {
changed = true;
}
}
});
};
ui.horizontal_wrapped(|ui| {
item(lid, ui);
item(logo, ui);
item(keyboard, ui);
item(lightbar, ui);
item(rear_glow, ui);
});
if changed {
let mut send = |enable: bool, data: AuraPower| {
let options = AuraPowerDev {
rog: data,
..Default::default()
};
// build data to send
states
.asus_dbus
.proxies()
.aura()
.set_led_power((options, enable))
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
};
send(
true,
AuraPower {
keyboard: *keyboard,
logo: *logo,
lightbar: *lightbar,
lid: *lid,
rear_glow: *rear_glow,
},
);
}
}

View File

@@ -1,208 +0,0 @@
use egui::plot::{Line, Plot, Points};
use egui::Ui;
use rog_platform::platform::ThrottlePolicy;
use rog_profiles::fan_curve_set::CurveData;
use rog_profiles::FanCurvePU;
use crate::system_state::FanCurvesState;
use crate::RogDbusClientBlocking;
pub fn fan_graphs(
curves: &mut FanCurvesState,
dbus: &RogDbusClientBlocking<'_>,
do_error: &mut Option<String>,
ui: &mut Ui,
) {
if curves.available_fans.is_empty() {
return; // TODO:
}
ui.separator();
let mut item = |profile: ThrottlePolicy, ui: &mut Ui| {
ui.group(|ui| {
if ui
.selectable_value(&mut curves.show_curve, profile, format!("{profile:?}"))
.clicked()
{
dbus.proxies()
.platform()
.set_throttle_thermal_policy(profile)
.ok();
}
ui.add_enabled_ui(curves.show_curve == profile, |ui| {
if curves.available_fans.contains(&FanCurvePU::CPU) {
ui.selectable_value(
&mut curves.show_graph,
FanCurvePU::CPU,
format!("{:?}", FanCurvePU::CPU),
);
}
if curves.available_fans.contains(&FanCurvePU::GPU) {
ui.selectable_value(
&mut curves.show_graph,
FanCurvePU::GPU,
format!("{:?}", FanCurvePU::GPU),
);
}
if curves.available_fans.contains(&FanCurvePU::MID) {
ui.selectable_value(
&mut curves.show_graph,
FanCurvePU::MID,
format!("{:?}", FanCurvePU::MID),
);
}
});
});
};
ui.horizontal_wrapped(|ui| {
for a in &curves.curves {
item(*a.0, ui);
}
});
let curve = curves.curves.get_mut(&curves.show_curve).unwrap();
let mut data = &mut CurveData::default();
for c in curve {
if c.fan == curves.show_graph {
data = c;
break;
}
}
let mut points: Vec<[f64; 2]> = data
.temp
.iter()
.enumerate()
.map(|(idx, x)| {
let x = *x as f64;
let y = ((data.pwm[idx] as u32) * 100 / 255) as f64;
[x, y]
})
.collect();
for i in 0..points.len() - 1 {
if i > 0 && i < points.len() - 1 {
if points[i][0] < points[i - 1][0] {
points[i][0] = points[i - 1][0] + 1.0;
data.temp[i] = points[i - 1][0] as u8;
}
if points[i][0] >= points[i + 1][0] {
points[i + 1][0] = points[i][0] + 1.0;
data.temp[i + 1] = points[i][0] as u8;
}
if points[i][1] < points[i - 1][1] {
points[i][1] = points[i - 1][1] + 1.0;
data.pwm[i] = (points[i - 1][1] * 255.0 / 100.0 + 1.0).floor() as u8;
}
if points[i][1] >= points[i + 1][1] {
points[i + 1][1] = points[i][1] + 1.0;
data.pwm[i + 1] = (points[i][1] * 255.0 / 100.0 + 1.0).floor() as u8;
}
}
}
let line = Line::new(points.clone()).width(2.0);
let points = Points::new(points).radius(3.0);
Plot::new("fan_curves")
.view_aspect(1.666)
// .center_x_axis(true)
// .center_y_axis(true)
.include_x(0.0)
.include_x(104.0)
.include_y(0.0)
.include_y(106.0)
.allow_scroll(false)
.allow_drag(false)
.allow_boxed_zoom(false)
// .x_axis_formatter(|d, _r| format!("{}", d))
// .y_axis_formatter(|d, _r| format!("{:.*}%", 1, d))
.label_formatter(|name, value| {
if !name.is_empty() {
format!("{}: {:.*}%", name, 1, value.y)
} else {
format!("Temp {}c\nFan {:.*}%", value.x as u8, 1, value.y)
}
})
.show(ui, |plot_ui| {
if plot_ui.plot_hovered() {
let mut idx = 0;
if let Some(point) = plot_ui.pointer_coordinate() {
let mut x: i32 = point.x as i32;
for (i, n) in data.temp.iter().enumerate() {
let tmp = x.min((point.x as i32 - *n as i32).abs());
if tmp < x {
x = tmp;
idx = i;
}
}
if plot_ui.plot_clicked() {
data.temp[idx] = point.x as u8;
data.pwm[idx] = (point.y * 255.0 / 100.0) as u8;
} else {
let drag = plot_ui.pointer_coordinate_drag_delta();
if drag.length_sq() != 0.0 {
data.temp[idx] = (point.x as f32 + drag.x) as u8;
data.pwm[idx] = ((point.y as f32 + drag.y) * 255.0 / 100.0) as u8;
}
}
}
}
plot_ui.line(line);
plot_ui.points(points);
});
let mut set = false;
let mut clear = false;
let mut reset = false;
ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
set = ui.add(egui::Button::new("Apply Profile")).clicked();
clear = ui.add(egui::Button::new("Clear Profile Changes")).clicked();
reset = ui.add(egui::Button::new("Factory Reset Profile")).clicked();
});
if set {
dbus.proxies()
.fan_curves()
.set_fan_curve(curves.show_curve, data.clone())
.map_err(|err| {
*do_error = Some(err.to_string());
})
.ok();
}
if clear {
if let Ok(curve) = dbus
.proxies()
.fan_curves()
.fan_curve_data(curves.show_curve)
.map_err(|err| {
*do_error = Some(err.to_string());
})
{
if let Some(value) = curves.curves.get_mut(&curves.show_curve) {
*value = curve;
}
}
}
if reset {
dbus.proxies()
.fan_curves()
.reset_profile_curves(curves.show_curve)
.map_err(|err| {
*do_error = Some(err.to_string());
})
.ok();
match FanCurvesState::new(dbus) {
Ok(f) => *curves = f,
Err(e) => *do_error = Some(e.to_string()),
}
}
}

View File

@@ -1,220 +0,0 @@
use egui::{Color32, Pos2};
use rog_aura::advanced::LedCode;
use rog_aura::layouts::{KeyLayout, KeyShape};
use rog_aura::{AdvancedAuraType, AuraModeNum};
use crate::system_state::AuraState;
const SCALE: f32 = 2.0;
// TODO:
// - Multizone: draw regions? While iterating keys check if located in one of
// the 4 regions and mark
// - Tab for advanced effects
// - Keys need to select colour themselves
pub fn keyboard(
ui: &mut egui::Ui,
keyboard_layout: &KeyLayout,
states: &mut AuraState,
colour: Color32,
) {
let (keyboard_is_multizoned, keyboard_width, keyboard_is_per_key) =
match keyboard_layout.advanced_type() {
AdvancedAuraType::PerKey => (false, 0.0, true),
AdvancedAuraType::None => (false, keyboard_layout.max_width(), false),
AdvancedAuraType::Zoned(zones) => {
let width = if let Some(row) = keyboard_layout.rows_ref().get(2) {
row.width()
} else {
0.0
};
(!zones.contains(&LedCode::SingleZone), width, false)
}
};
let mut start_pos = None;
let y = ui.spacing().interact_size.y;
let this_size = ui.available_size();
let keys_width = keyboard_layout.max_width() * SCALE * y;
let keys_height = keyboard_layout.max_height() * SCALE * y;
let keyboard_height = keyboard_layout.keyboard_height() * SCALE;
let x_start = (this_size.x - keys_width) / SCALE;
let y_start = (this_size.y - keys_height) / SCALE;
// Initial colour states
let mut input_colour = colour;
let mut key_colour = colour;
if states.current_mode == AuraModeNum::Rainbow && !keyboard_is_per_key {
key_colour = Color32::from_rgb(
(states.wave_red[0] as u32 * 255 / 100) as u8,
(states.wave_green[0] as u32 * 255 / 100) as u8,
(states.wave_blue[0] as u32 * 255 / 100) as u8,
);
}
ui.spacing_mut().item_spacing = egui::vec2(0.0, 0.0);
blank(ui, 0.0, y_start / y);
for row in keyboard_layout.rows() {
ui.horizontal_top(|ui| {
blank(ui, x_start / y, 0.0);
for (i, key) in row.row().enumerate() {
// For per-key rainbow which cascades across
if states.current_mode == AuraModeNum::Rainbow && keyboard_is_per_key
|| key.0.is_lightbar_zone()
{
key_colour = Color32::from_rgb(
(states.wave_red[i] as u32 * 255 / 100) as u8,
(states.wave_green[i] as u32 * 255 / 100) as u8,
(states.wave_blue[i] as u32 * 255 / 100) as u8,
);
}
if (keyboard_is_multizoned && !key.0.is_lightbar_zone())
&& states.current_mode == AuraModeNum::Rainbow
{
input_colour = key_colour;
key_colour = Color32::TRANSPARENT;
}
let label = <&str>::from(key.0);
let mut shape = key.1.clone();
shape.scale(SCALE);
match shape {
KeyShape::Led {
width,
height,
pad_left,
pad_right,
pad_top,
pad_bottom,
} => {
let (pos, response) = key_shape(
ui, key_colour, width, height, pad_left, pad_right, pad_top, pad_bottom,
);
if start_pos.is_none() {
start_pos = Some(pos);
} else if let Some(old_pos) = start_pos.as_mut() {
if !key.0.is_lightbar_zone() {
if pos.x < old_pos.x {
old_pos.x = pos.x;
}
if pos.y < old_pos.y {
old_pos.y = pos.y;
}
}
}
if response.on_hover_text(label).clicked() && keyboard_is_per_key {
// TODO: set an effect on the LedCode
}
}
KeyShape::Blank { width, height } => {
blank(ui, width, height);
}
}
}
});
}
if keyboard_is_multizoned {
let zone_width = keyboard_width * SCALE / 4.0 - 0.1;
for n in 0..4 {
if states.current_mode == AuraModeNum::Rainbow {
input_colour = Color32::from_rgba_unmultiplied(
(states.wave_red[n] as u32 * 255 / 100) as u8,
(states.wave_green[n] as u32 * 255 / 100) as u8,
(states.wave_blue[n] as u32 * 255 / 100) as u8,
70,
);
}
if let Some(mut pos) = start_pos {
pos.x += n as f32 * zone_width * y;
let response = zone_shape(ui, input_colour, pos, zone_width, keyboard_height);
let label = format!("Zone {}", 1 + n);
if response.on_hover_text(label).clicked() {
// TODO: set an effect on the zone
}
}
}
}
}
#[allow(clippy::too_many_arguments)]
fn key_shape(
ui: &mut egui::Ui,
colour: Color32,
width: f32,
height: f32,
pad_left: f32,
pad_right: f32,
pad_top: f32,
pad_bottom: f32,
) -> (egui::Pos2, egui::Response) {
// First, get some space
let y = ui.spacing().interact_size.y;
let desired_size = y * egui::vec2(width + pad_left + pad_right, height + pad_top + pad_bottom);
let (mut rect, mut response) = ui.allocate_exact_size(desired_size, egui::Sense::click());
// rect = rect.shrink(3.0);
if response.clicked() {
response.mark_changed();
}
response.widget_info(|| {
egui::WidgetInfo::selected(egui::WidgetType::Checkbox, response.clicked(), "")
});
if ui.is_rect_visible(rect) {
// Now set the actual visible rect
let visuals = ui.style().interact_selectable(&response, true);
let size = y * egui::vec2(width, height);
rect.set_width(size.x);
rect.set_height(size.y);
let center = Pos2::new(
rect.center().x + pad_left * y,
rect.center().y + pad_top * y,
);
rect.set_center(center);
// let rect = rect.expand(visuals.expansion);
ui.painter().rect(rect, 0.1, colour, visuals.fg_stroke);
}
(rect.left_top(), response)
}
#[allow(clippy::too_many_arguments)]
fn zone_shape(
ui: &mut egui::Ui,
mut colour: Color32,
pos: Pos2,
width: f32,
height: f32,
) -> egui::Response {
// First, get some space
let y = ui.spacing().interact_size.y;
let desired_size = y * egui::vec2(width, height);
let rect = egui::Rect::from_min_size(pos, desired_size);
let mut response = ui.allocate_rect(rect, egui::Sense::click());
// rect = rect.shrink(3.0);
if response.clicked() {
response.mark_changed();
}
response.widget_info(|| {
egui::WidgetInfo::selected(egui::WidgetType::Checkbox, response.clicked(), "")
});
if ui.is_rect_visible(rect) {
// Now set the actual visible rect
let visuals = ui.style().interact_selectable(&response, true);
// let rect = rect.expand(visuals.expansion);
colour[3] = 20;
ui.painter().rect(rect, 0.1, colour, visuals.fg_stroke);
}
response
}
fn blank(ui: &mut egui::Ui, ux: f32, uy: f32) {
let desired_size = ui.spacing().interact_size.y * egui::vec2(ux, uy);
ui.allocate_exact_size(desired_size, egui::Sense::click());
}

View File

@@ -1,17 +0,0 @@
mod anime_power;
mod app_settings;
mod aura_modes;
mod aura_power;
mod fan_graph;
mod keyboard_layout;
mod rog_bios;
mod side_panel;
mod top_bar;
pub use anime_power::*;
pub use app_settings::*;
pub use aura_modes::*;
pub use aura_power::*;
pub use fan_graph::*;
pub use keyboard_layout::*;
pub use rog_bios::*;

View File

@@ -1,153 +0,0 @@
use egui::Ui;
use rog_platform::platform::{GpuMode, ThrottlePolicy};
use crate::system_state::SystemState;
pub fn platform_profile(states: &mut SystemState, ui: &mut Ui) {
if let Some(mut throttle) = states.bios.throttle {
ui.heading("Platform profile");
let mut item = |p: ThrottlePolicy, ui: &mut Ui| {
if ui
.selectable_value(&mut throttle, p, format!("{p:?}"))
.clicked()
{
states
.asus_dbus
.proxies()
.platform()
.set_throttle_thermal_policy(throttle)
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
}
};
ui.horizontal_wrapped(|ui| {
for a in ThrottlePolicy::list() {
item(a, ui);
}
});
}
}
pub fn rog_bios_group(states: &mut SystemState, ui: &mut Ui) {
ui.heading("Bios options");
if let Some(mut limit) = states.bios.charge_limit {
let slider = egui::Slider::new(&mut limit, 20..=100)
.text("Charging limit")
.step_by(1.0);
if ui.add(slider).drag_released() {
states
.asus_dbus
.proxies()
.platform()
.set_charge_control_end_threshold(limit)
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
}
}
if let Some(mut sound) = states.bios.post_sound {
if ui
.add(egui::Checkbox::new(&mut sound, "POST sound"))
.changed()
{
states
.asus_dbus
.proxies()
.platform()
.set_post_animation_sound(sound)
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
}
}
if let Some(mut overdrive) = states.bios.panel_overdrive {
if ui
.add(egui::Checkbox::new(&mut overdrive, "Panel overdrive"))
.changed()
{
states
.asus_dbus
.proxies()
.platform()
.set_panel_od(overdrive)
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
}
}
if let Some(mut mini_led_mode) = states.bios.mini_led_mode {
if ui
.add(egui::Checkbox::new(&mut mini_led_mode, "MiniLED backlight"))
.changed()
{
states
.asus_dbus
.proxies()
.platform()
.set_mini_led_mode(mini_led_mode)
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
}
}
if let Some(mut gpu_mux_mode) = states.bios.gpu_mux_mode {
let mut changed = false;
let mut reboot_required = false;
if let Ok(mode) = states.asus_dbus.proxies().platform().gpu_mux_mode() {
reboot_required = GpuMode::from(mode) != gpu_mux_mode;
}
ui.group(|ui| {
ui.vertical(|ui| {
ui.horizontal_wrapped(|ui| ui.label("GPU MUX mode"));
ui.horizontal_wrapped(|ui| ui.label("NOTE: Value does not change until rebooted"));
ui.horizontal_wrapped(|ui| {
changed = ui
.selectable_value(
&mut gpu_mux_mode,
GpuMode::Discrete,
"Dedicated (Ultimate)",
)
.clicked()
|| ui
.selectable_value(
&mut gpu_mux_mode,
GpuMode::Optimus,
"Optimus (Hybrid)",
)
.clicked();
});
if reboot_required {
ui.horizontal_wrapped(|ui| ui.heading("REBOOT REQUIRED"));
}
});
});
if changed {
states
.asus_dbus
.proxies()
.platform()
.set_gpu_mux_mode(gpu_mux_mode)
.map_err(|err| {
states.error = Some(err.to_string());
})
.ok();
}
}
}

View File

@@ -1,72 +0,0 @@
use crate::{Page, RogApp};
impl RogApp {
pub fn side_panel(&mut self, ctx: &eframe::egui::Context) {
egui::SidePanel::left("side_panel")
.resizable(false)
.default_width(60.0) // TODO: set size to match icon buttons when done
.show(ctx, |ui| {
let Self { page, .. } = self;
ui.heading("Functions");
ui.separator();
if ui
.selectable_value(page, Page::System, "System Settings")
.clicked()
{
*page = Page::System;
}
if self.supported_interfaces.contains(&"FanCurves".to_owned()) {
ui.separator();
if ui
.selectable_value(page, Page::FanCurves, "Fan Curves")
.clicked()
{
*page = Page::FanCurves;
}
}
if self.supported_interfaces.contains(&"Aura".to_owned()) {
ui.separator();
if ui
.selectable_value(page, Page::AuraEffects, "Keyboard Aura")
.clicked()
{
*page = Page::AuraEffects;
}
}
// TODO: Anime page is not complete
if self.supported_interfaces.contains(&"Anime".to_owned()) {
ui.separator();
if ui
.selectable_value(page, Page::AnimeMatrix, "AniMe Matrix")
.clicked()
{
*page = Page::AnimeMatrix;
}
}
ui.separator();
if ui
.selectable_value(page, Page::AppSettings, "App Settings")
.clicked()
{
*page = Page::AppSettings;
}
ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| {
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 0.0;
ui.label("Source code ");
ui.hyperlink_to(
"rog-gui.",
"https://gitlab.com/asus-linux/asusctl/-/tree/main/rog-control-center",
);
});
});
});
}
}

View File

@@ -1,77 +0,0 @@
use egui::{vec2, Align2, Button, FontId, Id, Rect, RichText, Sense, Vec2};
use crate::{RogApp, VERSION};
impl RogApp {
pub fn top_bar(&mut self, ctx: &eframe::egui::Context, frame: &mut eframe::Frame) {
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
// The top panel is often a good place for a menu bar:
egui::menu::bar(ui, |ui| {
ui.horizontal(|ui| {
self.dark_light_mode_buttons(ui);
egui::warn_if_debug_build(ui);
});
// Drag area
let text_color = ctx.style().visuals.text_color();
let mut titlebar_rect = ui.available_rect_before_wrap();
titlebar_rect.max.x -= titlebar_rect.height();
if ui
.interact(titlebar_rect, Id::new("title_bar"), Sense::drag())
.drag_started()
{
frame.drag_window();
}
let height = titlebar_rect.height();
// Paint the title:
ui.painter().text(
titlebar_rect.right_top() + vec2(0.0, height / 2.0),
Align2::RIGHT_CENTER,
format!("v{}", VERSION),
FontId::proportional(height - 2.0),
text_color,
);
// Add the close button:
let close_response = ui.put(
Rect::from_min_size(titlebar_rect.right_top(), Vec2::splat(height)),
Button::new(RichText::new("").size(height - 4.0)).frame(false),
);
if close_response.clicked() {
frame.close();
}
});
});
}
fn dark_light_mode_buttons(&mut self, ui: &mut egui::Ui) {
let load_from_cfg = self.config.dark_mode != ui.ctx().style().visuals.dark_mode;
if ui
.add(egui::SelectableLabel::new(
!self.config.dark_mode,
"☀ Light",
))
.clicked()
|| (load_from_cfg && !self.config.dark_mode)
{
ui.ctx().set_visuals(egui::Visuals::light());
}
if ui
.add(egui::SelectableLabel::new(self.config.dark_mode, "🌙 Dark"))
.clicked()
|| (load_from_cfg && self.config.dark_mode)
{
ui.ctx().set_visuals(egui::Visuals::dark());
}
let applied_dark_mode = ui.ctx().style().visuals.dark_mode;
if self.config.dark_mode != applied_dark_mode {
self.config.dark_mode = applied_dark_mode;
let tmp = self.config.enabled_notifications.clone();
self.config.save(&tmp).ok();
}
}
}

View File

@@ -0,0 +1,246 @@
import { VerticalBox , StandardButton, Button} from "std-widgets.slint";
import { Theme } from "globals.slint";
export component SquareImageButton inherits Rectangle {
// if (AppConsts.sdfsdf.length < 0): Rectangle { background: red; }
callback clicked;
in-out property <image> img;
border-radius: 7px;
border-width: 2px;
border-color: Theme.control-outline;
background: Theme.image-button-background;
touch := TouchArea {
clicked => {
root.clicked();
}
}
Image {
height: 90%;
width: 90%;
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
source <=> root.img;
image-fit: contain;
// colorize: Theme.control-secondary;
}
}
export component RoundImageButton inherits Rectangle {
callback clicked;
in-out property <image> img;
in property <length> size;
width: self.size;
height: self.size;
border-radius: root.width / 2;
border-width: 6px;
border-color: Theme.control-outline;
background: Theme.image-button-background;
touch := TouchArea {
clicked => {
root.clicked();
}
}
Image {
height: 60%;
width: 60%;
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
source <=> root.img;
image-fit: contain;
// colorize: Theme.control-secondary;
}
}
export component SquareCharButton inherits Rectangle {
callback clicked;
in-out property <string> char;
border-radius: 7px;
border-width: 2px;
border-color: Theme.control-outline;
background: Theme.image-button-background;
touch := TouchArea {
clicked => {
root.clicked();
}
}
Text {
// height: 90%;
// width: 90%;
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
text: char;
font-size: 28px;
font-weight: 900;
horizontal-alignment: center;
vertical-alignment: center;
color: Theme.control-foreground;
}
}
// A variable bar that can be single or double ended
export component ValueBar inherits Rectangle {
in property <float> value: 0.0;
in property <float> min: 0.0;
in property <float> max: 1.0;
function percentage(min: float, max: float, value: float) -> float{
if (min < 0.0 && max > 0.0) {
// do a percentage of each half as 0-50%
if (value >= max + min) {
return (value - (max + min) / 2) / (max - min);
}
return 0.50 - (value - (min - max) / 2) / (max - min);
}
return (value - min) / (max - min);
}
function set_x(min: float, max: float, value: float, width: length) -> length{
if (min < 0.0 && max > 0.0) {
if (value < max + min) {
return width / 2 - width * (percentage(min, max, value));
}
return width / 2;
}
return 0;
}
Rectangle {
border-radius: 3px;
background: Theme.neutral-box;
Rectangle {
x: set_x(root.min, root.max, root.value, root.width);
width: parent.x + parent.width * percentage(root.min, root.max, root.value);
border-radius: parent.border-radius;
background: Theme.control-secondary;
}
Text {
vertical-alignment: center;
horizontal-alignment: center;
text: root.value;
font-size: root.height;
font-weight: 900;
color: Theme.control-foreground;
}
}
}
// Single direction spinbox
export component SpinBoxUni inherits Rectangle {
in-out property <int> value;
in property <int> minimum;
in property <int> maximum: 100;
height: 32px;
HorizontalLayout {
spacing: 12px;
padding: 0;
SquareCharButton {
width: root.height - parent.padding * 2;
char: "-";
clicked => {
if (root.value > root.minimum) {
root.value -= 1;
}
}
}
Rectangle {
border-radius: 3px;
border-width: 2px;
border-color: Theme.control-outline;
// TODO: replace with visual min/max drawing
Text {
width: 100%;
height: 100%;
vertical-alignment: center;
horizontal-alignment: center;
text: root.value;
color: Theme.control-foreground;
}
}
SquareCharButton {
width: root.height - parent.padding * 2;
char: "+";
clicked => {
if (root.value < root.maximum) {
root.value += 1;
}
}
}
}
}
export component PopupNotification {
in property <string> heading;
in property <string> content;
_p := PopupWindow {
x: root.x;
y: root.y;
width: root.width;
height: root.height;
// TODO: add properties to display
Rectangle {
border-width: 2px;
border-color: Theme.control-outline;
background: Theme.notification-background;
// TODO: drop shadows slow
// drop-shadow-offset-x: 7px;
// drop-shadow-offset-y: 7px;
// drop-shadow-color: black;
// drop-shadow-blur: 30px;
VerticalLayout {
Dialog {
VerticalLayout {
alignment: start;
Text {
text: heading;
color: Theme.text-foreground-color;
font-size: 32px;
font-weight: 900;
}
Text {
text: content;
color: Theme.text-foreground-color;
font-size: 18px;
}
}
StandardButton {
kind: ok;
}
StandardButton {
kind: cancel;
}
Button {
text: "More Info";
dialog-button-role: action;
}
}
}
}
}
public function show() {
_p.show();
}
}

View File

@@ -0,0 +1,39 @@
struct ButtonColours {
base: color,
pressed: color,
hovered: color,
}
export global AppSize {
out property <length> width: 800px;
out property <length> height: 480px;
}
export global Theme {
out property <color> window-background: #000000;
out property <color> neutral-box: #BDC0D1;
// The background colour of pages and bars
out property <color> background-color: root.dark-mode ? #12387b : white;
out property <color> text-foreground-color: root.dark-mode ? #F4F6FF : black;
out property <color> secondary-foreground-color: root.dark-mode ? #C1C3CA : #6C6E7A;
out property <color> image-button-background: root.dark-mode ? root.window-background : white;
out property <color> toolbar-background: root.background-color;
out property <color> notification-border: root.background-color;
out property <color> notification-background: root.background-color;
out property <color> control-outline: #FFBF63;
out property <color> control-secondary: #6284FF;
out property <color> control-foreground: root.dark-mode ? white : #122F7B;
out property <color> push-button-base: #FFBF63;
out property <ButtonColours> push-button: {
base: root.push-button-base,
pressed: root.push-button-base.darker(40%),
hovered: root.push-button-base.darker(20%),
};
out property <color> push-button-text-color: white;
out property <length> base-font-size: 16px;
in property <bool> dark-mode: true;
}
export global IconImages {
//out property <image> two_t: @image-url("images/parameters/2t.png");
}

View File

@@ -0,0 +1,120 @@
import { Button, VerticalBox } from "std-widgets.slint";
import { SpinBoxUni, ValueBar, SquareImageButton, RoundImageButton } from "common_widgets.slint";
import { Theme, AppSize } from "globals.slint";
import { PageSystem } from "pages/system.slint";
import { SideBar } from "widgets/sidebar.slint";
import { PageAbout } from "pages/about.slint";
import { PageGpu } from "pages/gpu.slint";
import { PageFans } from "pages/fans.slint";
import { PageAnime } from "pages/anime.slint";
import { PageAura } from "pages/aura.slint";
export { AppSize, Theme }
export component MainWindow inherits Window {
default-font-family: "DejaVu Sans";
private property <bool> show-notif;
private property <bool> fade-cover;
callback exit-app();
callback request-increase-value();
callback show-notification(bool);
show-notification(yes) => {
show-notif = yes;
fade-cover = yes;
}
height: AppSize.height;
width: AppSize.width;
background: Colors.orange;
HorizontalLayout {
padding: 0px;
side-bar := SideBar {
title: @tr("ROG");
model: [
@tr("Menu" => "System Control"),
@tr("Menu" => "Keyboard Aura"),
@tr("Menu" => "AniMe Matrix"),
@tr("Menu" => "Fan Curves"),
@tr("Menu" => "GPU Control"),
@tr("Menu" => "About"),
];
}
Rectangle {
background: Colors.purple;
if(side-bar.current-item == 0): PageSystem {
width: root.width - side-bar.width;
height: root.height + 12px;
}
if(side-bar.current-item == 1): PageAura {
width: root.width - side-bar.width;
}
if(side-bar.current-item == 2): PageAnime {
width: root.width - side-bar.width;
}
if(side-bar.current-item == 3): PageFans {
width: root.width - side-bar.width;
}
if(side-bar.current-item == 4): PageGpu {
width: root.width - side-bar.width;
}
if(side-bar.current-item == 5): PageAbout {
width: root.width - side-bar.width;
}
}
}
if fade-cover: Rectangle {
x: 0px;
y: 0px;
width: root.width;
height: root.height;
background: Colors.rgba(25,33,23,20);
opacity: 0.7;
TouchArea {
height: 100%;
width: 100%;
clicked => {
// toolbar-dropdown.close();
if (show-notif) {
show-notif = false;
}
fade-cover = false;
}
}
}
// // TODO: or use Dialogue
if show-notif: Rectangle {
x: root.width / 8;
y: root.height / 8;
height: (root.height / 8) * 6;
width: (root.width / 8) * 6;
TouchArea {
height: 100%;
width: 100%;
clicked => {
show-notif = false;
exit-app();
}
}
// TODO: add properties to display
Rectangle {
height: 100%;
width: 100%;
background: Theme.neutral-box;
Text {
text: "Click here to exit";
}
}
}
}

View File

@@ -0,0 +1,18 @@
import { ValueBar } from "../common_widgets.slint";
import { Theme } from "../globals.slint";
import { AboutSlint } from "std-widgets.slint";
export component PageAbout inherits VerticalLayout {
Rectangle {
clip: true;
// TODO: slow with border-radius
padding: 8px;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
// TODO: border-radius: 8px;
mainview := VerticalLayout {
padding: 10px;
spacing: 10px;
AboutSlint {}
}
}
}

View File

@@ -0,0 +1,50 @@
import { ValueBar } from "../common_widgets.slint";
import { Theme } from "../globals.slint";
export component PageAnime inherits VerticalLayout {
Rectangle {
clip: true;
// TODO: slow with border-radius
padding: 8px;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
// TODO: border-radius: 8px;
mainview := VerticalLayout {
padding: 10px;
spacing: 10px;
ValueBar {
height: 40px;
value: 10.5;
min: 0.0;
max: 100.0;
}
ValueBar {
height: 40px;
value: -70;
min: -100;
max: 0;
}
ValueBar {
height: 80px;
value: 40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
}
}
}

View File

@@ -0,0 +1,50 @@
import { ValueBar } from "../common_widgets.slint";
import { Theme } from "../globals.slint";
export component PageAura inherits VerticalLayout {
Rectangle {
clip: true;
// TODO: slow with border-radius
padding: 8px;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
// TODO: border-radius: 8px;
mainview := VerticalLayout {
padding: 10px;
spacing: 10px;
ValueBar {
height: 40px;
value: 10.5;
min: 0.0;
max: 100.0;
}
ValueBar {
height: 40px;
value: -70;
min: -100;
max: 0;
}
ValueBar {
height: 80px;
value: 40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
}
}
}

View File

@@ -0,0 +1,50 @@
import { ValueBar } from "../common_widgets.slint";
import { Theme } from "../globals.slint";
export component PageFans inherits VerticalLayout {
Rectangle {
clip: true;
// TODO: slow with border-radius
padding: 8px;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
// TODO: border-radius: 8px;
mainview := VerticalLayout {
padding: 10px;
spacing: 10px;
ValueBar {
height: 40px;
value: 10.5;
min: 0.0;
max: 100.0;
}
ValueBar {
height: 40px;
value: -70;
min: -100;
max: 0;
}
ValueBar {
height: 80px;
value: 40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
}
}
}

View File

@@ -0,0 +1,50 @@
import { ValueBar } from "../common_widgets.slint";
import { Theme } from "../globals.slint";
export component PageGpu inherits VerticalLayout {
Rectangle {
clip: true;
// TODO: slow with border-radius
padding: 8px;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
// TODO: border-radius: 8px;
mainview := VerticalLayout {
padding: 10px;
spacing: 10px;
ValueBar {
height: 40px;
value: 10.5;
min: 0.0;
max: 100.0;
}
ValueBar {
height: 40px;
value: -70;
min: -100;
max: 0;
}
ValueBar {
height: 80px;
value: 40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
}
}
}

View File

@@ -0,0 +1,113 @@
import { ValueBar } from "../common_widgets.slint";
import { Theme } from "../globals.slint";
import { HorizontalBox , VerticalBox, ScrollView} from "std-widgets.slint";
export component PageSystem inherits Rectangle {
background: Theme.background-color;
ScrollView {
VerticalLayout {
// padding: 10px;
spacing: 10px;
min-height: root.height;
Rectangle {
background: Theme.background-color;
VerticalBox {
Text {
color: Theme.text-foreground-color;
text: @tr("ChargeMode" => "Charging mode");
}
Text {
color: Theme.text-foreground-color;
text: @tr("ChargeLimit" => "Charge limit");
}
}
}
Rectangle {
background: Theme.background-color;
VerticalBox {
Text {
color: Theme.text-foreground-color;
text: @tr("PanelOverdrive" => "Panel Overdrive");
}
Text {
color: Theme.text-foreground-color;
text: @tr("PerformanceProfile" => "Performance Profile");
}
}
}
Rectangle {
background: Theme.background-color;
VerticalBox {
Text {
color: Theme.text-foreground-color;
text: @tr("nv_dynamic_boost" => "nv_dynamic_boost");
}
Text {
color: Theme.text-foreground-color;
text: @tr("nv_temp_target" => "nv_temp_target");
}
Text {
color: Theme.text-foreground-color;
text: @tr("ppt_pl1_spl" => "ppt_pl1_spl");
}
Text {
color: Theme.text-foreground-color;
text: @tr("ppt_pl2_sppt" => "ppt_pl2_sppt");
}
}
}
Rectangle {
background: Theme.background-color;
VerticalBox {
Text {
color: Theme.text-foreground-color;
text: @tr("PanelOverdrive" => "Panel Overdrive");
}
Text {
color: Theme.text-foreground-color;
text: @tr("PerformanceProfile" => "Performance Profile");
}
}
}
Rectangle {
background: Theme.background-color;
VerticalBox {
Text {
color: Theme.text-foreground-color;
text: @tr("PanelOverdrive" => "Panel Overdrive");
}
Text {
color: Theme.text-foreground-color;
text: @tr("PerformanceProfile" => "Performance Profile");
}
}
}
Rectangle {
background: Theme.background-color;
VerticalBox {
Text {
color: Theme.text-foreground-color;
text: @tr("PanelOverdrive" => "Panel Overdrive");
}
Text {
color: Theme.text-foreground-color;
text: @tr("PerformanceProfile" => "Performance Profile");
}
}
}
}
}
}

View File

@@ -0,0 +1,125 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { StyleMetrics } from "std-widgets.slint";
component SideBarItem inherits Rectangle {
in property <bool> selected;
in property <bool> has-focus;
in-out property <string> text<=> label.text;
callback clicked<=>touch.clicked;
min-height: l.preferred-height;
states [
pressed when touch.pressed: {
state.opacity: 0.8;
}
hover when touch.has-hover: {
state.opacity: 0.6;
}
selected when root.selected: {
state.opacity: 1;
}
focused when root.has-focus: {
state.opacity: 0.8;
}
]
state := Rectangle {
opacity: 0;
background: StyleMetrics.window-background;
animate opacity{ duration: 150ms;
}
}
l := HorizontalLayout {
y: (parent.height - self.height) / 2;
padding: StyleMetrics.layout-padding;
spacing: 0px;
label := Text {
color: StyleMetrics.default-text-color;
vertical-alignment: center;
}
}
touch := TouchArea {
width: 100%;
height: 100%;
}
}
export component SideBar inherits Rectangle {
in property <[string]> model: [];
in property <string> title<=> label.text;
out property <int> current-item: 0;
out property <int> current-focused: fs.has-focus ? fs.focused-tab : -1;
// The currently focused tab
width: 180px;
forward-focus: fs;
accessible-role: tab;
accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current-item;
Rectangle {
background: StyleMetrics.window-background.darker(0.2);
fs := FocusScope {
key-pressed(event) => {
if (event.text == "\n") {
root.current-item = root.current-focused;
return accept;
}
if (event.text == Key.UpArrow) {
self.focused-tab = Math.max(self.focused-tab - 1, 0);
return accept;
}
if (event.text == Key.DownArrow) {
self.focused-tab = Math.min(self.focused-tab + 1, root.model.length - 1);
return accept;
}
return reject;
}
key-released(event) => {
if (event.text == " ") {
root.current-item = root.current-focused;
return accept;
}
return reject;
}
property <int> focused-tab: 0;
x: 0;
width: 0;
// Do not react on clicks
}
}
VerticalLayout {
padding-top: StyleMetrics.layout-padding;
padding-bottom: StyleMetrics.layout-padding;
spacing: StyleMetrics.layout-spacing;
alignment: start;
label := Text {
font-size: 16px;
horizontal-alignment: center;
}
navigation := VerticalLayout {
alignment: start;
vertical-stretch: 0;
for item [index] in root.model: SideBarItem {
clicked => {
root.current-item = index;
}
has-focus: index == root.current-focused;
text: item;
selected: index == root.current-item;
}
}
VerticalLayout {
bottom := VerticalLayout {
padding-left: StyleMetrics.layout-padding;
padding-right: StyleMetrics.layout-padding;
@children
}
}
}
}

View File

@@ -1,8 +1,8 @@
use rog_anime::usb::Brightness;
use rog_anime::{Animations, AnimeDataBuffer, DeviceState as AnimeDeviceState};
use zbus::dbus_proxy;
use zbus::proxy;
#[dbus_proxy(
#[proxy(
interface = "org.asuslinux.Daemon",
default_service = "org.asuslinux.Daemon",
default_path = "/org/asuslinux/Anime"
@@ -18,48 +18,48 @@ trait Anime {
fn write(&self, input: AnimeDataBuffer) -> zbus::Result<()>;
/// NotifyDeviceState signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn notify_device_state(&self, data: AnimeDeviceState) -> zbus::Result<()>;
/// Brightness property
#[dbus_proxy(property)]
#[zbus(property)]
fn brightness(&self) -> zbus::Result<Brightness>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_brightness(&self, value: Brightness) -> zbus::Result<()>;
/// BuiltinAnimations property
#[dbus_proxy(property)]
#[zbus(property)]
fn builtin_animations(&self) -> zbus::Result<Animations>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_builtin_animations(&self, value: Animations) -> zbus::Result<()>;
/// BuiltinsEnabled property
#[dbus_proxy(property)]
#[zbus(property)]
fn builtins_enabled(&self) -> zbus::Result<bool>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_builtins_enabled(&self, value: bool) -> zbus::Result<()>;
/// EnableDisplay property
#[dbus_proxy(property)]
#[zbus(property)]
fn enable_display(&self) -> zbus::Result<bool>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_enable_display(&self, value: bool) -> zbus::Result<()>;
/// OffWhenLidClosed property
#[dbus_proxy(property)]
#[zbus(property)]
fn off_when_lid_closed(&self) -> zbus::Result<bool>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_off_when_lid_closed(&self, value: bool) -> zbus::Result<()>;
/// OffWhenSuspended property
#[dbus_proxy(property)]
#[zbus(property)]
fn off_when_suspended(&self) -> zbus::Result<bool>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_off_when_suspended(&self, value: bool) -> zbus::Result<()>;
/// OffWhenUnplugged property
#[dbus_proxy(property)]
#[zbus(property)]
fn off_when_unplugged(&self) -> zbus::Result<bool>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_off_when_unplugged(&self, value: bool) -> zbus::Result<()>;
}

View File

@@ -27,11 +27,11 @@ use rog_aura::aura_detection::PowerZones;
use rog_aura::usb::{AuraDevice, AuraPowerDev};
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness};
use zbus::blocking::Connection;
use zbus::{dbus_proxy, Result};
use zbus::{proxy, Result};
const BLOCKING_TIME: u64 = 33; // 100ms = 10 FPS, max 50ms = 20 FPS, 40ms = 25 FPS
#[dbus_proxy(
#[proxy(
interface = "org.asuslinux.Daemon",
default_service = "org.asuslinux.Daemon",
default_path = "/org/asuslinux/Aura"
@@ -44,47 +44,47 @@ trait Aura {
fn direct_addressing_raw(&self, data: UsbPackets) -> zbus::Result<()>;
/// Brightness property
#[dbus_proxy(property)]
#[zbus(property)]
fn brightness(&self) -> zbus::Result<LedBrightness>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_brightness(&self, value: LedBrightness) -> zbus::Result<()>;
/// DeviceType property
#[dbus_proxy(property)]
#[zbus(property)]
fn device_type(&self) -> zbus::Result<AuraDevice>;
/// LedMode property
#[dbus_proxy(property)]
#[zbus(property)]
fn led_mode(&self) -> zbus::Result<AuraModeNum>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_led_mode(&self, value: AuraModeNum) -> zbus::Result<()>;
/// LedModeData property
#[dbus_proxy(property)]
#[zbus(property)]
fn led_mode_data(&self) -> zbus::Result<AuraEffect>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_led_mode_data(&self, value: AuraEffect) -> zbus::Result<()>;
/// LedPower property
#[dbus_proxy(property)]
#[zbus(property)]
fn led_power(&self) -> zbus::Result<AuraPowerDev>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_led_power(&self, value: (AuraPowerDev, bool)) -> zbus::Result<()>;
/// SupportedBrightness property
#[dbus_proxy(property)]
#[zbus(property)]
fn supported_brightness(&self) -> zbus::Result<Vec<LedBrightness>>;
/// SupportedBasicModes property
#[dbus_proxy(property)]
#[zbus(property)]
fn supported_basic_modes(&self) -> zbus::Result<Vec<AuraModeNum>>;
/// SupportedBasicZones property
#[dbus_proxy(property)]
#[zbus(property)]
fn supported_basic_zones(&self) -> zbus::Result<Vec<AuraZone>>;
/// SupportedPowerZones property
#[dbus_proxy(property)]
#[zbus(property)]
fn supported_power_zones(&self) -> zbus::Result<Vec<PowerZones>>;
}

View File

@@ -23,9 +23,9 @@
use rog_platform::platform::ThrottlePolicy;
use rog_profiles::fan_curve_set::CurveData;
use rog_profiles::FanCurvePU;
use zbus::dbus_proxy;
use zbus::proxy;
#[dbus_proxy(
#[proxy(
interface = "org.asuslinux.Daemon",
default_service = "org.asuslinux.Daemon",
default_path = "/org/asuslinux/FanCurves"

View File

@@ -21,9 +21,9 @@
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
use rog_platform::platform::{GpuMode, Properties, ThrottlePolicy};
use zbus::dbus_proxy;
use zbus::proxy;
#[dbus_proxy(
#[proxy(
interface = "org.asuslinux.Daemon",
default_service = "org.asuslinux.Daemon",
default_path = "/org/asuslinux/Platform"
@@ -39,88 +39,88 @@ trait Platform {
fn supported_properties(&self) -> zbus::Result<Vec<Properties>>;
/// ChargeControlEndThreshold property
#[dbus_proxy(property)]
#[zbus(property)]
fn charge_control_end_threshold(&self) -> zbus::Result<u8>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_charge_control_end_threshold(&self, value: u8) -> zbus::Result<()>;
/// DgpuDisable property
#[dbus_proxy(property)]
#[zbus(property)]
fn dgpu_disable(&self) -> zbus::Result<bool>;
/// EgpuEnable property
#[dbus_proxy(property)]
#[zbus(property)]
fn egpu_enable(&self) -> zbus::Result<bool>;
/// GpuMuxMode property
#[dbus_proxy(property)]
#[zbus(property)]
fn gpu_mux_mode(&self) -> zbus::Result<u8>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_gpu_mux_mode(&self, value: GpuMode) -> zbus::Result<()>;
/// MiniLedMode property
#[dbus_proxy(property)]
#[zbus(property)]
fn mini_led_mode(&self) -> zbus::Result<bool>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_mini_led_mode(&self, value: bool) -> zbus::Result<()>;
/// NvDynamicBoost property
#[dbus_proxy(property)]
#[zbus(property)]
fn nv_dynamic_boost(&self) -> zbus::Result<u8>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_nv_dynamic_boost(&self, value: u8) -> zbus::Result<()>;
/// NvTempTarget property
#[dbus_proxy(property)]
#[zbus(property)]
fn nv_temp_target(&self) -> zbus::Result<u8>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_nv_temp_target(&self, value: u8) -> zbus::Result<()>;
/// PanelOd property
#[dbus_proxy(property)]
#[zbus(property)]
fn panel_od(&self) -> zbus::Result<bool>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_panel_od(&self, value: bool) -> zbus::Result<()>;
/// PostAnimationSound property
#[dbus_proxy(property)]
#[zbus(property)]
fn post_animation_sound(&self) -> zbus::Result<bool>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_post_animation_sound(&self, value: bool) -> zbus::Result<()>;
/// PptApuSppt property
#[dbus_proxy(property)]
#[zbus(property)]
fn ppt_apu_sppt(&self) -> zbus::Result<u8>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_ppt_apu_sppt(&self, value: u8) -> zbus::Result<()>;
/// PptFppt property
#[dbus_proxy(property)]
#[zbus(property)]
fn ppt_fppt(&self) -> zbus::Result<u8>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_ppt_fppt(&self, value: u8) -> zbus::Result<()>;
/// PptPl1Spl property
#[dbus_proxy(property)]
#[zbus(property)]
fn ppt_pl1_spl(&self) -> zbus::Result<u8>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_ppt_pl1_spl(&self, value: u8) -> zbus::Result<()>;
/// PptPl2Sppt property
#[dbus_proxy(property)]
#[zbus(property)]
fn ppt_pl2_sppt(&self) -> zbus::Result<u8>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_ppt_pl2_sppt(&self, value: u8) -> zbus::Result<()>;
/// PptPlatformSppt property
#[dbus_proxy(property)]
#[zbus(property)]
fn ppt_platform_sppt(&self) -> zbus::Result<u8>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_ppt_platform_sppt(&self, value: u8) -> zbus::Result<()>;
/// ThrottlePolicy property
#[dbus_proxy(property)]
#[zbus(property)]
fn throttle_thermal_policy(&self) -> zbus::Result<ThrottlePolicy>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_throttle_thermal_policy(&self, value: ThrottlePolicy) -> zbus::Result<()>;
}