feat: Add support for player controls in macOS dock menu (#1627)

* Added simple macOS dock menu similar to tray menu

* Enhanced and moved dock menu to darwin folder and enabled mpris on macOS to support play/pause state

* Added missing property sortName to silence TS error
This commit is contained in:
Steffen Martinsen
2026-01-31 03:01:02 +07:00
committed by GitHub
parent 7613bc32c2
commit b8228844df
3 changed files with 61 additions and 2 deletions
+57
View File
@@ -0,0 +1,57 @@
import { app, ipcMain, Menu } from 'electron';
import { getMainWindow } from '/@/main/index';
import { PlayerStatus } from '/@/shared/types/types';
let currentStatus: PlayerStatus = PlayerStatus.PAUSED;
const updateDockMenu = () => {
if (!app.dock) return;
const isPlaying = currentStatus === PlayerStatus.PLAYING;
const dockMenu = Menu.buildFromTemplate([
{
click: () => {
getMainWindow()?.webContents.send('renderer-player-play-pause');
},
label: isPlaying ? 'Pause' : 'Play',
},
{
type: 'separator',
},
{
click: () => {
getMainWindow()?.webContents.send('renderer-player-next');
},
label: 'Next',
},
{
click: () => {
getMainWindow()?.webContents.send('renderer-player-previous');
},
label: 'Previous',
},
{
type: 'separator',
},
{
click: () => {
getMainWindow()?.webContents.send('renderer-player-stop');
},
label: 'Stop',
},
]);
app.dock.setMenu(dockMenu);
};
ipcMain.on('update-playback', (_event, status: PlayerStatus) => {
currentStatus = status;
updateDockMenu();
});
// Initialize dock menu after app is ready
app.whenReady().then(() => {
updateDockMenu();
});
+1
View File
@@ -0,0 +1 @@
import './dock-menu';
@@ -13,7 +13,7 @@ import { PlayerShuffle, ServerType } from '/@/shared/types/types';
const ipc = isElectron() ? window.api.ipc : null;
const utils = isElectron() ? window.api.utils : null;
const mpris = isElectron() && utils?.isLinux() ? window.api.mpris : null;
const mpris = isElectron() && (utils?.isLinux() || utils?.isMacOS()) ? window.api.mpris : null;
export const useMPRIS = () => {
const player = usePlayerStore();
@@ -102,6 +102,7 @@ export const useMPRIS = () => {
releaseYear: null,
sampleRate: null,
size: 0,
sortName: title,
tags: null,
trackNumber: 0,
trackSubtitle: null,
@@ -221,7 +222,7 @@ const MPRISHookInner = () => {
export const MPRISHook = () => {
const isElectronEnv = isElectron();
const utils = isElectronEnv ? window.api.utils : null;
const mpris = isElectronEnv && utils?.isLinux() ? window.api.mpris : null;
const mpris = isElectronEnv && (utils?.isLinux() || utils?.isMacOS()) ? window.api.mpris : null;
if (mpris === null) {
return null;