diff --git a/CHANGELOG.md b/CHANGELOG.md index 10727aff..22c9b139 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Better support of using supergfxctl when available (tray icon and menu) - Check supergfx version before enabling use in tray - Update allowed Aura modes on asusd restart if changed +- Set tray icon for dgpu to "On" if in Vfio mode to prevent confusion +- Add support for Logout/Reboot in notification for KDE ## [v4.6.0] ### Added diff --git a/Cargo.lock b/Cargo.lock index cb10a5fe..92b021b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -638,6 +638,37 @@ dependencies = [ "winapi", ] +[[package]] +name = "cocoa" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "931d3837c286f56e3c58423ce4eba12d08db2374461a785c86f672b08b5650d6" +dependencies = [ + "bitflags", + "block", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", + "objc", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -894,7 +925,6 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "ecolor" version = "0.21.0" -source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def" dependencies = [ "bytemuck", ] @@ -902,30 +932,32 @@ dependencies = [ [[package]] name = "eframe" version = "0.21.3" -source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def" dependencies = [ "bytemuck", + "cocoa", "egui", "egui-winit", "egui_glow", "glow", "glutin", "glutin-winit", + "image", "js-sys", "log", + "objc", "percent-encoding", "raw-window-handle", "thiserror", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "winapi", "winit", ] [[package]] name = "egui" version = "0.21.0" -source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def" dependencies = [ "accesskit", "ahash", @@ -937,13 +969,13 @@ dependencies = [ [[package]] name = "egui-winit" version = "0.21.1" -source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def" dependencies = [ "accesskit_winit", "arboard", "egui", "instant", "log", + "raw-window-handle", "smithay-clipboard", "webbrowser", "winit", @@ -952,7 +984,6 @@ dependencies = [ [[package]] name = "egui_glow" version = "0.21.0" -source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def" dependencies = [ "bytemuck", "egui", @@ -972,7 +1003,6 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "emath" version = "0.21.0" -source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def" dependencies = [ "bytemuck", ] @@ -1057,7 +1087,6 @@ dependencies = [ [[package]] name = "epaint" version = "0.21.0" -source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def" dependencies = [ "ab_glyph", "ahash", @@ -1674,6 +1703,20 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.24.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-rational", + "num-traits", + "png", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -2123,6 +2166,27 @@ dependencies = [ "zbus", ] +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" diff --git a/rog-control-center/Cargo.toml b/rog-control-center/Cargo.toml index 4d484391..fa3e662d 100644 --- a/rog-control-center/Cargo.toml +++ b/rog-control-center/Cargo.toml @@ -10,8 +10,10 @@ edition = "2021" mocking = [] [dependencies] -egui = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"} -eframe = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"} +# egui = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"} +# eframe = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"} +egui = { path = "../../egui/crates/egui" } +eframe = { path = "../../egui/crates/eframe" } libappindicator = "0.7" # Tray icon gtk = "0.15.5" diff --git a/rog-control-center/src/tray.rs b/rog-control-center/src/tray.rs index 774216d0..1b9af2ec 100644 --- a/rog-control-center/src/tray.rs +++ b/rog-control-center/src/tray.rs @@ -480,7 +480,13 @@ pub fn init_tray( match lock.gfx_state.power_status { GfxPower::Suspended => tray.set_icon("asus_notif_blue"), - GfxPower::Off => tray.set_icon("asus_notif_green"), + GfxPower::Off => { + if lock.gfx_state.mode == GfxMode::Vfio { + tray.set_icon("asus_notif_red") + } else { + tray.set_icon("asus_notif_green") + } + } GfxPower::AsusDisabled => tray.set_icon("asus_notif_white"), GfxPower::AsusMuxDiscreet | GfxPower::Active => { tray.set_icon("asus_notif_red"); diff --git a/rog-control-center/src/update_and_notify.rs b/rog-control-center/src/update_and_notify.rs index de918ac2..a472862a 100644 --- a/rog-control-center/src/update_and_notify.rs +++ b/rog-control-center/src/update_and_notify.rs @@ -17,7 +17,8 @@ use rog_dbus::zbus_profile::ProfileProxy; use rog_platform::platform::GpuMode; use rog_profiles::Profile; use serde::{Deserialize, Serialize}; -use supergfxctl::pci_device::GfxPower; +use supergfxctl::actions::UserActionRequired as GfxUserAction; +use supergfxctl::pci_device::{GfxMode, GfxPower}; use supergfxctl::zbus_proxy::DaemonProxy as SuperProxy; use tokio::time::sleep; use zbus::export::futures_util::{future, StreamExt}; @@ -406,6 +407,7 @@ pub fn start_notifications( do_notification ); + let page_states1 = page_states.clone(); tokio::spawn(async move { let conn = zbus::Connection::system() .await @@ -426,15 +428,25 @@ pub fn start_notifications( while let Some(e) = p.next().await { if let Ok(out) = e.args() { let action = out.action(); - do_gfx_action_notif( - "Gfx mode change requires", - &format!("{action:?}",), - ) + let mode = if let Ok(lock) = page_states1.lock() { + convert_gfx_mode(lock.gfx_state.mode) + } else { + GpuMode::Error + }; + match action { + supergfxctl::actions::UserActionRequired::Reboot => { + do_mux_notification( + "Graphics mode change requires reboot", + &mode, + ) + } + _ => do_gfx_action_notif(<&str>::from(action), *action), + } .map_err(|e| { error!("zbus signal: do_gfx_action_notif: {e}"); e }) - .unwrap(); + .ok(); } } }; @@ -445,6 +457,18 @@ pub fn start_notifications( Ok(()) } +fn convert_gfx_mode(gfx: GfxMode) -> GpuMode { + match gfx { + GfxMode::Hybrid => GpuMode::Optimus, + GfxMode::Integrated => GpuMode::Integrated, + GfxMode::NvidiaNoModeset => GpuMode::Discrete, + GfxMode::Vfio => GpuMode::Vfio, + GfxMode::AsusEgpu => GpuMode::Egpu, + GfxMode::AsusMuxDgpu => GpuMode::Ultimate, + GfxMode::None => GpuMode::Error, + } +} + fn base_notification(message: &str, data: &T) -> Notification where T: Display, @@ -516,47 +540,84 @@ fn do_gpu_status_notif(message: &str, data: &GfxPower) -> Result(message: &str, data: &T) -> Result<()> -where - T: Display, -{ - let mut notif = base_notification(message, data); - notif.action("gnome-session-quit", "Logout"); - notif.urgency(Urgency::Critical); - notif.timeout(3000); - notif.icon("dialog-warning"); - notif.hint(Hint::Transient(true)); +fn do_gfx_action_notif(message: &str, data: GfxUserAction) -> Result<()> { + let mut notif = Notification::new(); + + notif + .summary(NOTIF_HEADER) + .body(message) + .timeout(2000) + //.hint(Hint::Resident(true)) + .hint(Hint::Category("device".into())) + .urgency(Urgency::Critical) + .timeout(3000) + .icon("dialog-warning") + .hint(Hint::Transient(true)) + .action("gfx-mode-session-action", "Logout"); let handle = notif.show()?; - handle.wait_for_action(|id| { - if id == "gnome-session-quit" { - let mut cmd = Command::new("gnome-session-quit"); - cmd.spawn().ok(); - } else if id == "__closed" { - // TODO: cancel the switching + + if matches!(data, GfxUserAction::Logout) { + if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") { + if desktop.to_lowercase() == "gnome" { + handle.wait_for_action(|id| { + if id == "gfx-mode-session-action" { + let mut cmd = Command::new("gnome-session-quit"); + cmd.spawn().ok(); + } else if id == "__closed" { + // TODO: cancel the switching + } + }); + } else if desktop.to_lowercase() == "kde" { + handle.wait_for_action(|id| { + if id == "gfx-mode-session-action" { + let mut cmd = Command::new("qdbus"); + cmd.args(["org.kde.ksmserver", "/KSMServer", "logout", "1", "0", "0"]); + cmd.spawn().ok(); + } else if id == "__closed" { + // TODO: cancel the switching + } + }); + } else { + // todo: handle alternatives + } } - }); + } Ok(()) } /// Actual `GpuMode` unused as data is never correct until switched by reboot 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.action("gfx-mode-session-action", "Reboot"); notif.urgency(Urgency::Critical); notif.icon("system-reboot-symbolic"); notif.hint(Hint::Transient(true)); 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 + if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") { + if desktop.to_lowercase() == "gnome" { + handle.wait_for_action(|id| { + if id == "gfx-mode-session-action" { + let mut cmd = Command::new("gnome-session-quit"); + cmd.arg("--reboot"); + cmd.spawn().ok(); + } else if id == "__closed" { + // TODO: cancel the switching + } + }); + } else if desktop.to_lowercase() == "kde" { + handle.wait_for_action(|id| { + if id == "gfx-mode-session-action" { + let mut cmd = Command::new("qdbus"); + cmd.args(["org.kde.ksmserver", "/KSMServer", "logout", "1", "1", "0"]); + cmd.spawn().ok(); + } else if id == "__closed" { + // TODO: cancel the switching + } + }); } - }); + } }); Ok(()) } diff --git a/rog-platform/src/platform.rs b/rog-platform/src/platform.rs index 82e8874e..8c39488b 100644 --- a/rog-platform/src/platform.rs +++ b/rog-platform/src/platform.rs @@ -76,6 +76,8 @@ pub enum GpuMode { Optimus, Integrated, Egpu, + Vfio, + Ultimate, #[default] Error, NotSupported, @@ -135,6 +137,8 @@ impl Display for GpuMode { GpuMode::Optimus => write!(f, "Optimus"), GpuMode::Integrated => write!(f, "Integrated"), GpuMode::Egpu => write!(f, "eGPU"), + GpuMode::Vfio => write!(f, "VFIO"), + GpuMode::Ultimate => write!(f, "Ultimate"), GpuMode::Error => write!(f, "Error"), GpuMode::NotSupported => write!(f, "Not Supported"), }