Commit Graph

817 Commits

Author SHA1 Message Date
alger 61797494cb fix(lyric): 点击歌词跳转不再跳到歌曲末尾触发切歌
根因:MusicHook.parseLyricsString 的 lrcTimeArray 直接使用 yrcParser 的
毫秒时间戳,而 seek/nowTime 全链路以秒为单位。合并播放重构(#712)后
'先播放、歌词后到'使 ensureLyricsLoaded 的 API 兜底分支成为在线歌曲
常规路径,点击歌词 seek(毫秒值) 被钳到音频末尾直接触发 ended 切歌,
歌词高亮同步也一并失效。

修复:
- parseLyricsString 时间数组统一换算为秒,与 usePlayerHooks.parseLyrics 一致
- 完整歌词对象(yrc 逐字/翻译)异步送达时强制重新解析,替换先行的兜底纯 lrc

测试:以真实 LRC/YRC 样本驱动真实 yrcParser 验证 7 项断言全过,
含修复前行为回归复现(seek(28910) 钳到末尾触发切歌)与修复后
全行点击不触发切歌、两解析路径单位一致性。
2026-07-05 16:05:03 +08:00
alger 8f0a959d44 fix(window): 修复迷你模式相关的两处状态污染
- 展开播放列表后的 340x400 迷你窗口被误判为普通窗口并持久化到
  windowState,导致下次启动主窗口尺寸异常
- 迷你/主界面切换时复位 musicFull,避免残留 true 使返回后第一次点击
  歌曲信息被取反关闭、全屏播放页'打不开'

Closes #242
2026-07-05 15:16:56 +08:00
alger dafd41cc2a fix(mini): 迷你模式右键'添加到歌单'恢复主窗口后接力打开歌单抽屉
Mini 窗口宽 340px 容不下 420px 歌单抽屉,此前 provide 的是空实现点击
无反应。现记录待添加歌曲 → window.api.restore() 恢复主窗口 →
AppLayout 挂载后自动打开歌单抽屉完成添加。

Closes #504
2026-07-05 15:16:50 +08:00
alger fde632aaa9 fix(lyric): 桌面歌词三处 UI 问题(主题色重置/延迟控件遮挡/锁图标淡出)
- 主题色面板新增'恢复默认'按钮,接入已有 resetThemeColor(此前设置自定义
  主题色后无任何入口可关闭,#591)
- 全屏歌词页的歌词延迟调整控件 bottom 从 16px 提至 96px,越过钉底的
  PlayBar(80px, z-index 9999),不再被遮挡无法点击(#592)
- 锁定态锁图标增加空闲淡出:无鼠标活动 2.5s 后隐藏并恢复点击穿透,
  mousemove(forward:true 转发)即重新唤出,移出窗口立即隐藏(#606)

Closes #591
Closes #592
Closes #606
2026-07-05 15:14:36 +08:00
alger 6676dec4ac fix(playlist): 歌单增删歌曲后刷新用户歌单列表
添加/删除成功后调用 initializePlaylist 重新拉取,用户页与详情页的
歌曲总数(trackCount)会话内即时更新;重启后仍滞后属网易服务端缓存,
客户端无法根治。

Closes #508
2026-07-05 15:08:45 +08:00
alger 6e69676766 feat(pwa): 补齐 web 端 PWA 可安装条件
- 新增 192/512 图标与 maskable 变体(源自 icon.png,安全区 80%)
- manifest.json 图标声明修正(原先仅声明一个实际不存在的 256 尺寸)
- 注册最小 Service Worker(空 fetch 处理器,不做缓存拦截),仅 Web 生产环境生效

Closes #640
Ref #382
2026-07-05 15:06:19 +08:00
alger 4b6303f557 fix(web): 修复 web 端构建失败(顶层 await 超出默认 target)
f652932 起 MusicHook 使用顶层 await,vite 默认 target(es2020/chrome87)
无法转译,npx vite build 直接报错——web 版因此无法产出新构建(#641 的
'网页版还是 5.0.0'与此相关)。build.target 提升至 es2022。

Ref #641
2026-07-05 15:06:13 +08:00
alger 80de1f88c6 feat(songitem): 外语歌曲显示中文译名/别名
网易 API 的 tns/alia 字段已随 formatSong 展开保留在歌曲对象上,
SongResult 补类型声明,5 个歌曲条目变体在歌名后以灰色小字显示译名。

Closes #629
2026-07-05 15:01:58 +08:00
alger 9d3a4dd4fb fix(build): 重生成 Windows 图标补齐 64/96/128 中间尺寸层
原 icon.ico 仅含 16/24/32/48/256 五层,高 DPI(如 4K 200% 缩放)任务栏
需要约 64px 图标时只能从 48 放大导致模糊。现补齐 16-128 全梯度 BMP 层
+ 256 PNG 层,NSIS 安装器图标一并受益。

Closes #376
2026-07-05 14:58:54 +08:00
alger d5395f7c75 fix(main): 拒绝麦克风/摄像头采集权限请求,防止系统授权弹窗
应用无任何录音功能;#639 已移除触发弹窗的 getUserMedia 调用(03b52cd),
本次在主进程权限层加防御:media/audioCapture 请求一律拒绝,防止未来依赖库
静默申请麦克风。输出设备枚举与 setSinkId 切换不受影响。

Ref #147 #246 #440 #639
2026-07-05 14:55:44 +08:00
alger 5c45134909 fix(player): 系统媒体控件(SMTC)封面尺寸上限提升至 1024
artwork 增加 1024x1024 档位并改用 getImgUrl 生成 URL,正确处理
data:/local:// 封面与已带参数的图片地址,提升 AMLL 等 SMTC 监听端的封面清晰度。

Closes #595
2026-07-05 14:51:57 +08:00
alger 97209e9053 fix(download): 单独下载歌词的文件名跟随文件名格式设置
downloadLyric 改用 set.downloadNameFormat 模板拼接文件名,与歌曲下载行为
一致(此前硬编码'歌曲名 - 歌手');多歌手连接符与歌曲下载统一为'、'。

Closes #655
2026-07-05 14:51:51 +08:00
alger 40faf92863 fix(i18n): 洛雪音源名称错别字修正(落雪→洛雪)
LX Music 官方中文名为'洛雪音乐助手',设置页三种语言的用户可见文案统一修正。

Closes #565
2026-07-05 14:47:43 +08:00
alger 3fc25ba9a4 feat(local-music): 支持从本地列表移除单曲并防止扫描失败误删(#713)
- 右键菜单新增'从本地列表移除'(本地歌曲自动切换文案,仅移除条目不删文件,5 语言文案)
- localMusic store 新增 removeEntry action
- 扫描失败的文件夹不再参与'已删除清理',避免移动盘/网络盘暂时不可用时整夹歌曲被误删
- 注:'刷新不清理已删除歌曲'主症状已由 c28368f 修复,本次补齐评论区诉求与防护

Closes #713
2026-07-05 14:35:00 +08:00
alger 2d693cee17 fix(parser): gdmusic 音源增加搜索结果校验,避免解析出货不对版的歌曲
此前 gdmusic 无条件取搜索第一条结果,版权下架歌曲(如周杰伦)会解析出
翻唱/同名不同曲并直接播放(#704)。现改为取前 5 条候选做归一化匹配:
- 歌名必须匹配(忽略大小写/标点/括号内 Live 等备注)
- 候选带歌手信息时歌手也必须匹配,宁可解析失败也不返回错歌
- 版权导致的全音源无资源属外部问题,代码层保证不再放错歌

Ref #704
2026-07-05 14:29:40 +08:00
alger 07d4204b5a fix(build): 修复 Ubuntu/Linux 安装后应用图标显示为齿轮
根因:linux.icon 指向单张 1084x1084 PNG,electron-builder 将其原样装入
hicolor/1084x1084/(非法的主题尺寸目录),GNOME 图标主题索引无法命中,
启动器/任务栏回退为齿轮默认图标。

新增 build/icons 标准尺寸集(16-1024),deb/rpm/AppImage 均装入合法的
hicolor 尺寸目录。已实际构建 deb 对比验证新旧产物。

Closes #701
2026-07-05 14:26:55 +08:00
alger baf3c7832e fix(songitem): 添加到歌单权限判断改为响应式并提示不可用原因
- 权限判断从 localStorage 快照改为 userStore 响应式状态,登录/登出后菜单状态即时刷新
- 菜单项不再灰色禁用,未登录或 UID 登录时点击给出明确提示(新增 5 语言文案)

Closes #706
2026-07-05 14:09:57 +08:00
alger edc7e70158 fix(player): 私人 FM 模式下点击上一曲不再重放当前歌曲
_prevPlay 补充 FM 分支:FM 不支持回到上一首,与下一曲行为一致直接拉取新的 FM 歌曲。
此前 FM 列表只有一首歌,上一曲计算出的索引仍是当前曲目导致原地重放。

Closes #682
2026-07-05 14:09:51 +08:00
alger da80dbc761 fix(main): 修复 config.json 并发读写导致的 EBUSY 主进程崩溃弹窗
- 主进程 6 个独立 Store 实例合并为共享单例(window-size/lyric/server/deviceInfo/window 复用 config.ts 实例)
- initializeConfig 幂等化,修复 set-store-value IPC 监听重复注册导致的双倍写入
- 窗口/歌词窗 move、resize 保存增加 500ms 防抖,拖动时不再每秒几十次写盘,close 时冲刷落盘
- store 读写 IPC handler 与窗口状态读写加 try-catch,撞锁丢弃单次写入而非崩溃
- 全局 uncaughtException 兜底:文件锁类错误(EBUSY/EPERM 等)仅记日志,其余异常保留报错弹窗

Closes #714
2026-07-05 14:06:01 +08:00
alger 837f0268d5 fix(player): 合并外部贡献后的集成修复
- PlayBar 下载按钮补 isElectron 守卫,Web 端不再显示无效按钮(#708 评审意见)
- preloadNextSongs 恢复 800ms 短去抖,避免快速切歌时音源请求风暴(#712 评审意见)
- 清理合并后未使用的导入
2026-07-05 14:00:07 +08:00
alger 8ea13e04f0 Merge pull request #712 from daili115/trae/agent-m1V9o5
feat: 优化音乐播放性能,实现异步加载和即时预加载
2026-07-05 13:55:34 +08:00
alger 91a3259e27 Merge pull request #708 from jiang-LJ/main
feat(player): 在播放栏添加下载当前歌曲按钮
2026-07-05 13:55:34 +08:00
alger ecb85f0146 Merge pull request #676 from chengww5217/refactor/persisted-storage
refactor(persist): localStorage 配额防护与历史持久化重写
2026-07-05 13:55:20 +08:00
alger 6bea735aef Merge pull request #675 from chengww5217/fix/local-music-playback
fix(local-music): 修复本地音乐播放失败、进度异常与切歌失效
2026-07-05 13:55:20 +08:00
alger d9b102879f Merge pull request #677 from chengww5217/chore/fix-existing-lint
ci: 修复 PR Code Quality job 失败(存量 lint + typecheck 拿不到 unplugin d.ts)
2026-07-05 13:55:09 +08:00
daili115 c5035b0583 feat: 修复软件切歌慢问题
Co-authored-by: traeagent <traeagent@users.noreply.github.com>
2026-06-25 07:41:15 +00:00
jiang-LJ 7792eeac2e feat(player): 在播放栏添加下载当前歌曲按钮 2026-06-17 21:57:01 +08:00
chengww 1a8b5f4977 ci: 加 setup-bun 让 lint:i18n 步骤能跑
package.json 里 lint:i18n = "bun scripts/check_i18n.ts",但 pr-check.yml
只装了 Node 没装 bun,I18n check 步骤报 sh: bun: not found。

之前这个错误被前两步(lint / typecheck)的失败遮住,前两步修了之后才暴露。
用官方 oven-sh/setup-bun 一步搞定,放在 setup-node 之后、install 之前。
2026-05-18 00:07:05 +08:00
chengww 95694057ec ci: typecheck 前先跑 build 让 unplugin 生成自动 import d.ts
tsconfig.web.json 的 compilerOptions.types 显式 require
src/renderer/{auto-imports,components}.d.ts,这两个文件由
unplugin-auto-import / unplugin-vue-components 在 vite 启动时生成,
且被 .gitignore 排除(58922dc 维护者主动设置)。

CI 直接跑 typecheck 拿不到 d.ts 会报 TS2688,导致所有 PR 都过不了
Code Quality job。在 Type check 步骤前插入一次 npm run build 触发
unplugin 生成 d.ts,同时顺带验证 build 链路(一次到位,不增加额外
专用脚本,CI 多 30-60s 但能拦下 build 阶段的回归)。

本地验证:删除两个 d.ts 后跑 npm run build 重新生成,typecheck 通过。
2026-05-18 00:01:19 +08:00
chengww 938c497ca3 chore: 修复 main 上的存量 lint 错误
pr-check.yml 只在 PR 触发,main push 不跑 lint,导致存量错误一直未被发现,
PR #675 / #676 都被 Code Quality job 拦下。

- 9 处 prettier/prettier 格式错误:StickyTabPage.vue / RadioCard.vue /
  list/index.vue / mv/index.vue / podcast/index.vue 的属性换行与 import
  排序,全部 eslint --fix 自动修复
- 1 处 no-undef ScrollToOptions(StickyTabPage.vue:79):在 eslint.config.mjs
  的 .ts 与 .vue 配置块同时补 ScrollToOptions 到 globals,与既有的
  ScrollBehavior 同级;TypeScript DOM lib 类型不在 globals.browser 里,
  需手动声明
2026-05-17 23:54:28 +08:00
chengww a078e37e2c fix(build): renderer 单 chunk 打包,规避 chunk 间循环依赖 TDZ 白屏
store/index.ts 用 `export *` 聚合所有 store + 抽出的共享工具(如
debouncedStorage)被多 store 引用,Vite 6 默认拆分会让 utils 合并到
entry chunk,再与 store chunk 形成 index ↔ store 循环;当循环 chunk
顶层同步访问对方导出的 const(如 `persist: { storage: debouncedLocalStorage }`),
生产构建会触发 TDZ 报错 `Cannot access 'debouncedLocalStorage' before
initialization`,表现为打包后白屏(dev 不分包不暴露)。

Electron 桌面端无 CDN/首屏体积顾虑,单 chunk 是最简洁的兜底。
2026-05-17 23:38:33 +08:00
chengww 405b144e66 refactor(playHistory): v1 旧 localStorage key 清理与调用方对齐
老用户升级后清掉 v1 时代独立 key 释放配额,调用方切到 store API。

- player.ts initializePlayState 调用从 migrateFromLocalStorage 切到
  cleanupLegacyPlayHistoryStorage:不再做数据迁移(历史是低关键性
  衍生数据,老用户重新听几次即可),仅清掉旧 musicHistory/podcastHistory/
  playlistHistory/albumHistory/podcastRadioHistory/playHistory-migrated/
  playMode 这 7 个旧 key,避免和新 play-history-store key 双倍占用
- SystemTab.vue 清缓存的 case 'history' 改走 usePlayHistoryStore().
  clearMusicHistory(),与 v1 时代行为对齐(只清音乐历史,不动 podcast/
  playlist/album/podcastRadio);移除 case 'settings' 里的
  removeItem('playMode')——已并入 player-core-store
2026-05-17 23:08:52 +08:00
chengww 761884f23a refactor(playHistory): 持久化重写,统一防抖落盘与序列化兜底
把 playHistory 接入 utils/debouncedStorage 与 utils/persistedSong,
配合 add* 方法重构与 clearAll 同步落盘,闭合 localStorage 配额防护。

- musicHistory 类型从 SongResult 收敛到 MusicHistoryItem(精简子集),
  导出 MinifiedDjProgram、stripBase64Covers,给 podcast/playlist/album/
  podcastRadio 历史也做顶层 picUrl/coverImgUrl/coverUrl 的 base64 兜底
- serializePlayHistoryState 提取为模块级函数,给 persistedstate.serializer
  与 clearAll 同步落盘共用,避免格式漂移;isPodcast/program 字段必须
  保留——playbackController.playTrack 用 isPodcast 决定写哪条历史
- 5 个 add* 全部重写成单步 ref 重赋值,避免 splice/pop/unshift 多次
  触发 watch 与持久化;命中已有条目时累加 count + 刷新 lastPlayTime,
  picUrl/al 用新数据覆盖(封面可能换了短引用)
- clearAll 增加 flushDebouncedStorage + 同步 setItem 空状态,防止
  kill -9 落在 2s 防抖窗口里导致旧历史残留
- heatmap/index.vue 类型切到 MusicHistoryItem,移除 music.artists
  兜底(minifySong 已合并 ar/artists,只剩 ar)
2026-05-17 23:08:22 +08:00
chengww 537e280fdd refactor(persist): 抽公共防抖 storage 与 minifySong 工具,playlist/playerCore 接入
把 9caaec3 在 playlist 内联的 minifySong + debouncedLocalStorage 抽到
utils 共用,playerCore 同步接入,为后续推广到 playHistory 做准备。

- 新增 utils/debouncedStorage.ts:高频状态变更(volume 拖动、isPlay
  切换)2s 防抖落盘,beforeunload 钩子兜底刷盘;多 store 共用同一
  pendingWrites map,flush 时一次写完所有 pending key
- 新增 utils/persistedSong.ts:minifySong 剥离 base64 picUrl、仅保留
  local:// 永不过期的 playMusicUrl;ar.length 守卫避免空数组吞掉
  s.artists 兜底;al.id 守卫避免序列化出无 id 空壳
- playlist.ts 删除内联实现改用 import,行为不变
- playerCore.ts 切到防抖落盘并 minify playMusic;id 守卫避免空
  playMusic 走 minify 后失去 Object.keys().length===0 判空能力,
  下次启动会误恢复一首无 id 的空歌

Trade-off:极端非正常退出(kill -9 / 断电)下最近 2s 的 volume /
isPlay / playMusic 变更会丢——这些状态丢一次无大碍,可接受
2026-05-17 23:07:58 +08:00
chengww 15258f28fd fix(local-music): 封面落盘 + URL 编码统一,修复持久化配额与编码边界
- 新增 src/shared/localUrl.ts 共用 local:// 编码:按路径段 encodeURIComponent,
  避免整体编码把 / 转成 %2F 引发 Chromium 解析边界差异,同时正确处理
  空格/中文/# 等特殊字符(封面落到含空格目录时 Image loader 会加载失败)
- 封面从内嵌 base64 Data URL 改为 userData/AudioCovers/<sha256>.<ext> 落盘,
  MAX_COVER_BYTES 1MB→8MB;老条目(无 coverPath 字段)扫描时一次性自愈
- playlist minify 剥离 base64 picUrl 并仅持久化 local:// 永不过期的 playMusicUrl,
  防止单张 base64 封面撑爆 localStorage 5MB 配额导致整个 playList 写入失败;
  localStorage 写入加 try/catch 兜底,避免配额超限时直接抛异常
2026-05-17 23:07:17 +08:00
chengww fa818a020f fix(player): 双击歌曲时同步设置播放列表上下文
BaseSongItem 双击和右键菜单"播放"只调了 setPlay,未 emit 'play',
导致父组件 setPlayList 不会执行,上下一首切换失效。抽出统一入口
先 emit 再触发播放,与点击播放按钮行为对齐。
2026-05-17 23:07:01 +08:00
chengww c15a10c098 fix(local-music): 主进程实现 Range/206 让本地音乐 seek/快进恢复
切到 protocol.handle 后,audio 元素发的 Range 请求会带 HTTP 头到达
主进程;net.fetch(file://) 既不识别 Range 也不带 Accept-Ranges,导致
浏览器认为 local:// 不支持随机访问,seek 时只能从头加载,表现为
快进失效、退出后恢复播放从 0 开始。

新增 buildLocalFileResponse:
- 无 Range:200 + Accept-Ranges: bytes,让 audio 知道支持随机访问
- 有 Range:206 + Content-Range,用 fs.createReadStream 切片返回
- 非法 Range:416 + Content-Range: bytes */total

顺手把 fs.existsSync 换成 stat,一次拿文件大小且过滤掉目录。
2026-05-17 23:07:01 +08:00
chengww 51f1aaba55 chore: 忽略 *.tsbuildinfo 编译缓存 2026-05-17 23:07:01 +08:00
chengww 0c0189bcef fix(local-music): 注册 local 协议为特权 scheme 修复本地音乐 CORS 报错
- main/index.ts 在 app.whenReady 之前调用 registerSchemesAsPrivileged,
  把 local 标记为 standard/secure/supportFetchAPI/stream/corsEnabled/bypassCSP,
  让 http 页面(dev server / 生产)可跨协议加载本地音频
- fileManager.ts 用 Electron 25 起推荐的 protocol.handle 替代已弃用的
  registerFileProtocol,内部转发到 file:// 自动支持 Range / 流式播放
- 修复 macOS/Linux 上去掉前导斜杠后丢失绝对路径前缀的问题
2026-05-17 23:07:01 +08:00
alger ee98eb0266 fix(player): 私人 FM 模式下点击下一首按钮可正常切歌
FM 播放列表只保留 1 首,原 _nextPlay 走到"顺序模式 + 最后一首"
分支只弹"列表已播完"提示,仅 audioService end 事件中拉取下一首
FM 的逻辑生效,导致用户手动点击下一首无效(issue #666)。

抽出 _nextFmPlay,_nextPlay 入口检测 isFmPlaying 直接路由到 FM
分支;MusicHook end 事件去掉重复的 FM 处理,统一走 nextPlayOnEnd。
2026-05-10 13:00:55 +08:00
alger d722728ee0 chore(scripts): 移动 fix-sandbox.js 到 scripts 目录
将根目录的运维脚本统一收纳到 scripts/,并把脚本内的相对路径
改为基于 __dirname,避免在仓库子目录执行时找不到 node_modules。
2026-05-10 12:34:53 +08:00
alger 5ba9e6591a refactor(lyric): 抽取全屏背景/文字颜色逻辑为 useLyricBackground composable
MusicFull.vue 与 MusicFullMobile.vue 各自持有的 setTextColors /
currentBackground / animationFrame / isDark 合并到共享 composable,
消除两份几乎一致的包装逻辑。Mobile 的 --bg-color 差异通过 writeBgColor
option 注入,行为等价。
2026-05-10 12:34:53 +08:00
Alger 7e95ab69be Merge pull request #654 from chengww5217/fix/unmute-restore-volume
fix(player): 静音保留原音量,解除后可恢复
2026-05-10 12:23:34 +08:00
Alger 7c6448733d Merge pull request #653 from chengww5217/fix/download-config
fix(download): 下载设置抽屉打开时路径显示为空
2026-05-10 12:23:31 +08:00
chengww 2b1024ca24 fix(player): 静音保留原音量,解除后可恢复
- playerCore 新增持久化 isMuted 状态及 setMuted/toggleMute,静音时音频输出置 0 但 volume 保持不变
- 音量 > 0 时自动解除静音
- useVolumeControl 移除原 0↔30 切换;滑块/百分比展示真实音量,图标反映静音态
- 三个播放栏的音量滑块在静音时 disabled;PlayBar 百分比文字同步置灰(仅文字颜色)
2026-04-26 21:47:11 +08:00
chengww a62f525840 fix(download): 下载设置抽屉打开时路径显示为空
get-store-value 主进程用 ipcMain.on 同步返回,renderer 却用 invoke 读取会直接
reject,导致 initDownloadSettings 中断、已保存的下载路径等配置回读失败。改为
sendSync,与项目其它调用点保持一致。

contentLength 类型错误非本次提交引入,因无法通过 precommit 检查,故一并修复。
2026-04-26 21:05:59 +08:00
alger 97220761cf fix(lyric): 重启后桌面歌词显示无歌词
playerCore.playMusic 整体替换 (id 不变) 时, lyric watcher 的响应式追踪不可靠
点击播放走 playTrack 流程也未必能可靠触发解析

- 提取 ensureLyricsLoaded 到 module 级别, 直接读 playMusic.value 解析
- openLyric 入口主动调用 (重启首次打开桌面歌词场景)
- onLyricWindowReady 兜底 (窗口异步就绪时 lyric 字段可能刚到位)
- audioService.on('play') 兜底 (重启后首次点击播放场景)
- 在线歌曲 lyric 字段缺失时, 主动调 getMusicLrc API 兜底
2026-04-19 16:15:09 +08:00
alger 7282e876f4 fix(lyric-window): 锁定状态启动时同步穿透并禁用 resize
- 重启应用恢复锁定时, 主进程主动 setIgnoreMouseEvents(true), 修复鼠标无法穿透
- 锁定时 setResizable(false), 隐藏窗口边缘 resize 光标
- 由 set-lyric-lock-state IPC 统一驱动, 后续 polling 按位置精细纠正
2026-04-19 15:44:28 +08:00
alger 6b22713854 perf(lyric-window): 仅在锁定+可见时启用鼠标位置轮询
- 新增 set-lyric-lock-state IPC, 渲染端 watch isLock 同步到主进程
- 主进程通过 isLyricLocked + isLyricWindowVisible 控制轮询启停
- 监听窗口 show/hide/minimize/restore, 隐藏时停止 50ms 轮询
- 解锁状态下 DOM mouseenter/mouseleave 已足够, 无需轮询兜底
2026-04-19 15:31:23 +08:00
alger 0d960aa8d5 Merge pull request #645 from geewon1i/Lyric-lock-icon
fix(歌词悬窗): 通过主进程周期检测鼠标位置纠正悬停状态,修复鼠标快速移出时锁图标残留问题

Closes #606
2026-04-19 15:29:06 +08:00