From 6b2271385410608555b11d3894c76245d77c1eff Mon Sep 17 00:00:00 2001 From: alger Date: Sun, 19 Apr 2026 15:31:23 +0800 Subject: [PATCH] =?UTF-8?q?perf(lyric-window):=20=E4=BB=85=E5=9C=A8?= =?UTF-8?q?=E9=94=81=E5=AE=9A+=E5=8F=AF=E8=A7=81=E6=97=B6=E5=90=AF?= =?UTF-8?q?=E7=94=A8=E9=BC=A0=E6=A0=87=E4=BD=8D=E7=BD=AE=E8=BD=AE=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 set-lyric-lock-state IPC, 渲染端 watch isLock 同步到主进程 - 主进程通过 isLyricLocked + isLyricWindowVisible 控制轮询启停 - 监听窗口 show/hide/minimize/restore, 隐藏时停止 50ms 轮询 - 解锁状态下 DOM mouseenter/mouseleave 已足够, 无需轮询兜底 --- src/main/lyric.ts | 40 +++++++++++++++++++++++++++--- src/renderer/views/lyric/index.vue | 5 ++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/main/lyric.ts b/src/main/lyric.ts index 7e059bf..61e9925 100644 --- a/src/main/lyric.ts +++ b/src/main/lyric.ts @@ -10,8 +10,11 @@ let isDragging = false; // 添加窗口大小变化防护 let originalSize = { width: 0, height: 0 }; +// 轮询只在 "锁定 + 窗口可见" 时启用:解锁状态下 DOM 事件足够,避免常驻 50ms 轮询 let mousePresenceTimer: ReturnType | null = null; let lastMouseInside: boolean | null = null; +let isLyricLocked = false; +let isLyricWindowVisible = false; const isPointInsideWindow = ( point: { x: number; y: number }, @@ -59,6 +62,14 @@ const startMousePresenceTracking = () => { }, 50); }; +const syncMousePresenceTracking = () => { + if (isLyricLocked && isLyricWindowVisible && lyricWindow && !lyricWindow.isDestroyed()) { + startMousePresenceTracking(); + } else { + stopMousePresenceTracking(); + } +}; + const createWin = () => { console.log('Creating lyric window'); @@ -151,12 +162,32 @@ const createWin = () => { // 监听窗口关闭事件 lyricWindow.on('closed', () => { stopMousePresenceTracking(); + isLyricLocked = false; + isLyricWindowVisible = false; if (lyricWindow) { lyricWindow.destroy(); lyricWindow = null; } }); + // 窗口可见性变化时同步轮询状态,避免最小化/隐藏时空转 + lyricWindow.on('show', () => { + isLyricWindowVisible = true; + syncMousePresenceTracking(); + }); + lyricWindow.on('hide', () => { + isLyricWindowVisible = false; + stopMousePresenceTracking(); + }); + lyricWindow.on('minimize', () => { + isLyricWindowVisible = false; + stopMousePresenceTracking(); + }); + lyricWindow.on('restore', () => { + isLyricWindowVisible = true; + syncMousePresenceTracking(); + }); + // 监听窗口大小变化事件,保存新的尺寸 lyricWindow.on('resize', () => { // 如果正在拖动,忽略大小调整事件 @@ -184,7 +215,6 @@ export const loadLyricWindow = (ipcMain: IpcMain, mainWin: BrowserWindow): void } lyricWindow.focus(); lyricWindow.show(); - startMousePresenceTracking(); return true; } return false; @@ -219,7 +249,6 @@ export const loadLyricWindow = (ipcMain: IpcMain, mainWin: BrowserWindow): void win.once('ready-to-show', () => { console.log('Lyric window ready to show'); win.show(); - startMousePresenceTracking(); }); }); @@ -248,7 +277,6 @@ export const loadLyricWindow = (ipcMain: IpcMain, mainWin: BrowserWindow): void ipcMain.on('close-lyric', () => { if (lyricWindow && !lyricWindow.isDestroyed()) { - stopMousePresenceTracking(); lyricWindow.webContents.send('lyric-window-close'); mainWin.webContents.send('lyric-control-back', 'close'); mainWin.webContents.send('lyric-window-closed'); @@ -257,6 +285,12 @@ export const loadLyricWindow = (ipcMain: IpcMain, mainWin: BrowserWindow): void } }); + // 渲染端同步锁定状态 → 决定主进程是否需要轮询鼠标位置 + ipcMain.on('set-lyric-lock-state', (_, isLocked: boolean) => { + isLyricLocked = isLocked; + syncMousePresenceTracking(); + }); + // 处理鼠标事件 ipcMain.on('mouseenter-lyric', () => { if (lyricWindow && !lyricWindow.isDestroyed()) { diff --git a/src/renderer/views/lyric/index.vue b/src/renderer/views/lyric/index.vue index dceeaa0..56536fb 100644 --- a/src/renderer/views/lyric/index.vue +++ b/src/renderer/views/lyric/index.vue @@ -401,6 +401,8 @@ watch( // 锁定时自动关闭主题色面板 showThemeColorPanel.value = false; } + // 通知主进程,按需启停鼠标位置轮询 + windowData.electron.ipcRenderer.send('set-lyric-lock-state', newLock); } ); @@ -794,6 +796,9 @@ onMounted(() => { } } ); + + // 同步初始锁定状态到主进程,使其按需启动鼠标位置轮询 + windowData.electron.ipcRenderer.send('set-lyric-lock-state', lyricSetting.value.isLock); }); onUnmounted(() => {