mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Major cleanup of older gui state code
This commit is contained in:
@@ -23,22 +23,12 @@ pub mod types;
|
||||
pub mod ui;
|
||||
pub mod update_and_notify;
|
||||
|
||||
#[cfg(feature = "mocking")]
|
||||
pub use mocking::RogDbusClientBlocking;
|
||||
use nix::sys::stat;
|
||||
use nix::unistd;
|
||||
#[cfg(not(feature = "mocking"))]
|
||||
pub use rog_dbus::RogDbusClientBlocking;
|
||||
use tempfile::TempDir;
|
||||
// use log::{error, info, warn};
|
||||
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
#[cfg(not(feature = "mocking"))]
|
||||
const DATA_DIR: &str = "/usr/share/rog-gui/";
|
||||
#[cfg(feature = "mocking")]
|
||||
const DATA_DIR: &str = env!("CARGO_MANIFEST_DIR");
|
||||
const BOARD_NAME: &str = "/sys/class/dmi/id/board_name";
|
||||
pub const APP_ICON_PATH: &str = "/usr/share/icons/hicolor/512x512/apps/rog-control-center.png";
|
||||
|
||||
pub fn print_versions() {
|
||||
|
||||
@@ -15,19 +15,28 @@ use rog_control_center::cli_options::CliStart;
|
||||
use rog_control_center::config::Config;
|
||||
use rog_control_center::error::Result;
|
||||
use rog_control_center::slint::ComponentHandle;
|
||||
use rog_control_center::system_state::{AuraCreation, SystemState};
|
||||
use rog_control_center::system_state::SystemState;
|
||||
use rog_control_center::tray::init_tray;
|
||||
use rog_control_center::ui::setup_window;
|
||||
use rog_control_center::update_and_notify::{start_notifications, EnabledNotifications};
|
||||
use rog_control_center::{
|
||||
get_ipc_file, on_tmp_dir_exists, print_versions, MainWindow, RogDbusClientBlocking, QUIT_APP,
|
||||
SHOWING_GUI, SHOW_GUI,
|
||||
get_ipc_file, on_tmp_dir_exists, print_versions, MainWindow, QUIT_APP, SHOWING_GUI, SHOW_GUI,
|
||||
};
|
||||
use tokio::runtime::Runtime;
|
||||
// use winit::monitor::VideoMode;
|
||||
// use winit::window::{Fullscreen, WindowLevel};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let self_version = env!("CARGO_PKG_VERSION");
|
||||
let conn = zbus::blocking::Connection::system()?;
|
||||
let proxy = rog_dbus::zbus_platform::PlatformProxyBlocking::new(&conn)?;
|
||||
let asusd_version = proxy.version().unwrap();
|
||||
if asusd_version != self_version {
|
||||
println!("Version mismatch: asusctl = {self_version}, asusd = {asusd_version}");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let dmi = DMIID::new().unwrap_or_default();
|
||||
let board_name = dmi.board_name;
|
||||
let prod_family = dmi.product_family;
|
||||
@@ -70,13 +79,7 @@ fn main() -> Result<()> {
|
||||
// Enter the runtime so that `tokio::spawn` is available immediately.
|
||||
let _enter = rt.enter();
|
||||
|
||||
let (dbus, _) = RogDbusClientBlocking::new()
|
||||
.map_err(|_| {
|
||||
// TODO: show an error window
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let supported_properties = match dbus.proxies().platform().supported_properties() {
|
||||
let supported_properties = match proxy.supported_properties() {
|
||||
Ok(s) => s,
|
||||
Err(_e) => {
|
||||
// TODO: show an error window
|
||||
@@ -113,10 +116,9 @@ fn main() -> Result<()> {
|
||||
config.write();
|
||||
|
||||
let enabled_notifications = EnabledNotifications::tokio_mutex(&config);
|
||||
let aura_creation = AuraCreation::new(cli_parsed.board_name, cli_parsed.layout_viewing)?;
|
||||
|
||||
// TODO: config mutex to share config in various places
|
||||
let states = setup_page_state_and_notifs(aura_creation, &enabled_notifications, &config)?;
|
||||
let states = setup_page_state_and_notifs(&enabled_notifications, &config).await?;
|
||||
|
||||
let enable_tray_icon = config.enable_tray_icon;
|
||||
let startup_in_background = config.startup_in_background;
|
||||
@@ -214,17 +216,18 @@ fn main() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn setup_page_state_and_notifs(
|
||||
aura_creation: AuraCreation,
|
||||
async fn setup_page_state_and_notifs(
|
||||
enabled_notifications: &Arc<Mutex<EnabledNotifications>>,
|
||||
config: &Config,
|
||||
) -> Result<Arc<Mutex<SystemState>>> {
|
||||
let page_states = Arc::new(Mutex::new(SystemState::new(
|
||||
aura_creation,
|
||||
enabled_notifications.clone(),
|
||||
config.enable_tray_icon,
|
||||
config.run_in_background,
|
||||
)?));
|
||||
let page_states = Arc::new(Mutex::new(
|
||||
SystemState::new(
|
||||
enabled_notifications.clone(),
|
||||
config.enable_tray_icon,
|
||||
config.run_in_background,
|
||||
)
|
||||
.await?,
|
||||
));
|
||||
|
||||
start_notifications(config, &page_states, enabled_notifications)?;
|
||||
|
||||
@@ -261,8 +264,10 @@ fn setup_page_state_and_notifs(
|
||||
// IconData {
|
||||
// height,
|
||||
// width,
|
||||
// rgba,
|
||||
// }
|
||||
// rgba
|
||||
//
|
||||
//
|
||||
// / }
|
||||
// }
|
||||
|
||||
fn do_cli_help(parsed: &CliStart) -> bool {
|
||||
|
||||
@@ -1,190 +1,15 @@
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use log::{error, warn};
|
||||
use rog_anime::{Animations, DeviceState};
|
||||
use rog_aura::aura_detection::{LaptopLedData, LedSupportFile};
|
||||
use rog_aura::layouts::KeyLayout;
|
||||
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;
|
||||
use log::error;
|
||||
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
||||
#[cfg(not(feature = "mocking"))]
|
||||
use supergfxctl::zbus_proxy::DaemonProxyBlocking as GfxProxyBlocking;
|
||||
use supergfxctl::zbus_proxy::DaemonProxy as GfxProxy;
|
||||
use zbus::Connection;
|
||||
|
||||
use crate::error::Result;
|
||||
#[cfg(feature = "mocking")]
|
||||
use crate::mocking::DaemonProxyBlocking as GfxProxyBlocking;
|
||||
use crate::update_and_notify::EnabledNotifications;
|
||||
use crate::{RogDbusClientBlocking, BOARD_NAME, DATA_DIR};
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PlatformState {
|
||||
/// To be shared to a thread that checks notifications.
|
||||
/// It's a bit general in that it won't provide *what* was
|
||||
/// updated, so the full state needs refresh
|
||||
pub post_sound: Option<bool>,
|
||||
pub gpu_mux_mode: Option<GpuMode>,
|
||||
pub panel_overdrive: Option<bool>,
|
||||
pub mini_led_mode: Option<bool>,
|
||||
pub dgpu_disable: Option<bool>,
|
||||
pub egpu_enable: Option<bool>,
|
||||
pub throttle: Option<ThrottlePolicy>,
|
||||
pub charge_limit: Option<u8>,
|
||||
}
|
||||
|
||||
impl PlatformState {
|
||||
pub fn new(dbus: &RogDbusClientBlocking<'_>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
post_sound: dbus.proxies().platform().boot_sound().ok(),
|
||||
gpu_mux_mode: dbus
|
||||
.proxies()
|
||||
.platform()
|
||||
.gpu_mux_mode()
|
||||
.map(GpuMode::from)
|
||||
.ok(),
|
||||
panel_overdrive: dbus.proxies().platform().panel_od().ok(),
|
||||
mini_led_mode: dbus.proxies().platform().mini_led_mode().ok(),
|
||||
// TODO: needs supergfx
|
||||
dgpu_disable: dbus.proxies().platform().dgpu_disable().ok(),
|
||||
egpu_enable: dbus.proxies().platform().egpu_enable().ok(),
|
||||
throttle: dbus.proxies().platform().throttle_thermal_policy().ok(),
|
||||
charge_limit: dbus
|
||||
.proxies()
|
||||
.platform()
|
||||
.charge_control_end_threshold()
|
||||
.ok(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct FanCurvesState {
|
||||
pub show_curve: ThrottlePolicy,
|
||||
pub show_graph: FanCurvePU,
|
||||
pub curves: BTreeMap<ThrottlePolicy, Vec<CurveData>>,
|
||||
pub available_fans: HashSet<FanCurvePU>,
|
||||
// pub drag_delta: Vec2,
|
||||
}
|
||||
|
||||
impl FanCurvesState {
|
||||
pub fn new(dbus: &RogDbusClientBlocking<'_>) -> Result<Self> {
|
||||
let profiles = vec![
|
||||
ThrottlePolicy::Balanced,
|
||||
ThrottlePolicy::Quiet,
|
||||
ThrottlePolicy::Performance,
|
||||
];
|
||||
|
||||
let mut available_fans = HashSet::new();
|
||||
let mut curves: BTreeMap<ThrottlePolicy, Vec<CurveData>> = BTreeMap::new();
|
||||
for p in &profiles {
|
||||
if let Ok(curve) = dbus.proxies().fan_curves().fan_curve_data(*p) {
|
||||
if available_fans.is_empty() {
|
||||
for fan in &curve {
|
||||
available_fans.insert(fan.fan);
|
||||
}
|
||||
}
|
||||
curves.insert(*p, curve);
|
||||
} else {
|
||||
curves.insert(*p, Default::default());
|
||||
}
|
||||
}
|
||||
|
||||
let show_curve = dbus.proxies().platform().throttle_thermal_policy()?;
|
||||
|
||||
Ok(Self {
|
||||
show_curve,
|
||||
show_graph: FanCurvePU::CPU,
|
||||
curves,
|
||||
available_fans,
|
||||
// drag_delta: Vec2::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct AuraState {
|
||||
pub current_mode: AuraModeNum,
|
||||
pub modes: BTreeMap<AuraModeNum, AuraEffect>,
|
||||
pub enabled: AuraPowerDev,
|
||||
/// Brightness from 0-3
|
||||
pub bright: LedBrightness,
|
||||
pub wave_red: [u8; 22],
|
||||
pub wave_green: [u8; 22],
|
||||
pub wave_blue: [u8; 22],
|
||||
}
|
||||
|
||||
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()
|
||||
} else {
|
||||
AuraModeNum::Static
|
||||
},
|
||||
|
||||
modes: if !layout.basic_modes().is_empty() {
|
||||
dbus.proxies().aura().all_mode_data().unwrap_or_default()
|
||||
} else {
|
||||
BTreeMap::new()
|
||||
},
|
||||
enabled: dbus.proxies().aura().led_power().unwrap_or_default(),
|
||||
bright: Default::default(),
|
||||
wave_red: [0u8; 22],
|
||||
wave_green: [0u8; 22],
|
||||
wave_blue: [0u8; 22],
|
||||
})
|
||||
}
|
||||
|
||||
/// Bump value in to the wave and surf all along.
|
||||
pub fn nudge_wave(&mut self, r: u8, g: u8, b: u8) {
|
||||
for i in (0..self.wave_red.len()).rev() {
|
||||
if i > 0 {
|
||||
self.wave_red[i] = self.wave_red[i - 1];
|
||||
self.wave_green[i] = self.wave_green[i - 1];
|
||||
self.wave_blue[i] = self.wave_blue[i - 1];
|
||||
}
|
||||
}
|
||||
self.wave_red[0] = r;
|
||||
self.wave_green[0] = g;
|
||||
self.wave_blue[0] = b;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct AnimeState {
|
||||
pub display_enabled: bool,
|
||||
pub display_brightness: u8,
|
||||
pub builtin_anims_enabled: bool,
|
||||
pub builtin_anims: Animations,
|
||||
}
|
||||
|
||||
impl AnimeState {
|
||||
pub fn new(dbus: &RogDbusClientBlocking<'_>) -> Result<Self> {
|
||||
let device_state = dbus.proxies().anime().device_state()?;
|
||||
Ok(Self {
|
||||
display_enabled: device_state.display_enabled,
|
||||
display_brightness: device_state.display_brightness as u8,
|
||||
builtin_anims_enabled: device_state.builtin_anims_enabled,
|
||||
builtin_anims: device_state.builtin_anims,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DeviceState> for AnimeState {
|
||||
fn from(dev: DeviceState) -> Self {
|
||||
Self {
|
||||
display_enabled: dev.display_enabled,
|
||||
display_brightness: dev.display_brightness as u8,
|
||||
builtin_anims_enabled: dev.builtin_anims_enabled,
|
||||
builtin_anims: dev.builtin_anims,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GfxState {
|
||||
@@ -194,11 +19,11 @@ pub struct GfxState {
|
||||
}
|
||||
|
||||
impl GfxState {
|
||||
pub fn new(dbus: &GfxProxyBlocking<'_>) -> Result<Self> {
|
||||
pub async fn new(dbus: &GfxProxy<'_>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
has_supergfx: dbus.mode().is_ok(),
|
||||
mode: dbus.mode().unwrap_or(GfxMode::None),
|
||||
power_status: dbus.power().unwrap_or(GfxPower::Unknown),
|
||||
has_supergfx: dbus.mode().await.is_ok(),
|
||||
mode: dbus.mode().await.unwrap_or(GfxMode::None),
|
||||
power_status: dbus.power().await.unwrap_or(GfxPower::Unknown),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -213,115 +38,16 @@ impl Default for GfxState {
|
||||
}
|
||||
}
|
||||
|
||||
/// The keyboard layout, used for such things as per-key and zones
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AuraCreation {
|
||||
/// Specifically for testing the development of keyboard layouts (combined
|
||||
/// with `--layout-name` CLI option)
|
||||
pub layout_testing: Option<PathBuf>,
|
||||
pub layout_last_modified: SystemTime,
|
||||
pub keyboard_layout: KeyLayout,
|
||||
pub keyboard_layouts: Vec<PathBuf>,
|
||||
/// current index in to `self.keyboard_layouts`
|
||||
pub keyboard_layout_index: usize,
|
||||
}
|
||||
|
||||
impl AuraCreation {
|
||||
pub fn new(test_name: Option<String>, view_layout: bool) -> Result<Self> {
|
||||
let mut led_support = LaptopLedData::get_data();
|
||||
|
||||
let mut path = PathBuf::from(DATA_DIR);
|
||||
let mut layout_testing = None;
|
||||
let mut keyboard_layouts = Vec::new();
|
||||
|
||||
// Find and load a matching layout for laptop
|
||||
let mut board_name = std::fs::read_to_string(BOARD_NAME).map_err(|e| {
|
||||
println!("DOH! {BOARD_NAME}, {e}");
|
||||
e
|
||||
})?;
|
||||
|
||||
if test_name.is_some() || view_layout {
|
||||
if cfg!(feature = "mocking") {
|
||||
path.pop();
|
||||
path.push("rog-aura");
|
||||
path.push("data");
|
||||
}
|
||||
keyboard_layouts = KeyLayout::layout_files(path.clone()).unwrap();
|
||||
|
||||
if let Some(name) = test_name {
|
||||
if let Some(modes) = LedSupportFile::load_from_supoprt_db() {
|
||||
if let Some(data) = modes.matcher(&name) {
|
||||
led_support = data;
|
||||
}
|
||||
}
|
||||
board_name = name;
|
||||
for layout in &keyboard_layouts {
|
||||
if layout
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_string_lossy()
|
||||
.contains(&led_support.layout_name.to_lowercase())
|
||||
{
|
||||
layout_testing = Some(layout.clone());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
board_name = "GQ401QM".to_owned();
|
||||
};
|
||||
|
||||
if view_layout {
|
||||
layout_testing = Some(keyboard_layouts[0].clone());
|
||||
board_name = keyboard_layouts[0]
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_string_lossy()
|
||||
.split_once('_')
|
||||
.unwrap()
|
||||
.0
|
||||
.to_owned();
|
||||
led_support.layout_name = board_name.clone();
|
||||
}
|
||||
}
|
||||
|
||||
let keyboard_layout = KeyLayout::find_layout(led_support, path)
|
||||
.map_err(|e| {
|
||||
println!("DERP! , {e}");
|
||||
})
|
||||
.unwrap_or_else(|_| {
|
||||
warn!("Did not find a keyboard layout matching {board_name}");
|
||||
KeyLayout::default_layout()
|
||||
});
|
||||
|
||||
Ok(Self {
|
||||
layout_testing,
|
||||
layout_last_modified: SystemTime::now(),
|
||||
keyboard_layout,
|
||||
keyboard_layouts,
|
||||
keyboard_layout_index: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// State stored from system daemons. This is shared with: tray, zbus
|
||||
/// notifications thread and the GUI app thread.
|
||||
pub struct SystemState {
|
||||
pub aura_creation: AuraCreation,
|
||||
//--
|
||||
pub enabled_notifications: Arc<Mutex<EnabledNotifications>>,
|
||||
/// Because much of the app state here is the same as
|
||||
/// `RogBiosSupportedFunctions` we can re-use that structure.
|
||||
pub bios: PlatformState,
|
||||
pub aura: AuraState,
|
||||
pub anime: AnimeState,
|
||||
pub fan_curves: FanCurvesState,
|
||||
pub gfx_state: GfxState,
|
||||
pub error: Option<String>,
|
||||
/// Specific field for the tray only so that we can know when it does need
|
||||
/// update. The tray should set this to false when done.
|
||||
pub tray_should_update: bool,
|
||||
pub app_should_update: bool,
|
||||
pub asus_dbus: RogDbusClientBlocking<'static>,
|
||||
pub gfx_dbus: GfxProxyBlocking<'static>,
|
||||
pub tray_enabled: bool,
|
||||
pub run_in_bg: bool,
|
||||
}
|
||||
@@ -329,47 +55,22 @@ pub struct SystemState {
|
||||
impl SystemState {
|
||||
/// Creates self, including the relevant dbus connections and proixies for
|
||||
/// internal use
|
||||
pub fn new(
|
||||
aura_creation: AuraCreation,
|
||||
pub async fn new(
|
||||
enabled_notifications: Arc<Mutex<EnabledNotifications>>,
|
||||
tray_enabled: bool,
|
||||
run_in_bg: bool,
|
||||
) -> Result<Self> {
|
||||
let (asus_dbus, conn) = RogDbusClientBlocking::new()?;
|
||||
let aura = AuraState::new(&aura_creation.keyboard_layout, &asus_dbus)
|
||||
.map_err(|e| {
|
||||
let e = format!("Could not get AuraState state: {e}");
|
||||
error!("{e}");
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let conn = Connection::system().await?;
|
||||
|
||||
let gfx_dbus = GfxProxyBlocking::builder(&conn)
|
||||
let gfx_dbus = GfxProxy::builder(&conn)
|
||||
.destination(":org.supergfxctl.Daemon")?
|
||||
.build()
|
||||
.await
|
||||
.expect("Couldn't connect to supergfxd");
|
||||
Ok(Self {
|
||||
aura_creation,
|
||||
enabled_notifications,
|
||||
bios: PlatformState::new(&asus_dbus)
|
||||
.map_err(|e| {
|
||||
let e = format!("Could not get BiosState state: {e}");
|
||||
error!("{e}");
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
aura,
|
||||
anime: AnimeState::new(&asus_dbus)
|
||||
.map_err(|e| {
|
||||
let e = format!("Could not get AnimeState state: {e}");
|
||||
error!("{e}");
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
fan_curves: FanCurvesState::new(&asus_dbus)
|
||||
.map_err(|e| {
|
||||
let e = format!("Could not get FanCurvesState state: {e}");
|
||||
error!("{e}");
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
gfx_state: GfxState::new(&gfx_dbus)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
let e = format!("Could not get supergfxd state: {e}");
|
||||
error!("{e}");
|
||||
@@ -378,8 +79,6 @@ impl SystemState {
|
||||
error: None,
|
||||
tray_should_update: true,
|
||||
app_should_update: true,
|
||||
asus_dbus,
|
||||
gfx_dbus,
|
||||
tray_enabled,
|
||||
run_in_bg,
|
||||
})
|
||||
@@ -390,51 +89,3 @@ impl SystemState {
|
||||
self.app_should_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SystemState {
|
||||
fn default() -> Self {
|
||||
let (asus_dbus, conn) = RogDbusClientBlocking::new().expect("Couldn't connect to asusd");
|
||||
let gfx_dbus = GfxProxyBlocking::builder(&conn)
|
||||
.build()
|
||||
.expect("Couldn't connect to supergfxd");
|
||||
|
||||
Self {
|
||||
aura_creation: AuraCreation {
|
||||
layout_testing: None,
|
||||
layout_last_modified: SystemTime::now(),
|
||||
keyboard_layout: KeyLayout::default_layout(),
|
||||
keyboard_layouts: Default::default(),
|
||||
keyboard_layout_index: 0,
|
||||
},
|
||||
enabled_notifications: Default::default(),
|
||||
bios: PlatformState {
|
||||
post_sound: Default::default(),
|
||||
gpu_mux_mode: None,
|
||||
charge_limit: Some(100),
|
||||
..Default::default()
|
||||
},
|
||||
aura: AuraState {
|
||||
current_mode: AuraModeNum::Static,
|
||||
modes: Default::default(),
|
||||
enabled: AuraPowerDev::default(),
|
||||
..Default::default()
|
||||
},
|
||||
anime: AnimeState::default(),
|
||||
fan_curves: FanCurvesState {
|
||||
..Default::default()
|
||||
},
|
||||
gfx_state: GfxState {
|
||||
has_supergfx: false,
|
||||
mode: GfxMode::None,
|
||||
power_status: GfxPower::Unknown,
|
||||
},
|
||||
error: Default::default(),
|
||||
tray_should_update: true,
|
||||
app_should_update: true,
|
||||
asus_dbus,
|
||||
gfx_dbus,
|
||||
tray_enabled: true,
|
||||
run_in_bg: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use std::time::Duration;
|
||||
|
||||
use betrayer::{Icon, Menu, MenuItem, TrayEvent, TrayIcon, TrayIconBuilder};
|
||||
use log::{debug, error, info, warn};
|
||||
use rog_platform::platform::{GpuMode, Properties};
|
||||
use rog_platform::platform::Properties;
|
||||
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
||||
use supergfxctl::zbus_proxy::DaemonProxyBlocking as GfxProxy;
|
||||
use versions::Versioning;
|
||||
@@ -113,16 +113,7 @@ fn set_tray_icon_and_tip(lock: &SystemState, tray: &TrayIcon<TrayAction>, superg
|
||||
}
|
||||
};
|
||||
|
||||
let current_gpu_mode = if supergfx_active {
|
||||
lock.gfx_state.mode
|
||||
} else if let Some(mode) = lock.bios.gpu_mux_mode {
|
||||
match mode {
|
||||
GpuMode::Discrete => GfxMode::AsusMuxDgpu,
|
||||
_ => GfxMode::Hybrid,
|
||||
}
|
||||
} else {
|
||||
GfxMode::Hybrid
|
||||
};
|
||||
let current_gpu_mode = lock.gfx_state.mode;
|
||||
|
||||
tray.set_tooltip(format!(
|
||||
"ROG: gpu mode = {current_gpu_mode:?}, gpu power = {gpu_status:?}"
|
||||
|
||||
@@ -11,10 +11,8 @@ use std::time::Duration;
|
||||
|
||||
use log::{error, info, trace, warn};
|
||||
use notify_rust::{Hint, Notification, NotificationHandle, Urgency};
|
||||
use rog_dbus::zbus_anime::AnimeProxy;
|
||||
use rog_dbus::zbus_aura::AuraProxy;
|
||||
use rog_dbus::zbus_platform::PlatformProxy;
|
||||
use rog_platform::platform::{GpuMode, ThrottlePolicy};
|
||||
use rog_platform::platform::GpuMode;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use supergfxctl::actions::UserActionRequired as GfxUserAction;
|
||||
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
||||
@@ -31,45 +29,12 @@ const NOTIF_HEADER: &str = "ROG Control";
|
||||
static mut POWER_AC_CMD: Option<Command> = None;
|
||||
static mut POWER_BAT_CMD: Option<Command> = None;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
|
||||
#[serde(default)]
|
||||
pub struct EnabledNotifications {
|
||||
pub receive_boot_sound_changed: bool,
|
||||
pub receive_panel_od_changed: bool,
|
||||
pub receive_mini_led_mode_changed: bool,
|
||||
pub receive_dgpu_disable_changed: bool,
|
||||
pub receive_egpu_enable_changed: bool,
|
||||
pub receive_gpu_mux_mode_changed: bool,
|
||||
pub receive_charge_control_end_threshold_changed: bool,
|
||||
pub receive_notify_mains_online: bool,
|
||||
pub receive_throttle_thermal_policy_changed: bool,
|
||||
pub receive_led_mode_data_changed: bool,
|
||||
/// Anime
|
||||
pub receive_power_states: bool,
|
||||
pub receive_notify_gfx: bool,
|
||||
pub receive_notify_gfx_status: bool,
|
||||
pub all_enabled: bool,
|
||||
}
|
||||
|
||||
impl Default for EnabledNotifications {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
receive_boot_sound_changed: false,
|
||||
receive_panel_od_changed: true,
|
||||
receive_mini_led_mode_changed: true,
|
||||
receive_dgpu_disable_changed: true,
|
||||
receive_egpu_enable_changed: true,
|
||||
receive_gpu_mux_mode_changed: true,
|
||||
receive_charge_control_end_threshold_changed: true,
|
||||
receive_notify_mains_online: false,
|
||||
receive_throttle_thermal_policy_changed: true,
|
||||
receive_led_mode_data_changed: true,
|
||||
receive_power_states: false,
|
||||
receive_notify_gfx: false,
|
||||
receive_notify_gfx_status: false,
|
||||
all_enabled: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EnabledNotifications {
|
||||
@@ -78,6 +43,18 @@ impl EnabledNotifications {
|
||||
}
|
||||
}
|
||||
|
||||
fn gpu_to_gfx(value: GpuMode) -> GfxMode {
|
||||
match value {
|
||||
GpuMode::Optimus => GfxMode::Hybrid,
|
||||
GpuMode::Integrated => GfxMode::Integrated,
|
||||
GpuMode::Egpu => GfxMode::AsusEgpu,
|
||||
GpuMode::Vfio => GfxMode::Vfio,
|
||||
GpuMode::Ultimate => GfxMode::AsusMuxDgpu,
|
||||
GpuMode::Error => GfxMode::None,
|
||||
GpuMode::NotSupported => GfxMode::None,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: drop the macro and use generics plus closure
|
||||
macro_rules! recv_notif {
|
||||
($proxy:ident,
|
||||
@@ -107,7 +84,7 @@ macro_rules! recv_notif {
|
||||
while let Some(e) = p.next().await {
|
||||
if let Ok(out) = e.args() {
|
||||
if let Ok(config) = notifs_enabled1.lock() {
|
||||
if config.all_enabled && config.$signal {
|
||||
if config.$signal {
|
||||
trace!("zbus signal {}", stringify!($signal));
|
||||
$notifier($msg, &out.$($out_arg)+()).ok();
|
||||
}
|
||||
@@ -124,49 +101,6 @@ macro_rules! recv_notif {
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! recv_changed {
|
||||
($proxy:ident,
|
||||
$signal:ident,
|
||||
$last_notif:ident,
|
||||
$notif_enabled:ident,
|
||||
$page_states:ident,
|
||||
($($args: tt)*),
|
||||
// ($($out_arg:tt)+),
|
||||
$msg:literal,
|
||||
$notifier:ident) => {
|
||||
|
||||
let notifs_enabled1 = $notif_enabled.clone();
|
||||
let page_states1 = $page_states.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let conn = zbus::Connection::system().await.map_err(|e| {
|
||||
log::error!("zbus signal: {}: {e}", stringify!($signal));
|
||||
e
|
||||
}).unwrap();
|
||||
let proxy = $proxy::new(&conn).await.map_err(|e| {
|
||||
log::error!("zbus signal: {}: {e}", stringify!($signal));
|
||||
e
|
||||
}).unwrap();
|
||||
info!("Started zbus signal thread: {}", stringify!($signal));
|
||||
while let Some(e) = proxy.$signal().await.next().await {
|
||||
if let Ok(out) = e.get().await {
|
||||
if let Ok(config) = notifs_enabled1.lock() {
|
||||
if config.all_enabled && config.$signal {
|
||||
trace!("zbus signal {}", stringify!($signal));
|
||||
$notifier($msg, &out).ok();
|
||||
}
|
||||
}
|
||||
if let Ok(mut lock) = page_states1.lock() {
|
||||
lock.$($args)+ = out.into();
|
||||
lock.set_notified();
|
||||
}
|
||||
}
|
||||
sleep(Duration::from_millis(500)).await;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
pub fn start_notifications(
|
||||
config: &Config,
|
||||
page_states: &Arc<Mutex<SystemState>>,
|
||||
@@ -196,155 +130,6 @@ pub fn start_notifications(
|
||||
}
|
||||
}
|
||||
|
||||
// BIOS notif
|
||||
recv_changed!(
|
||||
PlatformProxy,
|
||||
receive_boot_sound_changed,
|
||||
last_notification,
|
||||
enabled_notifications,
|
||||
page_states,
|
||||
(bios.post_sound),
|
||||
"BIOS Post sound",
|
||||
do_notification
|
||||
);
|
||||
|
||||
recv_changed!(
|
||||
PlatformProxy,
|
||||
receive_panel_od_changed,
|
||||
last_notification,
|
||||
enabled_notifications,
|
||||
page_states,
|
||||
(bios.panel_overdrive),
|
||||
"Panel Overdrive enabled:",
|
||||
do_notification
|
||||
);
|
||||
|
||||
recv_changed!(
|
||||
PlatformProxy,
|
||||
receive_mini_led_mode_changed,
|
||||
last_notification,
|
||||
enabled_notifications,
|
||||
page_states,
|
||||
(bios.mini_led_mode),
|
||||
"MiniLED mode enabled:",
|
||||
do_notification
|
||||
);
|
||||
|
||||
recv_changed!(
|
||||
PlatformProxy,
|
||||
receive_dgpu_disable_changed,
|
||||
last_notification,
|
||||
enabled_notifications,
|
||||
page_states,
|
||||
(bios.dgpu_disable),
|
||||
"BIOS dGPU disabled",
|
||||
do_notification
|
||||
);
|
||||
|
||||
recv_changed!(
|
||||
PlatformProxy,
|
||||
receive_egpu_enable_changed,
|
||||
last_notification,
|
||||
enabled_notifications,
|
||||
page_states,
|
||||
(bios.egpu_enable),
|
||||
"BIOS eGPU enabled",
|
||||
do_notification
|
||||
);
|
||||
|
||||
// Charge notif
|
||||
recv_changed!(
|
||||
PlatformProxy,
|
||||
receive_charge_control_end_threshold_changed,
|
||||
last_notification,
|
||||
enabled_notifications,
|
||||
page_states,
|
||||
(bios.charge_limit),
|
||||
"Battery charge limit changed to",
|
||||
do_notification
|
||||
);
|
||||
|
||||
// Profile notif
|
||||
recv_changed!(
|
||||
PlatformProxy,
|
||||
receive_throttle_thermal_policy_changed,
|
||||
last_notification,
|
||||
enabled_notifications,
|
||||
page_states,
|
||||
(bios.throttle),
|
||||
"Profile changed to",
|
||||
do_thermal_notif
|
||||
);
|
||||
// notify!(do_thermal_notif(&out.profile), lock);
|
||||
|
||||
// LED notif
|
||||
recv_changed!(
|
||||
AuraProxy,
|
||||
receive_led_mode_data_changed,
|
||||
last_notification,
|
||||
enabled_notifications,
|
||||
page_states,
|
||||
(aura.current_mode),
|
||||
"Keyboard LED mode changed to",
|
||||
do_notification
|
||||
);
|
||||
|
||||
// let page_states1 = page_states.clone();
|
||||
// tokio::spawn(async move {
|
||||
// let conn = zbus::Connection::system()
|
||||
// .await
|
||||
// .map_err(|e| {
|
||||
// error!("zbus signal: receive_device_state: {e}");
|
||||
// e
|
||||
// })
|
||||
// .unwrap();
|
||||
// let proxy = AuraProxy::new(&conn)
|
||||
// .await
|
||||
// .map_err(|e| {
|
||||
// error!("zbus signal: receive_device_state: {e}");
|
||||
// e
|
||||
// })
|
||||
// .unwrap();
|
||||
// let p = proxy.receive_led_power_changed().await;
|
||||
// info!("Started zbus signal thread: receive_notify_power_states");
|
||||
// while let Some(e) = p.next().await {
|
||||
// if let Ok(out) = e.get().await {
|
||||
// if let Ok(mut lock) = page_states1.lock() {
|
||||
// lock.aura.enabled = out;
|
||||
// lock.set_notified();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
let page_states1 = page_states.clone();
|
||||
tokio::spawn(async move {
|
||||
let conn = zbus::Connection::system()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("zbus signal: receive_device_state: {e}");
|
||||
e
|
||||
})
|
||||
.unwrap();
|
||||
let proxy = AnimeProxy::new(&conn)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("zbus signal: receive_device_state: {e}");
|
||||
e
|
||||
})
|
||||
.unwrap();
|
||||
if let Ok(mut p) = proxy.receive_notify_device_state().await {
|
||||
info!("Started zbus signal thread: receive_device_state");
|
||||
while let Some(e) = p.next().await {
|
||||
if let Ok(out) = e.args() {
|
||||
if let Ok(mut lock) = page_states1.lock() {
|
||||
lock.anime = out.data.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
let page_states1 = page_states.clone();
|
||||
tokio::spawn(async move {
|
||||
let conn = zbus::Connection::system()
|
||||
@@ -375,7 +160,7 @@ pub fn start_notifications(
|
||||
continue;
|
||||
}
|
||||
if let Ok(mut lock) = page_states1.lock() {
|
||||
lock.bios.gpu_mux_mode = Some(mode);
|
||||
lock.gfx_state.mode = gpu_to_gfx(mode);
|
||||
lock.set_notified();
|
||||
}
|
||||
do_mux_notification("Reboot required. BIOS GPU MUX mode set to", &mode).ok();
|
||||
@@ -397,7 +182,7 @@ pub fn start_notifications(
|
||||
if let Ok(status) = dev.get_runtime_status() {
|
||||
if status != GfxPower::Unknown && status != last_status {
|
||||
if let Ok(config) = notifs_enabled1.lock() {
|
||||
if config.all_enabled && config.receive_notify_gfx_status {
|
||||
if config.receive_notify_gfx_status {
|
||||
// Required check because status cycles through
|
||||
// active/unknown/suspended
|
||||
do_gpu_status_notif("dGPU status changed:", &status).ok();
|
||||
@@ -498,7 +283,7 @@ fn convert_gfx_mode(gfx: GfxMode) -> GpuMode {
|
||||
match gfx {
|
||||
GfxMode::Hybrid => GpuMode::Optimus,
|
||||
GfxMode::Integrated => GpuMode::Integrated,
|
||||
GfxMode::NvidiaNoModeset => GpuMode::Discrete,
|
||||
GfxMode::NvidiaNoModeset => GpuMode::Optimus,
|
||||
GfxMode::Vfio => GpuMode::Vfio,
|
||||
GfxMode::AsusEgpu => GpuMode::Egpu,
|
||||
GfxMode::AsusMuxDgpu => GpuMode::Ultimate,
|
||||
@@ -553,17 +338,6 @@ fn _ac_power_notification(message: &str, on: &bool) -> Result<NotificationHandle
|
||||
Ok(base_notification(message, &data).show()?)
|
||||
}
|
||||
|
||||
fn do_thermal_notif(message: &str, profile: &ThrottlePolicy) -> Result<NotificationHandle> {
|
||||
let icon = match profile {
|
||||
ThrottlePolicy::Balanced => "asus_notif_yellow",
|
||||
ThrottlePolicy::Performance => "asus_notif_red",
|
||||
ThrottlePolicy::Quiet => "asus_notif_green",
|
||||
};
|
||||
let profile: &str = (*profile).into();
|
||||
let mut notif = base_notification(message, &profile.to_uppercase());
|
||||
Ok(notif.icon(icon).show()?)
|
||||
}
|
||||
|
||||
fn do_gpu_status_notif(message: &str, data: &GfxPower) -> Result<NotificationHandle> {
|
||||
// eww
|
||||
let mut notif = base_notification(message, &<&str>::from(data).to_owned());
|
||||
|
||||
Reference in New Issue
Block a user