mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Various tray and notification improvements
This commit is contained in:
@@ -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
78
Cargo.lock
generated
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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(¬if)?)
|
Ok(Notification::show(¬if)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user