AdminJS启航计划Electron 默认拖盘(Tray)

lxf2023-03-17 17:23:01

我正参与「AdminJS·启航计划」

Electron 默认拖盘(Tray)带来了菜单栏水平,但是也不能让用户自定对话框主视图,有非常大的局限。我们通常见到 Mac 上有很多原生应用,点一下拖盘后可以弹出来往下拉对话框,那 Electron 能否完成这个啊?是完全可以的,现在就带着大家一起实现一个「桌面上计算方式」。

AdminJS启航计划Electron 默认拖盘(Tray)

最先,我们应该写一个无框的 BrowserWindow 来载入计算方式页面

let win, tray
function createTrayWindow() {
  const width = 300
  const height = 420
  win = new BrowserWindow({
    width,
    height,
    frame: false,
    resizable: false,
    show: false,
    movable: false,
    minimizable: false,
    maximizable: false,
  })
  win.loadFile(path.join(__dirname, '../renderer/calculator.html'))
}

留意这儿 BrowserWindow 默认为不表明(show: false),只有在用户点击拖盘标志时,才展现这一对话框。

这儿的难题是:托盘的部位并不是固定,想让对话框恰好展示在拖盘标志的下方,那样每一次点一下托盘的情况下,要实时分析一下托盘的部位。还好 Tray 有一个 API 能够掌握到标志位置:

tray.getBounds() // 回到 { x, y, width, height }

方法会回到一个方形(Rectangle)目标,包括下列信息内容:

  • x:托盘的 x 座标
  • y:托盘的 y 座标
  • width:托盘的总宽
  • height:托盘的相对高度

下面,大家建立一个托盘,并为其关联 click 事情:

const tray = new Tray(path.join(__dirname, 'calculatorTemplate.png'))
tray.on('click', () => {
  const trayBounds = tray.getBounds()
  win.setPosition(trayBounds.x   trayBounds.width / 2 - width / 2, trayBounds.height)
  if (win.isVisible()) {
    win.hide()
  } else {
    win.show()
  }
})

建立 Tray 案例时,需要提供一个 image 主要参数,能是本地图片的相对路径,还可以是 NativeImage 的案例。有关 NativeImage 类接下来会详尽讲,这节先直接用图片文件来建立拖盘。在 macOS 下,设定托盘的图片名称需要以 Template 末尾,一般需要提供 16x16(72dpi) 和 32x32@2x(144dpi) 的两个图片,比如:

  • trayiconTemplate.png
  • trayiconTemplate@2x.png

必须特别注意的是:模版图象需要由黑色和透明通道构成。应用模版图象做为工具栏标志的好处在于,它可以适应浅色系和深棕色工具栏。在 Windows 系统中则不需要依照这类命名规范了,最好在 Windows 中使用 ico 格式照片,视觉效果效果更好一点。

上边最重要的编码取决于这一行,用以操纵拖盘发生位置:

win.setPosition(trayBounds.x   trayBounds.width / 2 - width / 2 , trayBounds.height)

因为 BrowserWindow 的宽高比早已固定下来了,假如想让对话框恰好坐落于拖盘标志中间下方,就需要算过偏移,窗口坐标计算逻辑性为:

  • x 座标:拖盘中心点的 x 座标减掉对话框的宽度
  • y 座标:拖盘底部 y 座标(即拖盘相对高度)

那样基本效果就来了:

AdminJS启航计划Electron 默认拖盘(Tray)

但是这时窗口表明和掩藏全部由托盘的js点击事件操纵,当客户转换到其他软件时,主要表现实际效果和一般的 BrowserWindow 一样,等级在目前对焦的应用下边:

AdminJS启航计划Electron 默认拖盘(Tray)

但拖盘对话框更加好的互动是:当对话框失去焦点时,隐藏。这很简单,只需为对话框提升 blur 事情就可以:

win.on('blur', () => {
  win.hide()
})

那样程序流程就顺滑得多:

AdminJS启航计划Electron 默认拖盘(Tray)

但是还有一个不易发现的不完美的区域:Mac 是支持多桌面的,用户可以通过四指左右滑动的形式上下切换桌面:

AdminJS启航计划Electron 默认拖盘(Tray)

你就会发现上边的计算方式对话框在切换桌面以后消失了,计算方式对话框只出现在初次展现的桌面,在别的桌面上点一下拖盘标志,会自动切回第一个桌面上,这样的体验是很不好的:

AdminJS启航计划Electron 默认拖盘(Tray)

但是,要修补这种情况也很简单啦,只需一行代码就可以:

win.setVisibleOnAllWorkspaces(true)

对,便是表面意思:在大多数办公空间上面展现。最终在装包时还有一点应注意:一般的纯拖盘运用,是没有 dock 标志的,装包的时候在 info.plist 里边加上 LSUIElement 配置项可解决这些问题:

<plist version="1.0">
  <dict>
    <key>LSUIElement</key>
    <integer>1</integer>
  </dict>
</plist>

具体加上方式取决于运用打包方式,以 electron-packager 为例子,配置项为:

"mac": {
  "extendInfo": {
    "LSBackgroundOnly": 1,
    "LSUIElement": 1
  }
}

交给阅读者讨论题

上边的代码比较适合在 macOS 设备运行,请把它迁移到 Windows 系统中。

留意:在 Mac 和 Windows 上,托盘的部位是不一样的,Windows 默认设置是左下方,可是 Windows 系统软件里的任务栏图标位置是可以让用户自定的:

AdminJS启航计划Electron 默认拖盘(Tray)

部位能选前后左右四个:

AdminJS启航计划Electron 默认拖盘(Tray)

你需要考虑这四种场景中拖盘窗口显示位置才可以,聪明如你是不是有想法了啦?何不评论留言沟通交流!