From b38cfa669e41cc76452c70cea5dffdee7311541e Mon Sep 17 00:00:00 2001 From: kazukokawagawa <2580099704@qq.com> Date: Fri, 6 Mar 2026 16:14:43 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=9A=90?= =?UTF-8?q?=E8=97=8F=E6=AD=8C=E8=AF=8D=E8=AE=BE=E7=BD=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在设置中新增“隐藏歌词”选项,允许用户仅显示歌曲名称和歌手。 - 更新任务栏配置接口以支持该功能,并设置默认值为 false。 - 修改任务栏歌词组件以根据用户设置决定是否显示歌词内容。 --- src/components/Setting/config/lyric.ts | 13 +++++++++++++ src/types/shared/taskbar-ipc.ts | 3 +++ src/views/TaskbarLyric/index.vue | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/components/Setting/config/lyric.ts b/src/components/Setting/config/lyric.ts index 09a6e6770..961f96149 100644 --- a/src/components/Setting/config/lyric.ts +++ b/src/components/Setting/config/lyric.ts @@ -972,6 +972,19 @@ export const useLyricSettings = (): SettingConfig => { }, }), }, + { + key: "taskbarLyricHideLyrics", + label: "隐藏歌词", + type: "switch", + description: "开启后仅显示歌名和歌手,不显示歌词内容", + value: computed({ + get: () => taskbarLyricConfig.hideLyrics, + set: (v) => { + taskbarLyricConfig.hideLyrics = v ?? false; + saveTaskbarLyricConfig({ hideLyrics: taskbarLyricConfig.hideLyrics }); + }, + }), + }, { key: "taskbarLyricUseThemeColor", label: "跟随封面颜色", diff --git a/src/types/shared/taskbar-ipc.ts b/src/types/shared/taskbar-ipc.ts index c3dcea188..c9ac571ee 100644 --- a/src/types/shared/taskbar-ipc.ts +++ b/src/types/shared/taskbar-ipc.ts @@ -53,6 +53,8 @@ export interface TaskbarConfig { mainScale: number; /** 副歌词缩放比例 */ subScale: number; + /** 隐藏歌词,仅显示歌曲信息 */ + hideLyrics: boolean; } export interface TrackData { @@ -144,6 +146,7 @@ export const DEFAULT_TASKBAR_CONFIG: TaskbarConfig = { lineHeight: 1.1, mainScale: 1.0, subScale: 0.8, + hideLyrics: false, }; export const TASKBAR_IPC_CHANNELS = { diff --git a/src/views/TaskbarLyric/index.vue b/src/views/TaskbarLyric/index.vue index c692939f2..a3e0ba9fc 100644 --- a/src/views/TaskbarLyric/index.vue +++ b/src/views/TaskbarLyric/index.vue @@ -355,7 +355,7 @@ const updateBgCache = () => { watch(mainLyricIndex, updateBgCache); const displayItems = computed(() => { - if (!currentLyricText.value) { + if (taskbarConfig.hideLyrics || !currentLyricText.value) { return createMetadataItems(state.title, state.artist); } From 9dd06df16a224aa542d065d7ce46c2249e5469b8 Mon Sep 17 00:00:00 2001 From: kazukokawagawa <2580099704@qq.com> Date: Fri, 6 Mar 2026 16:21:01 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat(=E4=BB=BB=E5=8A=A1=E6=A0=8F=E6=AD=8C?= =?UTF-8?q?=E8=AF=8D):=20=E6=B7=BB=E5=8A=A0=E5=BC=BA=E5=88=B6=E9=87=8D?= =?UTF-8?q?=E8=BD=BD=E6=AD=8C=E8=AF=8D=E7=AA=97=E5=8F=A3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增任务栏歌词强制重载按钮,用于修复显示异常问题。当任务栏歌词出现显示问题时,用户可通过设置中的"强制重载"按钮关闭并重新创建歌词窗口。 --- electron/main/ipc/ipc-taskbar.ts | 11 +++++++++++ src/components/Setting/config/lyric.ts | 15 +++++++++++++++ src/types/shared/taskbar-ipc.ts | 4 ++++ 3 files changed, 30 insertions(+) diff --git a/electron/main/ipc/ipc-taskbar.ts b/electron/main/ipc/ipc-taskbar.ts index 9a37d8348..5be5b00bb 100644 --- a/electron/main/ipc/ipc-taskbar.ts +++ b/electron/main/ipc/ipc-taskbar.ts @@ -104,6 +104,17 @@ const initTaskbarIpc = () => { taskbarLyricManager.handleFadeDone(); }); + // 强制重载歌词窗口 + ipcMain.on(TASKBAR_IPC_CHANNELS.FORCE_RELOAD, () => { + const currentConfig = getTaskbarConfig(); + if (!currentConfig.enabled) return; + taskbarLyricManager.close(false); + setTimeout(() => { + taskbarLyricManager.create(currentConfig.mode); + updateWindowVisibility(currentConfig); + }, 500); + }); + // 把事件发射到 app 里不太好,但是我觉得也没有必要为了这一个事件创建一个事件总线 // TODO: 如果有了事件总线,通过那个事件总线发射这个事件 (app as EventEmitter).on("explorer-restarted", () => { diff --git a/src/components/Setting/config/lyric.ts b/src/components/Setting/config/lyric.ts index 961f96149..cfb6878ab 100644 --- a/src/components/Setting/config/lyric.ts +++ b/src/components/Setting/config/lyric.ts @@ -1251,6 +1251,21 @@ export const useLyricSettings = (): SettingConfig => { }), defaultValue: 0.8, }, + { + key: "taskbarLyricForceReload", + label: "强制重载", + type: "button", + description: "关闭并重新创建任务栏歌词窗口,用于修复显示异常", + buttonLabel: "重载", + action: () => { + if (!statusStore.showTaskbarLyric) { + window.$message.warning("请先开启任务栏歌词"); + return; + } + window.electron.ipcRenderer.send(TASKBAR_IPC_CHANNELS.FORCE_RELOAD); + window.$message.success("任务栏歌词已重载"); + }, + }, { key: "taskbarLyricRestore", label: "恢复默认配置", diff --git a/src/types/shared/taskbar-ipc.ts b/src/types/shared/taskbar-ipc.ts index c9ac571ee..6eb875050 100644 --- a/src/types/shared/taskbar-ipc.ts +++ b/src/types/shared/taskbar-ipc.ts @@ -174,4 +174,8 @@ export const TASKBAR_IPC_CHANNELS = { * 渲染进程 -> 主进程 (初始化握手) */ REQUEST_DATA: "taskbar:request-data", + /** + * 渲染进程 -> 主进程 (强制重载歌词窗口) + */ + FORCE_RELOAD: "taskbar:force-reload", } as const; From 6f52eef634dc89fdafc186070929a10b931e4415 Mon Sep 17 00:00:00 2001 From: kazukokawagawa <2580099704@qq.com> Date: Fri, 6 Mar 2026 16:59:56 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat(=E4=BB=BB=E5=8A=A1=E6=A0=8F=E6=AD=8C?= =?UTF-8?q?=E8=AF=8D):=20=E4=B8=BA=E6=82=AC=E6=B5=AE=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=94=81=E5=AE=9A=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增悬浮锁定模式开关,开启时鼠标穿透窗口,关闭时可拖动窗口 - 在任务栏歌词设置中添加锁定模式配置项 - 通过 IPC 通信实现前端与主进程的鼠标穿透状态同步 --- electron/main/ipc/ipc-taskbar.ts | 4 ++++ electron/main/utils/taskbar-lyric-manager.ts | 4 ++++ .../windows/floating-taskbar-lyric-window.ts | 21 +++++++++++++++++++ electron/main/windows/taskbar-lyric-window.ts | 9 ++++++++ src/components/Setting/config/lyric.ts | 14 +++++++++++++ src/types/shared/taskbar-ipc.ts | 3 +++ src/views/TaskbarLyric/index.vue | 19 +++++++++++++++++ 7 files changed, 74 insertions(+) diff --git a/electron/main/ipc/ipc-taskbar.ts b/electron/main/ipc/ipc-taskbar.ts index 5be5b00bb..dd2c34304 100644 --- a/electron/main/ipc/ipc-taskbar.ts +++ b/electron/main/ipc/ipc-taskbar.ts @@ -38,6 +38,10 @@ const initTaskbarIpc = () => { taskbarLyricManager.setContentWidth(width); }); + ipcMain.on("taskbar:set-ignore-mouse-events", (_event, ignore: boolean) => { + taskbarLyricManager.setMousePassthrough(Boolean(ignore)); + }); + ipcMain.handle(TASKBAR_IPC_CHANNELS.GET_OPTION, () => getTaskbarConfig()); // 设置配置(增量合并) diff --git a/electron/main/utils/taskbar-lyric-manager.ts b/electron/main/utils/taskbar-lyric-manager.ts index 9db4fb48f..ef1126f65 100644 --- a/electron/main/utils/taskbar-lyric-manager.ts +++ b/electron/main/utils/taskbar-lyric-manager.ts @@ -50,6 +50,10 @@ class TaskbarLyricManager { this.getActive().handleFadeDone(); } + setMousePassthrough(ignore: boolean) { + this.getActive().setMousePassthrough(ignore); + } + send(channel: string, ...args: unknown[]) { this.getActive().send(channel, ...args); } diff --git a/electron/main/windows/floating-taskbar-lyric-window.ts b/electron/main/windows/floating-taskbar-lyric-window.ts index c5942e9b9..5314eab50 100644 --- a/electron/main/windows/floating-taskbar-lyric-window.ts +++ b/electron/main/windows/floating-taskbar-lyric-window.ts @@ -18,6 +18,7 @@ class FloatingTaskbarLyricWindow { private isFadingOut = false; private lastFloatingAlign: "left" | "right" | null = null; private lastAlwaysOnTop: boolean | null = null; + private lastFloatingLock: boolean | null = null; private debouncedSaveBounds = debounce((bounds: Electron.Rectangle) => { const store = useStore(); @@ -73,6 +74,7 @@ class FloatingTaskbarLyricWindow { if (!this.win) return null; this.applyAlwaysOnTop(true); + this.applyFloatingLock(true); this.win.loadURL(floatingTaskbarLyricUrl); const sendTheme = () => { @@ -164,6 +166,15 @@ class FloatingTaskbarLyricWindow { } } + private applyFloatingLock(force: boolean) { + if (!this.win || this.win.isDestroyed()) return; + const store = useStore(); + const floatingLock = store.get("taskbar.floatingLock", true); + if (!force && this.lastFloatingLock === floatingLock) return; + this.lastFloatingLock = floatingLock; + this.setMousePassthrough(floatingLock); + } + updateLayout(_animate: boolean = false) { if (!this.win || this.win.isDestroyed()) return; @@ -210,6 +221,7 @@ class FloatingTaskbarLyricWindow { this.win.setBounds({ x: nextX, y: nextY, width: nextWidth, height: nextHeight }); this.applyAlwaysOnTop(false); + this.applyFloatingLock(false); this.sendFloatingAlign(false); } @@ -249,6 +261,15 @@ class FloatingTaskbarLyricWindow { } } + setMousePassthrough(ignore: boolean) { + if (!this.win || this.win.isDestroyed()) return; + if (ignore) { + this.win.setIgnoreMouseEvents(true, { forward: true }); + } else { + this.win.setIgnoreMouseEvents(false); + } + } + close() { if (this.win && !this.win.isDestroyed()) { this.win.close(); diff --git a/electron/main/windows/taskbar-lyric-window.ts b/electron/main/windows/taskbar-lyric-window.ts index 085e38594..31fd301ca 100644 --- a/electron/main/windows/taskbar-lyric-window.ts +++ b/electron/main/windows/taskbar-lyric-window.ts @@ -468,6 +468,15 @@ class TaskbarLyricWindow { } } + public setMousePassthrough(ignore: boolean) { + if (!this.win || this.win.isDestroyed()) return; + if (ignore) { + this.win.setIgnoreMouseEvents(true, { forward: true }); + } else { + this.win.setIgnoreMouseEvents(false); + } + } + public destroy() { if (this.isNativeDisposed) return; this.debouncedUpdateLayout.cancel(); diff --git a/src/components/Setting/config/lyric.ts b/src/components/Setting/config/lyric.ts index cfb6878ab..8f422c04c 100644 --- a/src/components/Setting/config/lyric.ts +++ b/src/components/Setting/config/lyric.ts @@ -905,6 +905,20 @@ export const useLyricSettings = (): SettingConfig => { }, }), }, + { + key: "taskbarLyricFloatingLock", + label: "锁定模式", + type: "switch", + description: "开启后鼠标将穿透窗口,关闭后可拖动窗口", + show: () => taskbarLyricConfig.mode === "floating", + value: computed({ + get: () => taskbarLyricConfig.floatingLock, + set: (v) => { + taskbarLyricConfig.floatingLock = v ?? true; + saveTaskbarLyricConfig({ floatingLock: taskbarLyricConfig.floatingLock }); + }, + }), + }, { key: "taskbarLyricFloatingAutoWidth", label: "悬浮自动宽度", diff --git a/src/types/shared/taskbar-ipc.ts b/src/types/shared/taskbar-ipc.ts index 6eb875050..648507247 100644 --- a/src/types/shared/taskbar-ipc.ts +++ b/src/types/shared/taskbar-ipc.ts @@ -25,6 +25,8 @@ export interface TaskbarConfig { floatingHeight: number; /** 悬浮置顶 */ floatingAlwaysOnTop: boolean; + /** 悬浮锁定模式 */ + floatingLock: boolean; /** 是否启用 */ enabled: boolean; /** 暂停时显示 */ @@ -132,6 +134,7 @@ export const DEFAULT_TASKBAR_CONFIG: TaskbarConfig = { floatingWidth: 300, floatingHeight: 48, floatingAlwaysOnTop: false, + floatingLock: false, enabled: false, showWhenPaused: true, showCover: true, diff --git a/src/views/TaskbarLyric/index.vue b/src/views/TaskbarLyric/index.vue index a3e0ba9fc..7231b27c4 100644 --- a/src/views/TaskbarLyric/index.vue +++ b/src/views/TaskbarLyric/index.vue @@ -92,6 +92,7 @@ const taskbarConfig = reactive({ ...DEFAULT_TASKBAR_CONFIG }); const isFloating = computed(() => route.query.mode === "floating"); const isHovering = ref(false); const showControls = computed(() => !isFloating.value && isHovering.value); +let lastMousePassthrough: boolean | null = null; /** * 只有当 IPC 时间与本地时间误差超过 250ms 时,才同步 IPC 的时间 @@ -190,6 +191,14 @@ const handleMouseLeave = () => { isHovering.value = false; }; +const setMousePassthrough = (ignore: boolean) => { + const ipc = window.electron?.ipcRenderer; + if (!ipc) return; + if (lastMousePassthrough === ignore) return; + lastMousePassthrough = ignore; + ipc.send("taskbar:set-ignore-mouse-events", ignore); +}; + const controlAction = (action: "playPrev" | "playOrPause" | "playNext") => { const ipc = window.electron?.ipcRenderer; if (!ipc) return; @@ -565,6 +574,15 @@ onMounted(() => { const ipc = window.electron?.ipcRenderer; if (!ipc) return; + if (isFloating.value) { + setMousePassthrough(taskbarConfig.floatingLock); + watch( + () => taskbarConfig.floatingLock, + (v) => setMousePassthrough(v), + { immediate: true }, + ); + } + ipc.on(TASKBAR_IPC_CHANNELS.SYNC_STATE, (_, payload: SyncStatePayload) => { switch (payload.type) { case "full-hydration": { @@ -698,6 +716,7 @@ $radius: 4px; margin: 5px 0; padding: 0 0.9em; box-sizing: border-box; + position: relative; display: flex; align-items: center; justify-content: flex-start; From edf78ff03685eb44e27e0288cb48794428075c4d Mon Sep 17 00:00:00 2001 From: imsyy Date: Wed, 11 Mar 2026 18:14:11 +0800 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- electron/main/ipc/ipc-taskbar.ts | 3 +-- electron/main/windows/floating-taskbar-lyric-window.ts | 2 +- src/components/Setting/config/lyric.ts | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/electron/main/ipc/ipc-taskbar.ts b/electron/main/ipc/ipc-taskbar.ts index dd2c34304..e9c67c82f 100644 --- a/electron/main/ipc/ipc-taskbar.ts +++ b/electron/main/ipc/ipc-taskbar.ts @@ -39,7 +39,7 @@ const initTaskbarIpc = () => { }); ipcMain.on("taskbar:set-ignore-mouse-events", (_event, ignore: boolean) => { - taskbarLyricManager.setMousePassthrough(Boolean(ignore)); + taskbarLyricManager.setMousePassthrough(ignore); }); ipcMain.handle(TASKBAR_IPC_CHANNELS.GET_OPTION, () => getTaskbarConfig()); @@ -114,7 +114,6 @@ const initTaskbarIpc = () => { if (!currentConfig.enabled) return; taskbarLyricManager.close(false); setTimeout(() => { - taskbarLyricManager.create(currentConfig.mode); updateWindowVisibility(currentConfig); }, 500); }); diff --git a/electron/main/windows/floating-taskbar-lyric-window.ts b/electron/main/windows/floating-taskbar-lyric-window.ts index 5314eab50..d479bc0ca 100644 --- a/electron/main/windows/floating-taskbar-lyric-window.ts +++ b/electron/main/windows/floating-taskbar-lyric-window.ts @@ -169,7 +169,7 @@ class FloatingTaskbarLyricWindow { private applyFloatingLock(force: boolean) { if (!this.win || this.win.isDestroyed()) return; const store = useStore(); - const floatingLock = store.get("taskbar.floatingLock", true); + const floatingLock = store.get("taskbar.floatingLock", false); if (!force && this.lastFloatingLock === floatingLock) return; this.lastFloatingLock = floatingLock; this.setMousePassthrough(floatingLock); diff --git a/src/components/Setting/config/lyric.ts b/src/components/Setting/config/lyric.ts index 8f422c04c..3732863d4 100644 --- a/src/components/Setting/config/lyric.ts +++ b/src/components/Setting/config/lyric.ts @@ -914,7 +914,7 @@ export const useLyricSettings = (): SettingConfig => { value: computed({ get: () => taskbarLyricConfig.floatingLock, set: (v) => { - taskbarLyricConfig.floatingLock = v ?? true; + taskbarLyricConfig.floatingLock = v ?? false; saveTaskbarLyricConfig({ floatingLock: taskbarLyricConfig.floatingLock }); }, }),