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);
  });
相关推荐
天宇&嘘月2 小时前
web第三次作业
前端·javascript·css
小王不会写code3 小时前
axios
前端·javascript·axios
发呆的薇薇°4 小时前
vue3 配置@根路径
前端·vue.js
luckyext4 小时前
HBuilderX中,VUE生成随机数字,vue调用随机数函数
前端·javascript·vue.js·微信小程序·小程序
小小码农(找工作版)4 小时前
JavaScript 前端面试 4(作用域链、this)
前端·javascript·面试
前端没钱4 小时前
前端需要学习 Docker 吗?
前端·学习·docker
前端郭德纲5 小时前
前端自动化部署的极简方案
运维·前端·自动化
海绵宝宝_5 小时前
【HarmonyOS NEXT】获取正式应用签名证书的签名信息
android·前端·华为·harmonyos·鸿蒙·鸿蒙应用开发
码农土豆5 小时前
chrome V3插件开发,调用 chrome.action.setIcon,提示路径找不到
前端·chrome
鱼樱前端5 小时前
深入JavaScript引擎与模块加载机制:从V8原理到模块化实战
前端·javascript