Skip to content

Commit 6efb989

Browse files
authored
Merge pull request #974 from Pissofdvpe/dev-latest
🐞fix(mac/statusbar): 修复 macOS 状态栏歌词显示失效及配置架构对齐问题
2 parents 16637e7 + 3ecc8e7 commit 6efb989

5 files changed

Lines changed: 58 additions & 12 deletions

File tree

electron/main/ipc/ipc-mac-statusbar.ts

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import type { LyricLine } from "@applemusic-like-lyrics/lyric";
2-
import { TASKBAR_IPC_CHANNELS, type SyncStatePayload, type SyncTickPayload } from "@shared";
2+
import {
3+
DEFAULT_TASKBAR_CONFIG,
4+
TASKBAR_IPC_CHANNELS,
5+
type SyncStatePayload,
6+
type SyncTickPayload,
7+
type TaskbarConfig,
8+
} from "@shared";
39
import { ipcMain } from "electron";
410
import { useStore } from "../store";
511
import { getMainTray } from "../tray";
@@ -88,9 +94,9 @@ const updateMacStatusBarLyric = (forceUpdate: boolean = false) => {
8894
return;
8995
}
9096

91-
// 如果歌词数据为空,则清空标题并返回
97+
// 如果歌词数据为空,则显示当前歌曲标题,避免空白
9298
if (macLyricLines.length === 0) {
93-
tray.setTitle("");
99+
tray.setTitle(getCurrentSongTitle());
94100
return;
95101
}
96102

@@ -107,7 +113,7 @@ const updateMacStatusBarLyric = (forceUpdate: boolean = false) => {
107113
.map((w) => w.word ?? "")
108114
.join("")
109115
.trim()
110-
: "";
116+
: getCurrentSongTitle(); // 处于前奏或未匹配到歌词时,显示歌曲名
111117

112118
tray.setTitle(currentLyric);
113119
};
@@ -151,27 +157,45 @@ export const initMacStatusBarIpc = () => {
151157
}
152158
});
153159

160+
// 注册任务栏配置通用处理器,确保 macOS 也能获取和设置配置
161+
ipcMain.handle(TASKBAR_IPC_CHANNELS.GET_OPTION, () => store.get("taskbar"));
162+
163+
ipcMain.on(TASKBAR_IPC_CHANNELS.SET_OPTION, (_event, option: Partial<TaskbarConfig>) => {
164+
if (!option) return;
165+
166+
// 安全过滤:仅允许写入 DEFAULT_TASKBAR_CONFIG 中定义的合法键
167+
const allowedKeys = Object.keys(DEFAULT_TASKBAR_CONFIG);
168+
169+
Object.entries(option).forEach(([key, value]) => {
170+
if (allowedKeys.includes(key)) {
171+
store.set(`taskbar.${key}`, value);
172+
}
173+
});
174+
// macOS 模式下不处理窗口可见性,仅同步配置
175+
});
176+
154177
ipcMain.on(TASKBAR_IPC_CHANNELS.SYNC_STATE, (_event, payload: SyncStatePayload) => {
155178
switch (payload.type) {
156179
case "lyrics-loaded": {
157-
// 仅更新歌词数据,不立即更新状态栏显示
180+
// 更新歌词数据并立即刷新显示
158181
macLyricLines = payload.data.lines;
159182
macLastLyricIndex = -1;
183+
updateMacStatusBarLyric(true);
160184
break;
161185
}
162186

163187
case "playback-state":
164188
macIsPlaying = payload.data.isPlaying;
165-
// 不在这里直接更新歌词,依赖 SYNC_TICK 来驱动
189+
// 播放状态变更时,如果是播放中,等待 SYNC_TICK 或插值器驱动
190+
// 如果是暂停状态,则停止插值器并进行一次最终更新
166191
if (!macIsPlaying) {
167-
// 如果是暂停状态,则停止插值器并进行一次最终更新
168192
stopInterpolation();
169-
updateMacStatusBarLyric();
193+
updateMacStatusBarLyric(true);
170194
}
171195
break;
172196

173197
case "full-hydration":
174-
// 接收完整的状态,但歌词更新仍然依赖 SYNC_TICK
198+
// 接收完整的状态,立即同步并刷新显示
175199
if (payload.data.lyrics) {
176200
macLyricLines = payload.data.lyrics.lines;
177201
macLastLyricIndex = -1;
@@ -184,6 +208,11 @@ export const initMacStatusBarIpc = () => {
184208
macOffset = offset;
185209
}
186210
}
211+
// 同步后立即刷新一次
212+
updateMacStatusBarLyric(true);
213+
if (macIsPlaying) {
214+
startInterpolation();
215+
}
187216
break;
188217
}
189218
});

electron/main/ipc/ipc-taskbar.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { TASKBAR_IPC_CHANNELS, type SyncStatePayload, type TaskbarConfig } from "@shared";
1+
import {
2+
DEFAULT_TASKBAR_CONFIG,
3+
TASKBAR_IPC_CHANNELS,
4+
type SyncStatePayload,
5+
type TaskbarConfig,
6+
} from "@shared";
27
import { app, ipcMain, nativeTheme } from "electron";
38
import type EventEmitter from "node:events";
49
import { useStore } from "../store";
@@ -45,12 +50,21 @@ const initTaskbarIpc = () => {
4550
TASKBAR_IPC_CHANNELS.SET_OPTION,
4651
(_event, option: Partial<TaskbarConfig>, pushToWindow = true) => {
4752
if (!option) return;
53+
54+
// 安全过滤:仅允许写入 DEFAULT_TASKBAR_CONFIG 中定义的合法键
55+
const allowedKeys = Object.keys(DEFAULT_TASKBAR_CONFIG);
56+
4857
// 增量更新
4958
const prev = getTaskbarConfig();
50-
const next = { ...prev, ...option };
59+
const next = { ...prev };
60+
5161
Object.entries(option).forEach(([key, value]) => {
52-
store.set(`taskbar.${key}`, value);
62+
if (allowedKeys.includes(key)) {
63+
store.set(`taskbar.${key}`, value);
64+
(next as any)[key] = value;
65+
}
5366
});
67+
5468
// 推送到歌词窗口
5569
if (pushToWindow) {
5670
taskbarLyricManager.send(TASKBAR_IPC_CHANNELS.SYNC_STATE, {

src/core/player/PlayerController.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { toRaw } from "vue";
12
import { AudioErrorCode } from "@/core/audio-player/BaseAudioPlayer";
23
import { useDataStore, useMusicStore, useSettingStore, useStatusStore } from "@/stores";
34
import type { AudioSourceType, QualityType, SongType } from "@/types/main";

src/core/player/PlayerIpc.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { toRaw } from "vue";
12
import { useMusicStore, useSettingStore } from "@/stores";
23
import type { SongLyric } from "@/types/lyric";
34
import { useLyricManager } from "./LyricManager";

src/stores/data.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { toRaw } from "vue";
12
import { defineStore } from "pinia";
23
import type {
34
SongType,

0 commit comments

Comments
 (0)