把 Mineradio 移植到 macOS:全屏修复与 DMG 打包记录

把 Mineradio 移植到 macOS:全屏修复与 DMG 打包记录
周言志Mineradio 是一款基于 Electron 的沉浸式音乐播放器,视觉和交互体验都做得很棒,但官方只提供了 Windows 版。前段时间抽空把它适配到了 macOS,并打包成了 .dmg 安装包。这篇文章记录一下踩过的坑和最终方案。
背景
Mineradio 用 Electron 构建——也就是说底层是 Chromium + Node.js——按理说天生跨平台。项目里也确实有一段 macOS 的判断逻辑:
1 | // 第 1288 行 |
这行代码的意思是”非 Windows 就退出”,给 macOS 留了个明确的入口开关。抱着试试看的心态关掉这个判断,跑了一下 npm start,窗口真的弹出来了。但全屏按钮点了没反应。
于是开始了适配之旅。
全屏修复:最折腾的一环
根因
Electron 窗口如果同时设置了 transparent: true 和 frame: false(透明 + 无边框),在 macOS 上调用 setFullScreen(true) 会静默失败。这是 Electron 在 macOS 上的一个已知限制,因为原生全屏动画依赖窗口管理器的某些特性,透明无边框窗口不满足条件。
Mineradio 恰好就是这种窗口:
1 | mainWindow = new BrowserWindow({ |
解决方案
macOS 提供了一个替代方法叫 setSimpleFullScreen()。它不依赖原生全屏动画,透明无边框窗口也能正常使用。唯一的区别是它不会触发系统级的全屏转场动画(就是 macOS 那个带 Mission Control 飞入效果的切换),但实际效果完全一致——窗口占满整个屏幕。
改动一共涉及四处地方:
1. 进入全屏时判断平台
1 | if (process.platform === 'darwin') { |
2. 退出全屏时同样走 macOS 分支
1 | if (process.platform === 'darwin' && win.isSimpleFullScreen()) { |
3. Escape 键退出的判断条件
原来的 isFullScreen() 在 simple fullscreen 模式下返回 false,所以要多加一个 isSimpleFullScreen() 的判断。
4. HTML 全屏退出时避免与简单全屏冲突
当视频等 HTML 元素退出全屏时,如果窗口本身也处于 simple fullscreen 状态,不要重置窗口尺寸。
改完之后全屏功能完全正常,包括窗口大小恢复和 Escape 键退出都跟原生体验一致。
打包成 .dmg
生成 macOS 图标
项目里只有 Windows 的 .ico 和一张 build/icon.png。macOS 需要 .icns 格式,可以用系统自带的 sips 和 iconutil 从 PNG 生成:
1 | # 创建 iconset 目录 |
electron-builder 配置
在 package.json 的 build 字段里添加 macOS 和 DMG 配置:
1 | "mac": { |
绕过 dmg-builder 的坑
在国内网络环境下,electron-builder 的 dmg-builder 工具经常下载失败(404 错误)。折腾了几次之后发现不如分两步走:
- 先用
electron-builder --mac dir生成.app目录包 - 再用系统自带的
hdiutil手动制作 DMG
手动生成 DMG 的命令很简单:
1 | hdiutil create -volname "Mineradio 1.0.10" \ |
最终产物约 141MB,拖到 Applications 文件夹就能用。
首次启动
因为没有 Apple 开发者签名,macOS 会弹”无法验证开发者”的提示。解决办法跟其他未签名应用一样——右键点”打开”即可,只需要确认一次,后续正常双击运行。
macOS 上哪些功能不可用
以下是几个依赖 Windows 专属 API 的功能,在 macOS 上无法工作:
| 功能 | 原因 | 影响 |
|---|---|---|
| 桌面壁纸模式 | 使用了 Windows WorkerW API 将播放器嵌入桌面壁纸层 |
无法将播放器设为壁纸 |
| 桌面歌词鼠标穿透 | 使用 Windows GetAsyncKeyState 轮询中键 |
桌面歌词的锁定切换不可用 |
| 自动创建桌面快捷方式 | 使用 Windows .lnk 文件 API |
无影响,拖到 Applications 即可 |
其他核心功能全部正常:
- 音乐播放、搜索、歌单管理
- 网易云音乐登录与播放
- QQ 音乐音源补充
- 歌词显示与桌面歌词(仅穿透不可用)
- 粒子视觉、Emily 播放态
- 3D 歌单架
- 天气电台
- 更新检测
总结
这次适配比预想的简单,大部分时间花在全屏问题的排查上。Electron 应用在 macOS 上跑起来的门槛其实很低,真正的坑往往藏在那些听起来人畜无害的 API 组合里——比如 transparent + frame: false 不能全屏这种事情,文档里不会特别提醒你。
最终适配的代码和构建配置我都放在了 Mineradio-macOS 这个 repo 里,有需要可以直接拿去用。






