Files
xk-admin/apps/desktop/src/main/tray.ts

79 lines
2.7 KiB
TypeScript
Raw Normal View History

import { app, Menu, nativeImage, Tray } from 'electron';
import log from 'electron-log/main';
import { getAutoLaunchEnabled, setAutoLaunchEnabled } from './auto-launch';
import { getResourcePath } from './config';
import { checkForUpdates } from './updater';
import { markQuitting, showMainWindow } from './window';
/**
* 系统托盘:应用常驻入口
* - Windows 单击托盘图标恢复主窗口;mac 单击弹出菜单(跟随平台惯例)
* - 菜单:显示主窗口 / 开机自启开关 / 检查更新 / 退出
* 注意:托盘实例必须保持模块级引用,否则会被 GC 导致图标消失(Electron 经典坑)
*/
let tray: Tray | null = null;
/** 构建托盘菜单:开机自启是动态勾选项,每次状态变化后需重建菜单 */
function buildTrayMenu(): Menu {
return Menu.buildFromTemplate([
{
label: '显示主窗口',
click: () => showMainWindow(),
},
{ type: 'separator' },
{
label: '开机自启',
type: 'checkbox',
checked: getAutoLaunchEnabled(),
// 开发模式登录项无意义,置灰避免误操作
enabled: app.isPackaged,
click: (menuItem) => {
setAutoLaunchEnabled(menuItem.checked);
refreshTrayMenu();
},
},
{
label: '检查更新',
click: () => checkForUpdates(true),
},
{ type: 'separator' },
{
label: '退出',
click: () => {
// 先标记退出,放行主窗口 close 拦截,再走正常退出流程
markQuitting();
app.quit();
},
},
]);
}
/** 刷新托盘菜单(开机自启状态从渲染端 IPC 修改后也要同步勾选态) */
export function refreshTrayMenu(): void {
tray?.setContextMenu(buildTrayMenu());
}
/**
* 创建系统托盘
* 图标用打包的应用图标缩放(mac 菜单栏建议 18px、Windows 托盘 16px 的倍数由系统处理)
* TODO(待确认):正式图标到位后,mac 建议换单色 Template 图以适配深浅菜单栏
*/
export function createTray(): void {
try {
const icon = nativeImage.createFromPath(getResourcePath('icon.png'));
const trayIcon = process.platform === 'darwin' ? icon.resize({ width: 18, height: 18 }) : icon.resize({ width: 16, height: 16 });
tray = new Tray(trayIcon);
tray.setToolTip('萧康云医');
tray.setContextMenu(buildTrayMenu());
// Windows 单击直接唤起主窗口;mac 上设置了 contextMenu 后单击默认弹菜单,不重复绑定
if (process.platform === 'win32') {
tray.on('click', () => showMainWindow());
}
} catch (error) {
// 托盘创建失败(图标缺失等)不阻塞应用启动,仅损失常驻入口
log.error('创建系统托盘失败', error);
}
}