diff --git a/rog-control-center/src/tray.rs b/rog-control-center/src/tray.rs index 0d92f23f..f7588423 100644 --- a/rog-control-center/src/tray.rs +++ b/rog-control-center/src/tray.rs @@ -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 = OnceLock::new(); + #[derive(Debug, Copy, Clone, Eq, PartialEq)] enum TrayAction { Open, @@ -66,6 +76,60 @@ fn build_menu() -> Menu { ]) } +fn do_action(event: TrayEvent) { + 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, 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>` pub fn init_tray( _supported_properties: Vec, @@ -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::::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; diff --git a/rog-control-center/translations/en/rog-control-center.po b/rog-control-center/translations/en/rog-control-center.po index 51afd490..5c50999a 100644 --- a/rog-control-center/translations/en/rog-control-center.po +++ b/rog-control-center/translations/en/rog-control-center.po @@ -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 \n" "Language-Team: LANGUAGE \n"