diff --git a/CHANGELOG.md b/CHANGELOG.md index c220b921..5bdb7420 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] -## [v4.5.6-RC2] +## [v4.5.6-RC3] ### Changed - Fix tasks not always running correctly on boot/sleep/wake/shutdown by finishing the move to async - Change how the profile/fan change task monitors changes due to TUF laptops behaving slightly different +- ROGCC: Better handle the use of GPU MUX without supergfxd +- ROGCC: Track if reboot required when not using supergfxd +- Add env var for logging levels to daemon and gui (`RUST_LOG= Result<(), Box> { let mut logger = env_logger::Builder::new(); logger + .parse_default_env() .target(env_logger::Target::Stdout) .format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args())) - .filter(None, LevelFilter::Info) .init(); let is_service = match env::var_os("IS_SERVICE") { diff --git a/data/asusd.service b/data/asusd.service index 9f0ee849..6e30f30e 100644 --- a/data/asusd.service +++ b/data/asusd.service @@ -6,6 +6,7 @@ Before=multi-user.target [Service] Environment=IS_SERVICE=1 +Environment=RUST_LOG="info" ExecStartPre=/bin/sleep 2 ExecStart=/usr/bin/asusd Restart=on-failure diff --git a/rog-control-center/src/main.rs b/rog-control-center/src/main.rs index 5b90e6d5..98da6909 100644 --- a/rog-control-center/src/main.rs +++ b/rog-control-center/src/main.rs @@ -1,5 +1,5 @@ use eframe::{IconData, NativeOptions}; -use log::{error, info, LevelFilter}; +use log::{error, info}; use rog_aura::layouts::KeyLayout; use rog_control_center::tray::init_tray; use rog_control_center::update_and_notify::EnabledNotifications; @@ -29,9 +29,9 @@ fn main() -> Result<()> { print_versions(); let mut logger = env_logger::Builder::new(); logger + .parse_default_env() .target(env_logger::Target::Stdout) .format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args())) - .filter(None, LevelFilter::Info) .init(); // start tokio diff --git a/rog-control-center/src/tray.rs b/rog-control-center/src/tray.rs index 0ebc5ce1..bbc42c1a 100644 --- a/rog-control-center/src/tray.rs +++ b/rog-control-center/src/tray.rs @@ -4,6 +4,7 @@ use std::{ io::Write, sync::{ + atomic::{AtomicBool, Ordering}, mpsc::{channel, Receiver}, Arc, Mutex, }, @@ -21,7 +22,7 @@ use supergfxctl::{ zbus_proxy::DaemonProxyBlocking as GfxProxyBlocking, }; -use log::{debug, error, info, trace}; +use log::{debug, error, info, trace, warn}; const TRAY_APP_ICON: &str = "rog-control-center"; const TRAY_LABEL: &str = "ROG Control Center"; @@ -241,7 +242,10 @@ impl ROGTray { } fn menu_add_gpu(&mut self, supported: &SupportedFunctions, current_mode: GfxMode) { + let set_mux_off = Arc::new(AtomicBool::new(false)); + let gfx_dbus = self.gfx_proxy.clone(); + let set_mux_off1 = set_mux_off.clone(); let mut gpu_menu = RadioGroup::new("Integrated", move |_| { let mode = gfx_dbus .mode() @@ -259,9 +263,11 @@ impl ROGTray { }) .ok(); } + set_mux_off1.store(true, Ordering::Relaxed); }); let gfx_dbus = self.gfx_proxy.clone(); + let set_mux_off1 = set_mux_off.clone(); gpu_menu.add("Hybrid", move |_| { let mode = gfx_dbus .mode() @@ -279,7 +285,31 @@ impl ROGTray { }) .ok(); } + set_mux_off1.store(true, Ordering::Relaxed); }); + if supported.rog_bios_ctrl.egpu_enable { + let set_mux_off1 = set_mux_off.clone(); + let gfx_dbus = self.gfx_proxy.clone(); + gpu_menu.add("eGPU", move |_| { + let mode = gfx_dbus + .mode() + .map_err(|e| { + error!("ROGTray: mode: {e}"); + e + }) + .unwrap_or(GfxMode::None); + if mode != GfxMode::Egpu { + gfx_dbus + .set_mode(&GfxMode::Egpu) + .map_err(|e| { + error!("ROGTray: set_mode: {e}"); + e + }) + .ok(); + } + set_mux_off1.store(true, Ordering::Relaxed); + }); + } if supported.rog_bios_ctrl.gpu_mux { let gfx_dbus = self.bios_proxy.clone(); gpu_menu.add("Ultimate (Reboot required)", move |_| { @@ -300,27 +330,17 @@ impl ROGTray { .ok(); } }); - } - if supported.rog_bios_ctrl.egpu_enable { - let gfx_dbus = self.gfx_proxy.clone(); - gpu_menu.add("eGPU", move |_| { - let mode = gfx_dbus - .mode() + + if set_mux_off.load(Ordering::Relaxed) { + warn!("Selected non-dgpu mode, must set MUX to optimus"); + self.bios_proxy + .set_gpu_mux_mode(GpuMode::Optimus) .map_err(|e| { - error!("ROGTray: mode: {e}"); + error!("ROGTray: set_mode: {e}"); e }) - .unwrap_or(GfxMode::None); - if mode != GfxMode::Egpu { - gfx_dbus - .set_mode(&GfxMode::Egpu) - .map_err(|e| { - error!("ROGTray: set_mode: {e}"); - e - }) - .ok(); - } - }); + .ok(); + } } let active = match current_mode { @@ -336,6 +356,61 @@ impl ROGTray { debug!("ROGTray: appended gpu menu"); } + fn menu_add_mux(&mut self, current_mode: GfxMode) { + let gfx_dbus = self.bios_proxy.clone(); + let mut reboot_required = false; + + if let Ok(mode) = gfx_dbus.gpu_mux_mode() { + let mode = match mode { + GpuMode::Discrete => GfxMode::AsusMuxDiscreet, + _ => GfxMode::Hybrid, + }; + reboot_required = mode != current_mode; + } + + let mut gpu_menu = RadioGroup::new("Optimus", move |_| { + gfx_dbus + .set_gpu_mux_mode(GpuMode::Optimus) + .map_err(|e| { + error!("ROGTray: set_mode: {e}"); + e + }) + .ok(); + debug!("Setting GPU mode: {}", GpuMode::Optimus); + }); + + let gfx_dbus = self.bios_proxy.clone(); + gpu_menu.add("Ultimate", move |_| { + gfx_dbus + .set_gpu_mux_mode(GpuMode::Discrete) + .map_err(|e| { + error!("ROGTray: set_mode: {e}"); + e + }) + .ok(); + debug!("Setting GPU mode: {}", GpuMode::Discrete); + }); + + let active = match current_mode { + GfxMode::AsusMuxDiscreet => "Ultimate".to_owned(), + GfxMode::Hybrid => "Optimus".to_owned(), + _ => current_mode.to_string(), + }; + debug!("Current active GPU mode: {}", active); + let reboot_required = if reboot_required { + "(Reboot required)" + } else { + "" + }; + self.add_radio_sub_menu( + &format!("GPU Mode: {active} {reboot_required}"), + active.as_str(), + &gpu_menu, + ); + + debug!("ROGTray: appended gpu menu"); + } + fn menu_clear(&mut self) { self.menu = gtk::Menu::new(); debug!("ROGTray: cleared self"); @@ -362,6 +437,8 @@ impl ROGTray { self.menu_add_panel_od(supported, panel_od); if has_supergfx { self.menu_add_gpu(supported, current_gfx_mode); + } else if supported.rog_bios_ctrl.gpu_mux { + self.menu_add_mux(current_gfx_mode); } self.menu_update(); } @@ -412,10 +489,19 @@ pub fn init_tray( loop { 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 lock.gfx_state.has_supergfx { + lock.gfx_state.mode + } else { + match lock.bios.dedicated_gfx { + GpuMode::Discrete => GfxMode::AsusMuxDiscreet, + _ => GfxMode::Hybrid, + } + }; tray.rebuild_and_update( &supported, has_supergfx, - lock.gfx_state.mode, + current_gpu_mode, lock.power_state.charge_limit, lock.bios.panel_overdrive, ); diff --git a/rog-control-center/src/update_and_notify.rs b/rog-control-center/src/update_and_notify.rs index 7b64c3b3..fc124ae0 100644 --- a/rog-control-center/src/update_and_notify.rs +++ b/rog-control-center/src/update_and_notify.rs @@ -185,18 +185,6 @@ pub fn start_notifications( do_notification ); - recv_notif!( - RogBiosProxy, - receive_notify_gpu_mux_mode, - last_notification, - enabled_notifications, - page_states, - (bios.dedicated_gfx), - (mode), - "Reboot required. BIOS GPU MUX mode set to", - do_mux_notification - ); - // Charge notif recv_notif!( PowerProxy, @@ -277,6 +265,43 @@ pub fn start_notifications( }; }); + let page_states1 = page_states.clone(); + let last_notification1 = last_notification.clone(); + tokio::spawn(async move { + let conn = zbus::Connection::system() + .await + .map_err(|e| { + error!("zbus signal: receive_notify_gpu_mux_mode: {e}"); + e + }) + .unwrap(); + let proxy = RogBiosProxy::new(&conn) + .await + .map_err(|e| { + error!("zbus signal: receive_notify_gpu_mux_mode: {e}"); + e + }) + .unwrap(); + if let Ok(mut p) = proxy.receive_notify_gpu_mux_mode().await { + info!("Started zbus signal thread: receive_power_states"); + while let Some(e) = p.next().await { + if let Ok(out) = e.args() { + if let Ok(mut lock) = page_states1.lock() { + lock.bios.dedicated_gfx = out.mode; + lock.set_notified(); + } + if let Ok(ref mut lock) = last_notification1.lock() { + if let Some(notif) = lock.take() { + notif.close(); + } + } + do_mux_notification("Reboot required. BIOS GPU MUX mode set to", &out.mode) + .ok(); + } + } + }; + }); + if let Ok(lock) = page_states.try_lock() { use supergfxctl::pci_device::Device; let dev = Device::find().unwrap_or_default(); @@ -456,10 +481,24 @@ where } /// Actual `GpuMode` unused as data is never correct until switched by reboot -fn do_mux_notification(message: &str, _: &GpuMode) -> Result { - let mut notif = base_notification(message, &""); +fn do_mux_notification(message: &str, m: &GpuMode) -> Result<()> { + let mut notif = base_notification(message, &m.to_string()); + notif.action("gnome-session-quit", "Reboot"); notif.urgency(Urgency::Critical); notif.icon("system-reboot-symbolic"); notif.hint(Hint::Transient(true)); - Ok(notif.show()?) + let handle = notif.show()?; + + std::thread::spawn(|| { + handle.wait_for_action(|id| { + if id == "gnome-session-quit" { + let mut cmd = Command::new("gnome-session-quit"); + cmd.arg("--reboot"); + cmd.spawn().ok(); + } else if id == "__closed" { + // TODO: cancel the switching + } + }) + }); + Ok(()) } diff --git a/rog-control-center/src/widgets/rog_bios.rs b/rog-control-center/src/widgets/rog_bios.rs index 456c59db..8bdeb100 100644 --- a/rog-control-center/src/widgets/rog_bios.rs +++ b/rog-control-center/src/widgets/rog_bios.rs @@ -93,6 +93,13 @@ pub fn rog_bios_group(supported: &SupportedFunctions, states: &mut SystemState, if supported.rog_bios_ctrl.gpu_mux { let mut changed = false; + let mut dedicated_gfx = states.bios.dedicated_gfx; + + let mut reboot_required = false; + if let Ok(mode) = states.asus_dbus.proxies().rog_bios().gpu_mux_mode() { + reboot_required = mode != states.bios.dedicated_gfx; + } + ui.group(|ui| { ui.vertical(|ui| { ui.horizontal_wrapped(|ui| ui.label("GPU MUX mode")); @@ -100,19 +107,23 @@ pub fn rog_bios_group(supported: &SupportedFunctions, states: &mut SystemState, ui.horizontal_wrapped(|ui| { changed = ui .selectable_value( - &mut states.bios.dedicated_gfx, + &mut dedicated_gfx, GpuMode::Discrete, "Dedicated (Ultimate)", ) .clicked() || ui .selectable_value( - &mut states.bios.dedicated_gfx, + &mut dedicated_gfx, GpuMode::Optimus, "Optimus (Hybrid)", ) .clicked(); }); + + if reboot_required { + ui.horizontal_wrapped(|ui| ui.heading("REBOOT REQUIRED")); + } }); }); @@ -121,7 +132,7 @@ pub fn rog_bios_group(supported: &SupportedFunctions, states: &mut SystemState, .asus_dbus .proxies() .rog_bios() - .set_gpu_mux_mode(states.bios.dedicated_gfx) + .set_gpu_mux_mode(dedicated_gfx) .map_err(|err| { states.error = Some(err.to_string()); })