electron globalShortcut 快捷键,在焦点移到其他软件上时,调用快捷键报错

electron 开发软件,在设置了 globalShortcut 快捷键后,在当前开发的软件上调用快捷键正常,但是当焦点不在当前软件时,在使用快捷键,好些时候会报错。大概率与系统快捷键产生冲突或者快键键控制的回调里获取的内容,需在软件聚焦时才可获取到。

开始我设置快键键的方式:

javascript 复制代码
function createWindow () {
  // 隐藏窗体顶部菜单
  Menu.setApplicationMenu(null)

  /**
   * Initial window options
   */
  mainWindow = new BrowserWindow({
    width: 1338, // 宽
    height: 839, // 高
    minWidth: 1024,
    minHeight: 600,
    useContentSize: true,
    show: false, // 创建后是否显示
    frame: false, // 添加后自定义标题//自定义边框
    center: true, // 是否出现在屏幕居中的位置
    fullscreenable: platform === 'darwin',
    resizable: false, // 可否缩放
    movable: true, // 可否移动
    maximizable: false,
    minimizable: false,
    title: '当前项目名称', // 默认窗口标题
    transparent: false, // 是否是透明窗口(仅macOS)
    // vibrancy: 'ultra-dark', // 窗口模糊的样式(仅macOS)
    backgroundColor: 'none', // 背景色,用于transparent和frameless窗口
    hasShadow: true, // Boolean (可选) - 窗口是否有阴影. 仅在 macOS 上支持. 默认值为 true
    titleBarStyle: 'hidden',
    webPreferences: {
      nodeIntegration: true,
      webSecurity: false, // electron窗体跨域方案
      backgroundThrottling: false // 当页面被置于非激活窗口的时候是否停止动画和计时器
    }
  })

  mainWindow.setMenu(null) // 隐藏菜单栏
  if (platform === 'darwin') {
    Menu.setApplicationMenu(Menu.buildFromTemplate([]))
  }

  mainWindow.loadURL(winURL)

  mainWindow.on('ready-to-show', function () {
    mainWindow.show() // 初始化后再显示
  })

  mainWindow.on('closed', () => {
    mainWindow = null
  })
}

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('ready', createWindow)

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow()
  }
})

app.whenReady().then(() => {
  // 设置快捷键
  globalShortcut.register('CommandOrControl+Alt+T', () => {
    const currentWindow = BrowserWindow.getFocusedWindow()
    currentWindow.webContents.openDevTools()
  })
})

app.on('will-quit', () => {
  // 注销所有快捷键
  globalShortcut.unregisterAll()
})

但是这样在失去焦点时,windows和mac下都会报错:

原因是:const currentWindow = BrowserWindow.getFocusedWindow() 方法需在当前软件聚焦时才可正常调用。

const currentWindow = BrowserWindow.getFocusedWindow() 改为 mainWindow.webContents.openDevTools()

javascript 复制代码
// 将 const currentWindow = BrowserWindow.getFocusedWindow() 改为以下代码
mainWindow.webContents.openDevTools()

这种改法在windows下正常,但是mac下关闭程序,程序在Dock中还在,这是使用这种方式依然会报错,这是因为我们没有再mac环境下在程序关闭的时候注销快捷键。所以我们需要再window-all-closed补充上mac环境下的处理。

javascript 复制代码
function createWindow () {
  // 隐藏窗体顶部菜单
  Menu.setApplicationMenu(null)

  /**
   * Initial window options
   */
  mainWindow = new BrowserWindow({
    width: 1338, // 宽
    height: 839, // 高
    minWidth: 1024,
    minHeight: 600,
    useContentSize: true,
    show: false, // 创建后是否显示
    frame: false, // 添加后自定义标题//自定义边框
    center: true, // 是否出现在屏幕居中的位置
    fullscreenable: platform === 'darwin',
    resizable: false, // 可否缩放
    movable: true, // 可否移动
    maximizable: false,
    minimizable: false,
    title: '当前项目名称', // 默认窗口标题
    transparent: false, // 是否是透明窗口(仅macOS)
    // vibrancy: 'ultra-dark', // 窗口模糊的样式(仅macOS)
    backgroundColor: 'none', // 背景色,用于transparent和frameless窗口
    hasShadow: true, // Boolean (可选) - 窗口是否有阴影. 仅在 macOS 上支持. 默认值为 true
    titleBarStyle: 'hidden',
    webPreferences: {
      nodeIntegration: true,
      webSecurity: false, // electron窗体跨域方案
      backgroundThrottling: false // 当页面被置于非激活窗口的时候是否停止动画和计时器
    }
  })

  mainWindow.setMenu(null) // 隐藏菜单栏
  if (platform === 'darwin') {
    Menu.setApplicationMenu(Menu.buildFromTemplate([]))
  }

  mainWindow.loadURL(winURL)

  mainWindow.on('ready-to-show', function () {
    mainWindow.show() // 初始化后再显示

    // 注册快捷键
    globalShortcut.register('CommandOrControl+Alt+T', () => {
      mainWindow.webContents.openDevTools()
    })
  })

  mainWindow.on('closed', () => {
    mainWindow = null
  })
}

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    // windows下调用退出方法
    app.quit()
  } else {
    // mac环境注销所有快捷键
    globalShortcut.unregisterAll()
  }
})

app.on('ready', createWindow)

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow()
  }
})

// 退出程序
app.on('will-quit', () => {
  // windows注销所有快捷键
  globalShortcut.unregisterAll()
})

正确逻辑的核心代码:

javascript 复制代码
  mainWindow.on('ready-to-show', function () {
    mainWindow.show() // 初始化后再显示

    // 注册快捷键
    globalShortcut.register('CommandOrControl+Alt+T', () => {
      mainWindow.webContents.openDevTools()
    })
  })

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    // windows下调用退出方法
    app.quit()
  } else {
    // mac环境注销所有快捷键
    globalShortcut.unregisterAll()
  }
})

// 退出程序
app.on('will-quit', () => {
  // windows环境注销所有快捷键
  globalShortcut.unregisterAll()
})
相关推荐
平头哥~13 分钟前
Day 07 _ 那条 1px 的线,为什么在手机上忽粗忽细
前端·css·样式·学习资料
小江的记录本31 分钟前
【CSS】CSS 动画:transition、animation、transform、CSS3 新特性(附《思维导图》)
前端·css·安全·spring·前端框架·css3·动画
circuitsosk36 分钟前
任务规划器的三种范式对比:ReAct、Plan-and-Execute 与 Tree-of-Thought 在真实业务中的取舍
前端·javascript·python·react.js·llm·ai agent
hzxpaipai2 小时前
企业官网技术架构拆解:前端、后台、数据库、服务器如何协同
前端·数据库·架构
小磊哥er2 小时前
深入解构Claude Code - 第 12 篇 · 整体串起来
javascript·ai编程
小磊哥er2 小时前
深入解构Claude Code - 第 11 篇 · 工程上的讲究
javascript·ai编程
深念Y4 小时前
Lenovo XiaoXinAir 14 — 性能模式切换
前端·网络
计算机魔术师4 小时前
Meta突然杀进第一梯队:一个新模型,把AI推理成本打下来8倍
前端
IT_陈寒4 小时前
Redis缓存雪崩把我坑惨了,这次长记性了
前端·人工智能·后端