perf(less-computer-glow): 隐藏时卸载全屏发光层,消除空闲 GPU 占用 (#675)
issue #470:彩虹描边 glow 是全屏 transparent 浮层 + 4 条无限动画(lcg-spin/breathe/ spin-reverse/flow)。原组件无状态无监听,窗口 .hide() 后 webview 仍持续合成发光层、 跑满 4 条动画,GPU 永不释放(Windows 尤其不释放)。 改为后端 show/hide 主动 emit `less-computer-glow:active` 驱动可见状态(不依赖在隐藏 窗口上失灵的 WebView2 visibilitychange):可见时渲染与原来完全一致的 DOM(视觉零变化), 不可见时返回 null 卸载发光层 → 零 GPU。另加 document.hidden 二级兜底(只停不启)。 注:glow 当前为 macOS-only(Windows show/hide 是 no-op),本修复消除 macOS 隐藏态泄漏, 并让组件具备跨平台「隐藏即零 GPU」安全性,为后续 Windows 重启用铺路。 Co-authored-by: 吕柏青 <lubaiqing9@gmail.com>
This commit is contained in:
1 parent
28ea5123b4
commit
9f3eebcb88
2 files changed
+36
No files matched your search
@@ -2181,6 +2181,8 @@ pub(crate) fn show_less_computer_glow<R: tauri::Runtime>(app: &AppHandle<R>) {
|
||||
}
|
||||
// 点击穿透:纯视觉浮层,绝不拦截鼠标。
|
||||
let _ = window.set_ignore_cursor_events(true);
|
||||
// issue #470:通知 glow 前端「可见」,恢复发光动画(隐藏时会 emit(false) 卸载发光层以释放 GPU)。
|
||||
let _ = window.emit("less-computer-glow:active", true);
|
||||
let window_clone = window.clone();
|
||||
let _ = app.run_on_main_thread(move || {
|
||||
use objc2::msg_send;
|
||||
@@ -2215,6 +2217,9 @@ pub(crate) fn show_less_computer_glow<R: tauri::Runtime>(_app: &AppHandle<R>) {}
|
||||
#[cfg(target_os = "macos")]
|
||||
pub(crate) fn hide_less_computer_glow<R: tauri::Runtime>(app: &AppHandle<R>) {
|
||||
if let Some(window) = app.get_webview_window("less-computer-glow") {
|
||||
// issue #470:先通知前端「不可见」卸载全屏发光层(4 条无限动画),webview 隐藏后即零 GPU;
|
||||
// 否则 .hide() 后 webview 仍持续合成发光层(Windows 尤其不释放动画)。
|
||||
let _ = window.emit("less-computer-glow:active", false);
|
||||
let _ = window.hide();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// 只画贴边光带,不铺暗场;彩色弧段沿边缘流动,模拟 Apple Intelligence 的粗细变化。
|
||||
// 纯视觉:pointer-events:none,后端再 set_ignore_cursor_events(true)。仅 macOS 显示。
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const glowCss = `
|
||||
@property --lcg-angle { syntax: '<angle>'; initial-value: 0deg; inherits: false; }
|
||||
@keyframes lcg-spin { to { --lcg-angle: 360deg; } }
|
||||
@@ -93,6 +95,35 @@ if (typeof document !== 'undefined' && !document.getElementById('less-computer-g
|
||||
}
|
||||
|
||||
export function LessComputerGlow() {
|
||||
// issue #470:窗口 .hide() 后 webview 不会自动停掉这 4 条无限动画(Windows 尤其不释放),
|
||||
// 全屏发光层持续占 GPU 合成。改由后端 show/hide 主动 emit 可见状态驱动:不可见时直接卸载
|
||||
// 发光层(无元素 → 零 GPU),可见时原样渲染——显示时视觉零变化。
|
||||
const [active, setActive] = useState(true);
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
let unlisten: (() => void) | undefined;
|
||||
void import('@tauri-apps/api/event').then(({ listen }) => {
|
||||
if (cancelled) return;
|
||||
void listen<boolean>('less-computer-glow:active', (e) => {
|
||||
setActive(Boolean(e.payload));
|
||||
}).then((un) => {
|
||||
if (cancelled) un();
|
||||
else unlisten = un;
|
||||
});
|
||||
});
|
||||
// 二级兜底:页面被标记为隐藏时也停(只停不启,绝不误关正在显示的发光)。
|
||||
const onVisibility = () => {
|
||||
if (document.hidden) setActive(false);
|
||||
};
|
||||
document.addEventListener('visibilitychange', onVisibility);
|
||||
return () => {
|
||||
cancelled = true;
|
||||
unlisten?.();
|
||||
document.removeEventListener('visibilitychange', onVisibility);
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (!active) return null;
|
||||
return (
|
||||
<div className="lcg-root" aria-hidden>
|
||||
<span className="lcg-flow" />
|
||||
|
||||
Reference in new issue
Block a user