基于electron开发MacOS Menubar app主要涉及的技术其实就是Electron的 Tray API。
此外也有人将这个API做了简单的封装:menubar(github) 。
其基本原理就是将Electron的窗口挪到menubar对应app按钮的下面,也就是点击menu bar按钮时,在获取按钮的位置,然后在按钮的下方显示窗口。
比如在这里有一个将传统Electron改造为MacOS Menubar application的例子:
// 检测是否MacOS darwin
if (platform === 'darwin' || tray) {
const iconPath = join(__dirname, 'static/IconTrayMac.png');
const trayIcon = new Tray(iconPath);
trayIcon.setToolTip(`${app.getName()}`);
// 点击时显示窗口,并修改窗口的显示位置
trayIcon.on('click', () => {
const {screen} = electron;
const {width, height} = screen.getPrimaryDisplay().workAreaSize;
const [defaultWidth, defaultHeight] = [width, height].map(x => Math.round((x * 3) / 4));
const WINDOW_WIDTH = defaultWidth - 350;
const WINDOW_HEIGHT = defaultHeight;
const HORIZ_PADDING = 15;
const VERT_PADDING = 15;
const cursorPosition = screen.getCursorScreenPoint();
const primarySize = screen.getPrimaryDisplay().workAreaSize;
const trayPositionVert = cursorPosition.y >= primarySize.height / 2 ? 'bottom' : 'top';
const trayPositionHoriz = cursorPosition.x >= primarySize.width / 2 ? 'right' : 'left';
win.setPosition(getTrayPosX(), getTrayPosY());
if (win.isVisible()) {
win.hide();
} else {
win.show();
}
// 计算位置
function getTrayPosX() {
const horizBounds = {
left: cursorPosition.x - (WINDOW_WIDTH / 2),
right: cursorPosition.x + (WINDOW_WIDTH / 2)
};
if (trayPositionHoriz === 'left') {
return horizBounds.left <= HORIZ_PADDING ? HORIZ_PADDING : horizBounds.left;
}
return horizBounds.right >= primarySize.width ? primarySize.width - HORIZ_PADDING - WINDOW_WIDTH : horizBounds.right - WINDOW_WIDTH;
}
function getTrayPosY() {
return trayPositionVert === 'bottom' ? cursorPosition.y - WINDOW_HEIGHT - VERT_PADDING : cursorPosition.y + VERT_PADDING;
}
});
return;
}
这个时候就有了效果:
接下来还有一个问题,就是怎么实现 点击其他地方时,该窗口自动隐藏 。
这里要用到的是Electron的 Blur 事件(文档):
aoWindow.on('blur', () => {
if (platform === 'darwin') {
aoWindow.hide();
}
});
在MacOS系统中,检测到Blur事件,也就是未聚焦于窗口时,调用 hide
把窗口隐藏掉。
这样,就实现了一个MacOS的Menubar application!
接下来就用 electron-packager
将该App打包成MacOS的dmg包就行了!
Tips:
使用electron-packager
打包过程有个坑,就是使用cnpm安装依赖的话,会导致打包时间极为漫长,用npm重新安装就好了。Tips:
用于MacOS中Tray的icon,有个经验是将icon大小设置为14X14。
最后给出一个我Fork后修改的Github开源Microsoft To-Do desktop app应用的地址:https://github.com/Anderson-L...
原repo地址:https://github.com/klauscfhq/ao
界面很有设计感,经过改造为Menubar app后效率更是大幅提升!