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)
- 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

78
Cargo.lock generated
View File

@@ -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"

View File

@@ -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"

View File

@@ -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");

View File

@@ -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<T>(message: &str, data: &T) -> Notification
where
T: Display,
@@ -516,47 +540,84 @@ fn do_gpu_status_notif(message: &str, data: &GfxPower) -> Result<NotificationHan
Ok(Notification::show(&notif)?)
}
fn do_gfx_action_notif<T>(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(())
}

View File

@@ -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"),
}