2025-11-03 23:25:22 +08:00
|
|
|
import { BrowserWindow, ipcMain, screen } from "electron";
|
2025-10-25 23:43:54 +08:00
|
|
|
import { useStore } from "../store";
|
2025-10-29 23:59:13 +08:00
|
|
|
import lyricWindow from "../windows/lyric-window";
|
2025-10-25 23:43:54 +08:00
|
|
|
import mainWindow from "../windows/main-window";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 歌词相关 IPC
|
|
|
|
|
*/
|
|
|
|
|
const initLyricIpc = (): void => {
|
|
|
|
|
const store = useStore();
|
|
|
|
|
const mainWin = mainWindow.getWin();
|
2025-11-03 23:25:22 +08:00
|
|
|
|
|
|
|
|
// 歌词窗口
|
|
|
|
|
let lyricWin: BrowserWindow | null = null;
|
2025-10-25 23:43:54 +08:00
|
|
|
|
2025-11-05 18:21:17 +08:00
|
|
|
/**
|
|
|
|
|
* 窗口是否存活
|
|
|
|
|
* @param win 窗口实例
|
|
|
|
|
* @returns 是否存活
|
|
|
|
|
*/
|
|
|
|
|
const isWinAlive = (win: BrowserWindow | null): win is BrowserWindow =>
|
|
|
|
|
!!win && !win.isDestroyed();
|
|
|
|
|
|
2025-10-25 23:43:54 +08:00
|
|
|
// 切换桌面歌词
|
2025-11-03 23:25:22 +08:00
|
|
|
ipcMain.on("toggle-desktop-lyric", (_event, val: boolean) => {
|
2025-10-25 23:43:54 +08:00
|
|
|
if (val) {
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!isWinAlive(lyricWin)) {
|
2025-11-04 12:01:27 +08:00
|
|
|
lyricWin = lyricWindow.create();
|
2025-11-05 18:21:17 +08:00
|
|
|
// 监听关闭,置空引用,防止后续调用报错
|
|
|
|
|
lyricWin?.on("closed", () => {
|
|
|
|
|
lyricWin = null;
|
|
|
|
|
});
|
|
|
|
|
// 设置位置
|
|
|
|
|
const { x, y } = store.get("lyric");
|
|
|
|
|
const xPos = Number(x);
|
|
|
|
|
const yPos = Number(y);
|
|
|
|
|
if (Number.isFinite(xPos) && Number.isFinite(yPos)) {
|
|
|
|
|
lyricWin?.setPosition(Math.round(xPos), Math.round(yPos));
|
|
|
|
|
}
|
2025-11-04 12:01:27 +08:00
|
|
|
} else {
|
2025-11-05 18:21:17 +08:00
|
|
|
lyricWin.show();
|
|
|
|
|
}
|
|
|
|
|
if (isWinAlive(lyricWin)) {
|
|
|
|
|
lyricWin.setAlwaysOnTop(true, "screen-saver");
|
2025-11-04 12:01:27 +08:00
|
|
|
}
|
2025-11-03 23:25:22 +08:00
|
|
|
} else {
|
2025-11-04 12:01:27 +08:00
|
|
|
// 关闭:不销毁窗口,直接隐藏,保留位置与状态
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!isWinAlive(lyricWin)) return;
|
2025-11-04 12:01:27 +08:00
|
|
|
lyricWin.hide();
|
2025-11-03 23:25:22 +08:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-11-05 18:21:17 +08:00
|
|
|
// 向主窗口发送事件
|
|
|
|
|
ipcMain.on("send-to-main", (_, eventName, ...args) => {
|
|
|
|
|
mainWin?.webContents.send(eventName, ...args);
|
|
|
|
|
});
|
|
|
|
|
|
2025-11-03 23:25:22 +08:00
|
|
|
// 更新歌词窗口数据
|
|
|
|
|
ipcMain.on("update-desktop-lyric-data", (_, lyricData) => {
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!lyricData || !isWinAlive(lyricWin)) return;
|
|
|
|
|
lyricWin.webContents.send("update-desktop-lyric-data", lyricData);
|
2025-11-03 23:25:22 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 更新歌词窗口配置
|
2025-11-06 01:07:04 +08:00
|
|
|
ipcMain.on("update-desktop-lyric-option", (_, option, callback: boolean = false) => {
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!option || !isWinAlive(lyricWin)) return;
|
2025-11-06 15:04:40 +08:00
|
|
|
// 增量更新
|
|
|
|
|
const prevOption = store.get("lyric.config");
|
|
|
|
|
if (prevOption) {
|
|
|
|
|
option = { ...prevOption, ...option };
|
|
|
|
|
}
|
2025-11-06 01:07:04 +08:00
|
|
|
store.set("lyric.config", option);
|
|
|
|
|
// 触发窗口更新
|
|
|
|
|
if (callback && isWinAlive(lyricWin)) {
|
|
|
|
|
lyricWin.webContents.send("update-desktop-lyric-option", option);
|
|
|
|
|
}
|
|
|
|
|
mainWin?.webContents.send("update-desktop-lyric-option", option);
|
2025-11-03 23:25:22 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 播放状态更改
|
|
|
|
|
ipcMain.on("play-status-change", (_, status) => {
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!isWinAlive(lyricWin)) return;
|
|
|
|
|
lyricWin.webContents.send("update-desktop-lyric-data", { playStatus: status });
|
2025-10-25 23:43:54 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 音乐名称更改
|
|
|
|
|
ipcMain.on("play-song-change", (_, title) => {
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!title || !isWinAlive(lyricWin)) return;
|
|
|
|
|
lyricWin.webContents.send("update-desktop-lyric-data", { playName: title });
|
2025-10-25 23:43:54 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 音乐歌词更改
|
|
|
|
|
ipcMain.on("play-lyric-change", (_, lyricData) => {
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!lyricData || !isWinAlive(lyricWin)) return;
|
|
|
|
|
lyricWin.webContents.send("update-desktop-lyric-data", lyricData);
|
2025-10-25 23:43:54 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 获取窗口位置
|
|
|
|
|
ipcMain.handle("get-window-bounds", () => {
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!isWinAlive(lyricWin)) return {};
|
|
|
|
|
return lyricWin.getBounds();
|
2025-10-25 23:43:54 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 获取屏幕尺寸
|
|
|
|
|
ipcMain.handle("get-screen-size", () => {
|
|
|
|
|
const { width, height } = screen.getPrimaryDisplay().workAreaSize;
|
|
|
|
|
return { width, height };
|
|
|
|
|
});
|
|
|
|
|
|
2025-11-05 18:21:17 +08:00
|
|
|
// 获取多屏虚拟边界(支持负坐标)
|
|
|
|
|
ipcMain.handle("get-virtual-screen-bounds", () => {
|
|
|
|
|
const displays = screen.getAllDisplays();
|
|
|
|
|
const bounds = displays.map((d) => d.workArea);
|
|
|
|
|
const minX = Math.min(...bounds.map((b) => b.x));
|
|
|
|
|
const minY = Math.min(...bounds.map((b) => b.y));
|
|
|
|
|
const maxX = Math.max(...bounds.map((b) => b.x + b.width));
|
|
|
|
|
const maxY = Math.max(...bounds.map((b) => b.y + b.height));
|
|
|
|
|
return { minX, minY, maxX, maxY };
|
|
|
|
|
});
|
|
|
|
|
|
2025-10-25 23:43:54 +08:00
|
|
|
// 移动窗口
|
|
|
|
|
ipcMain.on("move-window", (_, x, y, width, height) => {
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!isWinAlive(lyricWin)) return;
|
2025-11-03 23:25:22 +08:00
|
|
|
lyricWin.setBounds({ x, y, width, height });
|
2025-10-25 23:43:54 +08:00
|
|
|
// 保存配置
|
|
|
|
|
store.set("lyric", { ...store.get("lyric"), x, y, width, height });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 更新高度
|
|
|
|
|
ipcMain.on("update-window-height", (_, height) => {
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!isWinAlive(lyricWin)) return;
|
2025-11-06 15:04:40 +08:00
|
|
|
const store = useStore();
|
2025-10-25 23:43:54 +08:00
|
|
|
const { width } = lyricWin.getBounds();
|
|
|
|
|
// 更新窗口高度
|
|
|
|
|
lyricWin.setBounds({ width, height });
|
2025-11-06 15:04:40 +08:00
|
|
|
store.set("lyric", { ...store.get("lyric"), height });
|
2025-10-25 23:43:54 +08:00
|
|
|
});
|
|
|
|
|
|
2025-11-05 18:21:17 +08:00
|
|
|
// 请求歌词数据及配置
|
|
|
|
|
ipcMain.on("request-desktop-lyric-data", () => {
|
|
|
|
|
if (!isWinAlive(lyricWin)) return;
|
|
|
|
|
// 触发窗口更新
|
|
|
|
|
mainWin?.webContents.send("request-desktop-lyric-data");
|
|
|
|
|
});
|
|
|
|
|
|
2025-10-25 23:43:54 +08:00
|
|
|
// 获取配置
|
2025-11-06 01:07:04 +08:00
|
|
|
ipcMain.handle("request-desktop-lyric-option", () => {
|
|
|
|
|
const config = store.get("lyric.config");
|
|
|
|
|
if (isWinAlive(lyricWin)) {
|
|
|
|
|
lyricWin.webContents.send("update-desktop-lyric-option", config);
|
2025-10-25 23:43:54 +08:00
|
|
|
}
|
2025-11-06 01:07:04 +08:00
|
|
|
return config;
|
2025-10-25 23:43:54 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 发送主程序事件
|
|
|
|
|
ipcMain.on("send-main-event", (_, name, val) => {
|
|
|
|
|
mainWin?.webContents.send(name, val);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 关闭桌面歌词
|
|
|
|
|
ipcMain.on("closeDesktopLyric", () => {
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!isWinAlive(lyricWin)) return;
|
2025-11-03 23:25:22 +08:00
|
|
|
lyricWin.hide();
|
2025-10-25 23:43:54 +08:00
|
|
|
mainWin?.webContents.send("closeDesktopLyric");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 锁定/解锁桌面歌词
|
|
|
|
|
ipcMain.on("toogleDesktopLyricLock", (_, isLock: boolean) => {
|
2025-11-05 18:21:17 +08:00
|
|
|
if (!isWinAlive(lyricWin)) return;
|
2025-10-25 23:43:54 +08:00
|
|
|
// 是否穿透
|
|
|
|
|
if (isLock) {
|
|
|
|
|
lyricWin.setIgnoreMouseEvents(true, { forward: true });
|
|
|
|
|
} else {
|
|
|
|
|
lyricWin.setIgnoreMouseEvents(false);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default initLyricIpc;
|