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);
  });
相关推荐
细节控菜鸡16 小时前
【2025最新】ArcGIS for JS 实现随着时间变化而变化的热力图
开发语言·javascript·arcgis
2501_9160088916 小时前
Web 前端开发常用工具推荐与团队实践分享
android·前端·ios·小程序·uni-app·iphone·webview
SkylerHu16 小时前
前端代码规范:husky+ lint-staged+pre-commit
前端·代码规范
菜鸟una17 小时前
【微信小程序 + 消息订阅 + 授权】 微信小程序实现消息订阅流程介绍,代码示例(仅前端)
前端·vue.js·微信小程序·小程序·typescript·taro·1024程序员节
Yeats_Liao17 小时前
Go Web 编程快速入门 05 - 表单处理:urlencoded 与 multipart
前端·golang·iphone
飞翔的佩奇17 小时前
【完整源码+数据集+部署教程】【运动的&足球】足球场地区域图像分割系统源码&数据集全套:改进yolo11-RFAConv
前端·python·yolo·计算机视觉·数据集·yolo11·足球场地区域图像分割系统
拉不动的猪17 小时前
h5后台切换检测利用visibilitychange的缺点分析
前端·javascript·面试
桃子不吃李子17 小时前
nextTick的使用
前端·javascript·vue.js
萌新小码农‍17 小时前
SpringBoot+alibaba的easyexcel实现前端使用excel表格批量插入
前端·spring boot·excel
冰暮流星18 小时前
css3新增背景图片样式
前端·css·css3