Electron 实现自定义系统托盘菜单

效果如下:

其实实现自定义托盘菜单的本质上,就是开一个新窗口,下面直接给出核心代码。

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);
  });
相关推荐
阿蒙Amon4 小时前
TypeScript学习-第7章:泛型(Generic)
javascript·学习·typescript
睡美人的小仙女1274 小时前
Threejs加载环境贴图报错Bad File Format: bad initial token
开发语言·javascript·redis
fanruitian4 小时前
uniapp android开发 测试板本与发行版本
前端·javascript·uni-app
rayufo4 小时前
【工具】列出指定文件夹下所有的目录和文件
开发语言·前端·python
RANCE_atttackkk4 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
摘星编程5 小时前
React Native + OpenHarmony:Timeline垂直时间轴
javascript·react native·react.js
2501_944525546 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 支出分析页面
android·开发语言·前端·javascript·flutter
jin1233226 小时前
React Native鸿蒙跨平台完成剧本杀组队详情页面,可以复用桌游、团建、赛事等各类组队详情页开发
javascript·react native·react.js·ecmascript·harmonyos
李白你好6 小时前
Burp Suite插件用于自动检测Web应用程序中的未授权访问漏洞
前端
经年未远7 小时前
vue3中实现耳机和扬声器切换方案
javascript·学习·vue