fix(windows): tray double-click flicker + GPU use when minimized

1. Tray double-click (reported by @cucadmuh's brother-in-law):
   Windows fires a Click event on *both* halves of a double-click, so
   our left-click handler toggled visibility twice — the window popped
   up and immediately vanished. Switch the Windows branch to the
   `TrayIconEvent::DoubleClick` variant (Windows-only in tray-icon);
   other platforms keep the Click-on-Up behaviour. Matches the standard
   Windows tray convention (Discord, Telegram, etc).

2. GPU use while minimized:
   WebView2 on Windows keeps compositing infinite CSS animations
   (mesh-aura-a/b, portrait-drift, eq-bounce, track-pulse, led-pulse …)
   even when the window is minimized — steady visible GPU load on
   systems that should be idle. App.tsx now toggles a
   `data-app-hidden="true"` attribute on <html> on `visibilitychange`,
   and a single CSS rule pauses every `animation` at once via
   `animation-play-state: paused !important`. Zero cost when visible,
   catches all current and future infinite animations without
   per-element listeners.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-04-18 20:20:24 +02:00
parent 225609e93c
commit 66c0ecbc1f
3 changed files with 46 additions and 5 deletions
+14
View File
@@ -325,6 +325,20 @@ function AppShell() {
};
}, []);
// Pause CSS animations when the window is minimized / hidden.
// WebView2 on Windows keeps compositing infinite-loop animations (mesh-aura,
// portrait-drift, eq-bounce, …) even when the app is minimized, which shows
// up as steady GPU usage. The CSS rule `html[data-app-hidden="true"]` in
// components.css pauses all running animations while this flag is set.
useEffect(() => {
const update = () => {
document.documentElement.dataset.appHidden = document.hidden ? 'true' : 'false';
};
document.addEventListener('visibilitychange', update);
update();
return () => document.removeEventListener('visibilitychange', update);
}, []);
const isMobilePlayer = isMobile && location.pathname === '/now-playing';
return (
+12
View File
@@ -8804,3 +8804,15 @@ html.no-compositing .fsr-lyric-line.fsrl-active .fsr-lyric-word.active {
.device-sync-row-name { flex: 1; font-size: 0.85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.device-sync-row-meta { font-size: 0.75rem; color: var(--text-secondary); flex-shrink: 0; }
/* ── Pause CSS animations when the window is hidden / minimized ────────────
Set via App.tsx on `visibilitychange`. WebView2 on Windows keeps compositing
infinite CSS animations (mesh-aura, portrait-drift, eq-bounce, track-pulse,
led-pulse, …) even when the app is minimized, causing constant GPU use.
Pausing them cuts that to near zero while hidden without touching the
running Rust/audio threads. */
html[data-app-hidden="true"] *,
html[data-app-hidden="true"] *::before,
html[data-app-hidden="true"] *::after {
animation-play-state: paused !important;
}