feat(themes): warn about animated themes on high-CPU setups (#1020)

* feat(themes): warn about animated themes on high-CPU setups

Show a warning icon + tooltip on animated themes (those defining
@keyframes) in the store and in Your Themes, on Linux setups where
animation is costly — the Nvidia WebKit quirk is active or compositing
is forced off. The Nvidia detection already runs once at startup; its
result is recorded (theme_animation.rs) and read via a new
theme_animation_risk command — no GPU re-probe. Display-only; never
shown off Linux. The animated flag comes from the registry (store) or
the theme CSS (Your Themes).

* docs(themes): note the animated-theme warning PR in the Theme Store entry
This commit is contained in:
Psychotoxical
2026-06-07 20:38:36 +02:00
committed by GitHub
parent daa6fbbfd7
commit 88f7a7bc90
20 changed files with 144 additions and 7 deletions
+2
View File
@@ -6,6 +6,7 @@ mod cover_cache;
mod library_analysis_backfill;
mod lib_commands;
mod theme_import;
pub mod theme_animation;
pub use psysonic_integration::discord;
@@ -653,6 +654,7 @@ pub fn run() {
performance_cpu_snapshot,
set_subsonic_wire_user_agent,
no_compositing_mode,
theme_animation_risk,
linux_xdg_session_type,
is_tiling_wm_cmd,
open_mini_player,
@@ -23,6 +23,7 @@ pub(crate) use perf::performance_cpu_snapshot;
pub(crate) use platform::{
linux_wayland_gpu_font_tuning_active, linux_wayland_text_render_settings_available,
set_linux_wayland_text_render_profile, set_linux_webkit_smooth_scrolling, set_window_decorations,
theme_animation_risk,
};
#[cfg(target_os = "linux")]
pub(crate) use platform::{
@@ -137,6 +137,29 @@ pub(crate) fn linux_webkit_apply_wayland_gpu_font_tuning(win: &tauri::WebviewWin
}
/// Toggle native window decorations at runtime (Linux custom title bar opt-out).
/// Tauri command: true when theme animations may be costly on this setup —
/// Linux with the Nvidia WebKit quirk active (recorded once at startup) or
/// compositing forced off. The frontend warns on animated themes when true.
/// Always false off Linux.
#[tauri::command]
pub(crate) fn theme_animation_risk() -> bool {
#[cfg(target_os = "linux")]
{
// Compositing forced off → GPU-accelerated effects/animation are costly.
if std::env::var("WEBKIT_DISABLE_COMPOSITING_MODE")
.map(|v| v == "1")
.unwrap_or(false)
{
return true;
}
crate::theme_animation::nvidia_quirk_active()
}
#[cfg(not(target_os = "linux"))]
{
false
}
}
#[tauri::command]
pub(crate) fn set_window_decorations(enabled: bool, app_handle: tauri::AppHandle) {
if let Some(win) = app_handle.get_webview_window("main") {
+6 -1
View File
@@ -17,11 +17,16 @@ fn apply_linux_webkit_nvidia_quirk() {
// may still be `XDG_SESSION_TYPE=wayland`. The quirk maps that to `__NV_DISABLE_EXPLICIT_SYNC`,
// which mismatches a real X11 EGL stack and can leave the webview gray — mirror the native-X11
// branch (`WEBKIT_DISABLE_DMABUF_RENDERER` only) whenever GDK is pinned to x11 first in the list.
// Detect once and record it for the UI's animated-theme CPU-load warning,
// so the theme_animation_risk command never has to re-probe the GPU.
let kind = needs_workaround();
psysonic_lib::theme_animation::set_nvidia_quirk_active(!matches!(kind, WorkaroundKind::None));
let forced_x11_gdk = std::env::var("GDK_BACKEND").ok().is_some_and(|s| {
matches!(s.split(',').next().map(str::trim), Some("x11"))
});
if forced_x11_gdk {
match needs_workaround() {
match kind {
WorkaroundKind::None => {}
WorkaroundKind::DisableWebkitDmabufRenderer | WorkaroundKind::DisableNvExplicitSync => {
set_webkit_disable_dmabuf_renderer();
+22
View File
@@ -0,0 +1,22 @@
//! Startup-recorded display hint for the theme system.
//!
//! The Nvidia/WebKit GPU quirk is detected once at process start (in `main()`,
//! before the webview/GTK init). We record whether it was needed so the UI can
//! warn that animated themes may raise CPU load on this setup — without
//! re-probing the GPU later. Read via the `theme_animation_risk` command
//! (`lib_commands::app_api::platform`).
use std::sync::OnceLock;
static NVIDIA_QUIRK_ACTIVE: OnceLock<bool> = OnceLock::new();
/// Record the startup Nvidia-WebKit-quirk detection. Called once from `main()`.
pub fn set_nvidia_quirk_active(active: bool) {
let _ = NVIDIA_QUIRK_ACTIVE.set(active);
}
/// Whether the Nvidia WebKit quirk was needed at startup. False when unrecorded
/// (non-Linux, or GPU acceleration opted in via `PSYSONIC_WEBKIT_GPU_ACCEL`).
pub(crate) fn nvidia_quirk_active() -> bool {
NVIDIA_QUIRK_ACTIVE.get().copied().unwrap_or(false)
}