Clean up the tray code

This commit is contained in:
Luke D. Jones
2024-03-04 13:28:19 +13:00
parent a1fcf5023c
commit 02b9bac899
2 changed files with 82 additions and 62 deletions

View File

@@ -5,11 +5,11 @@ use std::fs::OpenOptions;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::process::exit;
use std::sync::{Arc, Mutex};
use std::sync::{Arc, Mutex, OnceLock};
use std::thread::sleep;
use std::time::Duration;
use betrayer::{Icon, Menu, MenuItem, TrayEvent, TrayIconBuilder};
use betrayer::{Icon, Menu, MenuItem, TrayEvent, TrayIcon, TrayIconBuilder};
use log::{debug, error, info, warn};
use rog_platform::platform::{GpuMode, Properties};
use supergfxctl::pci_device::{GfxMode, GfxPower};
@@ -23,6 +23,16 @@ use crate::{get_ipc_file, QUIT_APP, SHOW_GUI};
const TRAY_LABEL: &str = "ROG Control Center";
const TRAY_ICON_PATH: &str = "/usr/share/icons/hicolor/512x512/apps/";
struct Icons {
rog_blue: Icon,
rog_red: Icon,
rog_green: Icon,
rog_white: Icon,
gpu_integrated: Icon,
}
static ICONS: OnceLock<Icons> = OnceLock::new();
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
enum TrayAction {
Open,
@@ -66,6 +76,60 @@ fn build_menu() -> Menu<TrayAction> {
])
}
fn do_action(event: TrayEvent<TrayAction>) {
if let TrayEvent::Menu(action) = event {
match action {
TrayAction::Open => open_app(),
TrayAction::Quit => {
quit_app();
exit(0);
}
}
}
}
fn set_tray_icon_and_tip(lock: &SystemState, tray: &TrayIcon<TrayAction>, supergfx_active: bool) {
if let Some(icons) = ICONS.get() {
let gpu_status = lock.gfx_state.power_status;
match gpu_status {
GfxPower::Suspended => tray.set_icon(Some(icons.rog_blue.clone())),
GfxPower::Off => {
if lock.gfx_state.mode == GfxMode::Vfio {
tray.set_icon(Some(icons.rog_red.clone()))
} else {
tray.set_icon(Some(icons.rog_green.clone()))
}
}
GfxPower::AsusDisabled => tray.set_icon(Some(icons.rog_white.clone())),
GfxPower::AsusMuxDiscreet | GfxPower::Active => {
tray.set_icon(Some(icons.rog_red.clone()));
}
GfxPower::Unknown => {
if supergfx_active {
tray.set_icon(Some(icons.gpu_integrated.clone()));
} else {
tray.set_icon(Some(icons.rog_red.clone()));
}
}
};
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
};
tray.set_tooltip(format!(
"ROG: gpu mode = {current_gpu_mode:?}, gpu power = {gpu_status:?}"
));
}
}
/// The tray is controlled somewhat by `Arc<Mutex<SystemState>>`
pub fn init_tray(
_supported_properties: Vec<Properties>,
@@ -74,6 +138,18 @@ pub fn init_tray(
) {
std::thread::spawn(move || {
debug!("init_tray");
let rog_blue = read_icon(&PathBuf::from("asus_notif_blue.png"));
let rog_red = read_icon(&PathBuf::from("asus_notif_red.png"));
let rog_green = read_icon(&PathBuf::from("asus_notif_green.png"));
let rog_white = read_icon(&PathBuf::from("asus_notif_white.png"));
let gpu_integrated = read_icon(&PathBuf::from("rog-control-center.png"));
ICONS.get_or_init(|| Icons {
rog_blue,
rog_red: rog_red.clone(),
rog_green,
rog_white,
gpu_integrated,
});
let conn = zbus::blocking::Connection::system().unwrap();
let gfx_proxy = GfxProxy::new(&conn).unwrap();
@@ -93,75 +169,19 @@ pub fn init_tray(
}
};
let rog_blue = read_icon(&PathBuf::from("asus_notif_blue.png"));
let rog_red = read_icon(&PathBuf::from("asus_notif_red.png"));
let rog_green = read_icon(&PathBuf::from("asus_notif_green.png"));
let rog_white = read_icon(&PathBuf::from("asus_notif_white.png"));
let gpu_integrated = read_icon(&PathBuf::from("rog-control-center.png"));
info!("Started ROGTray");
let tray = TrayIconBuilder::<TrayAction>::new()
.with_icon(rog_red.clone())
.with_tooltip(TRAY_LABEL)
.with_menu(build_menu())
.build(|event| {
if let TrayEvent::Menu(action) = event {
match action {
TrayAction::Open => open_app(),
TrayAction::Quit => {
quit_app();
exit(0);
}
}
}
})
.build(|event| do_action(event))
.unwrap();
info!("Started ROGTray");
loop {
// let states = states.clone();
if let Ok(mut lock) = states.lock() {
if lock.tray_should_update {
// Supergfx ends up adding some complexity to handle if it isn't available
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
};
dbg!(current_gpu_mode);
dbg!(lock.bios.gpu_mux_mode);
tray.set_tooltip(format!("ROG: gpu mode = {current_gpu_mode:?}"));
set_tray_icon_and_tip(&lock, &tray, supergfx_active);
lock.tray_should_update = false;
debug!("ROGTray: rebuilt menus due to state change");
match lock.gfx_state.power_status {
GfxPower::Suspended => tray.set_icon(Some(rog_blue.clone())),
GfxPower::Off => {
if lock.gfx_state.mode == GfxMode::Vfio {
tray.set_icon(Some(rog_red.clone()))
} else {
tray.set_icon(Some(rog_green.clone()))
}
}
GfxPower::AsusDisabled => tray.set_icon(Some(rog_white.clone())),
GfxPower::AsusMuxDiscreet | GfxPower::Active => {
tray.set_icon(Some(rog_red.clone()));
}
GfxPower::Unknown => {
if supergfx_active {
tray.set_icon(Some(gpu_integrated.clone()));
} else {
tray.set_icon(Some(rog_red.clone()));
}
}
};
if let Ok(lock) = config.try_lock() {
if !lock.enable_tray_icon {
return;

View File

@@ -2,7 +2,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-03-03 09:26+0000\n"
"POT-Creation-Date: 2024-03-03 09:41+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"