Various tray and notification improvements

This commit is contained in:
Luke D. Jones
2023-04-26 10:57:13 +12:00
parent 31af8f9511
commit 25ecfda095
6 changed files with 181 additions and 42 deletions

View File

@@ -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) - Better support of using supergfxctl when available (tray icon and menu)
- Check supergfx version before enabling use in tray - Check supergfx version before enabling use in tray
- Update allowed Aura modes on asusd restart if changed - 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] ## [v4.6.0]
### Added ### Added

78
Cargo.lock generated
View File

@@ -638,6 +638,37 @@ dependencies = [
"winapi", "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]] [[package]]
name = "color_quant" name = "color_quant"
version = "1.1.0" version = "1.1.0"
@@ -894,7 +925,6 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]] [[package]]
name = "ecolor" name = "ecolor"
version = "0.21.0" version = "0.21.0"
source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
] ]
@@ -902,30 +932,32 @@ dependencies = [
[[package]] [[package]]
name = "eframe" name = "eframe"
version = "0.21.3" version = "0.21.3"
source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"cocoa",
"egui", "egui",
"egui-winit", "egui-winit",
"egui_glow", "egui_glow",
"glow", "glow",
"glutin", "glutin",
"glutin-winit", "glutin-winit",
"image",
"js-sys", "js-sys",
"log", "log",
"objc",
"percent-encoding", "percent-encoding",
"raw-window-handle", "raw-window-handle",
"thiserror", "thiserror",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"web-sys", "web-sys",
"winapi",
"winit", "winit",
] ]
[[package]] [[package]]
name = "egui" name = "egui"
version = "0.21.0" version = "0.21.0"
source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"ahash", "ahash",
@@ -937,13 +969,13 @@ dependencies = [
[[package]] [[package]]
name = "egui-winit" name = "egui-winit"
version = "0.21.1" version = "0.21.1"
source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def"
dependencies = [ dependencies = [
"accesskit_winit", "accesskit_winit",
"arboard", "arboard",
"egui", "egui",
"instant", "instant",
"log", "log",
"raw-window-handle",
"smithay-clipboard", "smithay-clipboard",
"webbrowser", "webbrowser",
"winit", "winit",
@@ -952,7 +984,6 @@ dependencies = [
[[package]] [[package]]
name = "egui_glow" name = "egui_glow"
version = "0.21.0" version = "0.21.0"
source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"egui", "egui",
@@ -972,7 +1003,6 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]] [[package]]
name = "emath" name = "emath"
version = "0.21.0" version = "0.21.0"
source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
] ]
@@ -1057,7 +1087,6 @@ dependencies = [
[[package]] [[package]]
name = "epaint" name = "epaint"
version = "0.21.0" version = "0.21.0"
source = "git+https://github.com/emilk/egui?rev=b8e798777de519de3a1878798097ab2ab0bd4def#b8e798777de519de3a1878798097ab2ab0bd4def"
dependencies = [ dependencies = [
"ab_glyph", "ab_glyph",
"ahash", "ahash",
@@ -1674,6 +1703,20 @@ dependencies = [
"unicode-normalization", "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]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.9.3" version = "1.9.3"
@@ -2123,6 +2166,27 @@ dependencies = [
"zbus", "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]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.15" version = "0.2.15"

View File

@@ -10,8 +10,10 @@ edition = "2021"
mocking = [] mocking = []
[dependencies] [dependencies]
egui = { 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"} # eframe = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"}
egui = { path = "../../egui/crates/egui" }
eframe = { path = "../../egui/crates/eframe" }
libappindicator = "0.7" # Tray icon libappindicator = "0.7" # Tray icon
gtk = "0.15.5" gtk = "0.15.5"

View File

@@ -480,7 +480,13 @@ pub fn init_tray(
match lock.gfx_state.power_status { match lock.gfx_state.power_status {
GfxPower::Suspended => tray.set_icon("asus_notif_blue"), 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::AsusDisabled => tray.set_icon("asus_notif_white"),
GfxPower::AsusMuxDiscreet | GfxPower::Active => { GfxPower::AsusMuxDiscreet | GfxPower::Active => {
tray.set_icon("asus_notif_red"); tray.set_icon("asus_notif_red");

View File

@@ -17,7 +17,8 @@ use rog_dbus::zbus_profile::ProfileProxy;
use rog_platform::platform::GpuMode; use rog_platform::platform::GpuMode;
use rog_profiles::Profile; use rog_profiles::Profile;
use serde::{Deserialize, Serialize}; 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 supergfxctl::zbus_proxy::DaemonProxy as SuperProxy;
use tokio::time::sleep; use tokio::time::sleep;
use zbus::export::futures_util::{future, StreamExt}; use zbus::export::futures_util::{future, StreamExt};
@@ -406,6 +407,7 @@ pub fn start_notifications(
do_notification do_notification
); );
let page_states1 = page_states.clone();
tokio::spawn(async move { tokio::spawn(async move {
let conn = zbus::Connection::system() let conn = zbus::Connection::system()
.await .await
@@ -426,15 +428,25 @@ pub fn start_notifications(
while let Some(e) = p.next().await { while let Some(e) = p.next().await {
if let Ok(out) = e.args() { if let Ok(out) = e.args() {
let action = out.action(); let action = out.action();
do_gfx_action_notif( let mode = if let Ok(lock) = page_states1.lock() {
"Gfx mode change requires", convert_gfx_mode(lock.gfx_state.mode)
&format!("{action:?}",), } 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| { .map_err(|e| {
error!("zbus signal: do_gfx_action_notif: {e}"); error!("zbus signal: do_gfx_action_notif: {e}");
e e
}) })
.unwrap(); .ok();
} }
} }
}; };
@@ -445,6 +457,18 @@ pub fn start_notifications(
Ok(()) 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<T>(message: &str, data: &T) -> Notification fn base_notification<T>(message: &str, data: &T) -> Notification
where where
T: Display, T: Display,
@@ -516,47 +540,84 @@ fn do_gpu_status_notif(message: &str, data: &GfxPower) -> Result<NotificationHan
Ok(Notification::show(&notif)?) Ok(Notification::show(&notif)?)
} }
fn do_gfx_action_notif<T>(message: &str, data: &T) -> Result<()> fn do_gfx_action_notif(message: &str, data: GfxUserAction) -> Result<()> {
where let mut notif = Notification::new();
T: Display,
{ notif
let mut notif = base_notification(message, data); .summary(NOTIF_HEADER)
notif.action("gnome-session-quit", "Logout"); .body(message)
notif.urgency(Urgency::Critical); .timeout(2000)
notif.timeout(3000); //.hint(Hint::Resident(true))
notif.icon("dialog-warning"); .hint(Hint::Category("device".into()))
notif.hint(Hint::Transient(true)); .urgency(Urgency::Critical)
.timeout(3000)
.icon("dialog-warning")
.hint(Hint::Transient(true))
.action("gfx-mode-session-action", "Logout");
let handle = notif.show()?; let handle = notif.show()?;
handle.wait_for_action(|id| {
if id == "gnome-session-quit" { if matches!(data, GfxUserAction::Logout) {
let mut cmd = Command::new("gnome-session-quit"); if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
cmd.spawn().ok(); if desktop.to_lowercase() == "gnome" {
} else if id == "__closed" { handle.wait_for_action(|id| {
// TODO: cancel the switching 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(()) Ok(())
} }
/// Actual `GpuMode` unused as data is never correct until switched by reboot /// Actual `GpuMode` unused as data is never correct until switched by reboot
fn do_mux_notification(message: &str, m: &GpuMode) -> Result<()> { fn do_mux_notification(message: &str, m: &GpuMode) -> Result<()> {
let mut notif = base_notification(message, &m.to_string()); 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.urgency(Urgency::Critical);
notif.icon("system-reboot-symbolic"); notif.icon("system-reboot-symbolic");
notif.hint(Hint::Transient(true)); notif.hint(Hint::Transient(true));
let handle = notif.show()?; let handle = notif.show()?;
std::thread::spawn(|| { std::thread::spawn(|| {
handle.wait_for_action(|id| { if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
if id == "gnome-session-quit" { if desktop.to_lowercase() == "gnome" {
let mut cmd = Command::new("gnome-session-quit"); handle.wait_for_action(|id| {
cmd.arg("--reboot"); if id == "gfx-mode-session-action" {
cmd.spawn().ok(); let mut cmd = Command::new("gnome-session-quit");
} else if id == "__closed" { cmd.arg("--reboot");
// TODO: cancel the switching 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(()) Ok(())
} }

View File

@@ -76,6 +76,8 @@ pub enum GpuMode {
Optimus, Optimus,
Integrated, Integrated,
Egpu, Egpu,
Vfio,
Ultimate,
#[default] #[default]
Error, Error,
NotSupported, NotSupported,
@@ -135,6 +137,8 @@ impl Display for GpuMode {
GpuMode::Optimus => write!(f, "Optimus"), GpuMode::Optimus => write!(f, "Optimus"),
GpuMode::Integrated => write!(f, "Integrated"), GpuMode::Integrated => write!(f, "Integrated"),
GpuMode::Egpu => write!(f, "eGPU"), GpuMode::Egpu => write!(f, "eGPU"),
GpuMode::Vfio => write!(f, "VFIO"),
GpuMode::Ultimate => write!(f, "Ultimate"),
GpuMode::Error => write!(f, "Error"), GpuMode::Error => write!(f, "Error"),
GpuMode::NotSupported => write!(f, "Not Supported"), GpuMode::NotSupported => write!(f, "Not Supported"),
} }