效果如下:

其实实现自定义托盘菜单的本质上,就是开一个新窗口,下面直接给出核心代码。
javascript
// 加载窗口
const loadWindow = (example, path) => {
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
example.loadURL(process.env['ELECTRON_RENDERER_URL'] + (path ? `/#/${path}` : ''))
} else {
let obj = {}
if (path) {
obj.hash = path
}
example.loadFile(join(__dirname, '../renderer/index.html'), obj)
}
}
const tww = 145
const thh = 408
trayWindow = new BrowserWindow({
width: tww,
height: thh,
show: false,// 窗口创建后立即显示
autoHideMenuBar: true,// 隐藏菜单栏
frame: false,// 边框
modal: true, // 模态窗口
disableAutoHideCursor: true,// 禁止隐藏光标
skipTaskbar: true,// 隐藏任务栏
alwaysOnTop: true,// 窗口置顶
resizable: false,// 禁止调整窗口大小
webPreferences: {
preload: join(__dirname, '../preload/index.js'),// 预加载脚本
sandbox: false // 是否启用沙箱模式
}
})
loadWindow(trayWindow, 'tray-menus')
const tray = new Tray(icon)
tray.setToolTip(`QQ: 1366666666\n声音: 开启\n消息提醒框: 开启\n会话消息: 任务栏头像闪动`)
tray.on('click', () => {
mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show()
})
tray.on('right-click', (e, point) => {
if (trayWindow.isVisible()) {
return
}
// 显示弹窗
trayWindow.show();
// 获取托盘图标的位置
const { x, y } = tray.getBounds();
trayWindow.setPosition(x + 20, y - thh + 20); // 设置弹窗的位置
// 设置定时器检查鼠标位置
let timer = null;
clearInterval(timer);
timer = setInterval(() => {
const screenPoint = screen.getCursorScreenPoint();
const trayBounds = tray.getBounds();
const windowBounds = trayWindow.getBounds();
// 判断鼠标是否在托盘图标或弹窗范围内
const isMouseOverTray = screenPoint.x >= trayBounds.x && screenPoint.x <= trayBounds.x + trayBounds.width &&
screenPoint.y >= trayBounds.y && screenPoint.y <= trayBounds.y + trayBounds.height;
const isMouseOverWindow = screenPoint.x >= windowBounds.x && screenPoint.x <= windowBounds.x + windowBounds.width &&
screenPoint.y >= windowBounds.y && screenPoint.y <= windowBounds.y + windowBounds.height;
// 如果鼠标不在托盘图标或弹窗范围内,隐藏弹窗
if (!isMouseOverTray && !isMouseOverWindow) {
clearInterval(timer);
trayWindow.hide();
}
}, 100);
});