You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript+Electron环境下获取桌面通知的尺寸(分辨率)

解决方案

Electron 的桌面通知基于系统原生通知组件渲染(Windows 为 Toast 通知、macOS 为 User Notification、Linux 为 libnotify),不属于 Electron 内置 BrowserWindow 的 DOM 树,所以调用 innerHeight、innerWidth 等 DOM 相关属性无法获取到通知的实际渲染尺寸。

核心实现思路

Electron 官方 Notification 模块没有直接暴露原生通知的尺寸接口,可通过「通知截图+像素计算」的方案实现分辨率校验,步骤如下:

  • 触发对应规格的通知展示,设置 300-500ms 延迟等待系统完成通知渲染,避免捕获到半加载的内容
  • 调用 Electron 的 desktopCapturer 模块捕获当前整屏的视频流,提取单帧图像
  • 通过系统通知的特征匹配定位通知区域:Windows 匹配通知右上角关闭按钮/通知背景色特征,macOS 匹配右上角通知中心弹出区域的固定水平坐标范围,Linux 匹配桌面右上角/右下角的通知弹出固定区域
  • 对匹配到的通知区域做像素边界计算,得到实际宽高数值,和预设的三种规格预期值做差值校验,差值在 2px 以内可判定为符合预期

可直接复用的核心代码片段

const { Notification, desktopCapturer, screen } = require('electron')
const Jimp = require('jimp') // 纯JS图像像素处理工具,无需外部系统依赖

// 通知尺寸校验函数,入参为对应规格的预期宽、预期高
async function verifyNotificationSize(expectedWidth, expectedHeight) {
  // 1. 弹出目标规格的测试通知,配置和生产环境完全一致
  const testNotification = new Notification({
    title: '尺寸校验测试通知',
    body: '用于校验实际分辨率的测试通知',
    // 此处补充对应规格的其他配置:图标、自定义内容、样式参数等
  })
  testNotification.show()

  // 2. 等待通知渲染完成
  await new Promise(resolve => setTimeout(resolve, 400))

  // 3. 捕获当前屏幕内容
  const primaryDisplay = screen.getPrimaryDisplay()
  const [screenSource] = await desktopCapturer.getSources({ 
    types: ['screen'], 
    thumbnailSize: primaryDisplay.workAreaSize 
  })
  const screenImg = await Jimp.read(screenSource.thumbnail.toPNG())
  const dpiScale = primaryDisplay.scaleFactor

  // 4. 定位通知区域计算实际尺寸(此处以macOS为例,Windows/Linux可调整匹配逻辑)
  const screenWidth = screenImg.getWidth()
  const screenHeight = screenImg.getHeight()
  let notifyLeft = screenWidth, notifyRight = 0, notifyTop = screenHeight, notifyBottom = 0
  // 扫描右上角30%宽*40%高的区域,匹配通知半透明白色背景,可根据系统主题调整RGBA阈值
  for (let x = Math.floor(screenWidth * 0.7); x < screenWidth; x++) {
    for (let y = 0; y < Math.floor(screenHeight * 0.4); y++) {
      const { r, g, b, a } = Jimp.intToRGBA(screenImg.getPixelColor(x, y))
      if (r > 240 && g > 240 && b > 240 && a > 200) {
        notifyLeft = Math.min(notifyLeft, x)
        notifyRight = Math.max(notifyRight, x)
        notifyTop = Math.min(notifyTop, y)
        notifyBottom = Math.max(notifyBottom, y)
      }
    }
  }

  // 换算实际物理像素,去除DPI缩放影响
  const actualWidth = Math.round((notifyRight - notifyLeft) / dpiScale)
  const actualHeight = Math.round((notifyBottom - notifyTop) / dpiScale)

  // 关闭测试通知
  testNotification.close()

  // 允许2px的系统渲染误差
  return Math.abs(actualWidth - expectedWidth) <= 2 && Math.abs(actualHeight - expectedHeight) <= 2
}

特殊场景优化

如果你的桌面端使用了自定义 HTML 通知(用 BrowserWindow 模拟原生通知样式),无需走截图匹配逻辑,直接获取通知窗口实例调用 getBounds() 方法即可拿到精确的宽高数值。

批量校验小、中、大三种规格时,两次校验之间需要留至少1s的间隔,避免上一个通知的消失动画影响下一个通知的捕获结果。

内容的提问来源于stack exchange,提问作者Les pères Lumière

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 07:27:04