Electron -- 窗口焦点通知

Electron - 窗口焦点通知

本文介绍了在 Electron 应用程序中实现窗口焦点通知的方法。通过使用 IPC 机制和自定义事件,可以在多个窗口之间同步和反映窗口的聚焦状态。

1. 步骤概述

1. 创建新的浏览器窗口,并监听窗口被聚焦的 'focus' 事件。在窗口被聚焦时,发送名为 'window-focused' 的 IPC 消息给主进程。

js 复制代码
 win = new BrowserWindow({
   width: 800,
   height: 600,
 });

 // 监听窗口被聚焦事件
 win.on('focus', () => {
   const winId = win.id;
   // 向主进程发送消息,传递当前窗口的 winId
   win.webContents.send('window-focused', winId);
 });

这段代码是在 Electron 的主进程中创建一个新的 BrowserWindow 窗口,并监听窗口被聚焦的 'focus' 事件。

在 'focus' 事件的回调函数中,首先获取当前窗口的 winId,然后使用 win.webContents.send() 方法向渲染进程发送名为 'window-focused' 的 IPC 消息,并将当前窗口的 winId 作为参数传递。 这样做的目的是,在窗口被聚焦时触发 'focus' 事件,并通过 IPC 将窗口的聚焦状态通知给渲染进程,以便其他相关的窗口能够接收到该消息并响应相应的操作。

2. 在主进程中,使用 ipcMain 监听名为 'window-focused' 的 IPC 消息,并广播窗口聚焦状态给其他窗口。

js 复制代码
ipcMain.on('window-focused', (event, winId) => {
  // 广播窗口聚焦消息给其他窗口
BrowserWindow.getAllWindows().forEach(window => {
      window.webContents.send('window-focus-update', winId);
    });
});

这段代码是在 Electron 的主进程中使用 ipcMain 监听名为 'window-focused' 的 IPC 消息。当收到该消息时,它会执行回调函数。

在回调函数中,主要的逻辑是广播窗口聚焦消息给其他窗口。它通过使用 BrowserWindow.getAllWindows() 方法获取当前应用程序中的所有窗口,并遍历每个窗口发送名为 'window-focus-update' 的 IPC 消息,将聚焦的窗口的 winId 作为参数传递。

这样做可以实现窗口聚焦更新的事件通知,让其他窗口能够获取到最新的聚焦窗口的信息。

3. 通过接口registerWinFocusCallback注册回调函数 _cb,用于处理窗口聚焦更新事件。在回调函数被调用时,通过自定义事件 'window-focus-update' 分发窗口的 winId 到文档中。

js 复制代码
const _cb = winId => void document.dispatch(new CustomEvent('window-focus-update', {details:winId}));

globalThis.globalAPI?.registerWinFocusCallback(_cb);

这段代码是在渲染进程中调用 globalAPI 全局对象的 registerWinFocusCallback 方法,并传递一个回调函数 _cb 作为参数。 在回调函数 _cb 中,它创建了一个自定义事件 'window-focus-update',并通过 document.dispatch() 方法将该事件分发到文档中。事件的细节信息包含了窗口的 winId 参数。

这样做的目的是使用 registerWinFocusCallback 注册一个窗口聚焦更新的回调函数,当窗口聚焦更新事件发生时,回调函数会被调用,并触发自定义事件 'window-focus-update',从而通知其他部分(如之前提到的第一段代码)进行相应处理。

4. 在渲染进程中,使用 contextBridgeipcRendererglobalAPI 对象注入到前端页面的上下文中。

js 复制代码
const { contextBridge, ipcRenderer } = require('electron');

// 定义全局对象
const globalAPI = {
  registerWinFocusCallback: (cb) => {
    ipcRenderer.on('window-focus-update', (event, winId) => void cb(winId))},
};

// 将全局对象注入到渲染进程的上下文中
contextBridge.exposeInMainWorld('globalAPI', globalAPI);

这段代码是在 Electron 的渲染进程中使用 contextBridgeipcRenderer,将一个名为 globalAPI 的全局对象注入到渲染进程的上下文中。

globalAPI 对象包含了一个方法 registerWinFocusCallback,它用于注册窗口聚焦更新事件的回调函数。具体来说,当收到名为 'window-focus-update' 的 IPC 消息时,该回调函数会被调用,并将窗口的 winId 作为参数传递给回调函数。

通过使用 contextBridge.exposeInMainWorld() 方法,globalAPI 全局对象被暴露给渲染进程的前端页面,在前端页面中可以直接访问和使用其中的方法。

5. 在 React 组件中使用 useEffect 钩子监听窗口聚焦更新事件。根据获取的窗口 ID 更新 SVG 元素的颜色。

js 复制代码
useEffect(() => {
    const changeSvgColor = (color) => {
    const svgElement = document.getElementById('state');
    if (svgElement) {
      svgElement.style.fill = color;
    }
  };
    const handleFocusUpdate = (event) => {
      const winId = event.detail;
      const _winId = sessionStorage.getItem("winId");
      changeSvgColor(winId===_winId?'grey':'white');
    };

    window.addEventListener('window-focus-update', handleFocusUpdate);

    return () => {
      window.removeEventListener('window-focus-update', handleFocusUpdate);
    };
  }, []);

这段代码是使用 React 的 useEffect 钩子实现了监听窗口聚焦更新事件,并根据获取的窗口 ID 更新 SVG 元素的颜色。

在 useEffect 中,首先定义了 changeSvgColor 函数,用于修改 SVG 元素的颜色。然后定义了 handleFocusUpdate 函数,它会在窗口聚焦更新事件触发时被调用。在该函数中,它通过比较传入的窗口 ID (winId) 与存储在 sessionStorage 中的窗口 ID (_winId),确定要设置的颜色,并调用 changeSvgColor 函数进行颜色的更新。 接下来,使用 window.addEventListener 方法将 handleFocusUpdate 函数注册为 'window-focus-update' 事件的监听器。

2. 总结

通过结合上述步骤和示例代码,可以实现在 Electron 应用程序中监听和处理窗口焦点更新事件,并相应地更新界面元素的颜色。这样可以提供一致的用户体验,使用户能够清晰地了解当前具有焦点的窗口。

相关推荐
bin915333 分钟前
DeepSeek 助力 Vue 开发:打造丝滑的复制到剪贴板(Copy to Clipboard)
前端·javascript·vue.js·ecmascript·deepseek
晴空万里藏片云2 小时前
elment Table多级表头固定列后,合计行错位显示问题解决
前端·javascript·vue.js
曦月合一2 小时前
html中iframe标签 隐藏滚动条
前端·html·iframe
奶球不是球2 小时前
el-button按钮的loading状态设置
前端·javascript
kidding7232 小时前
前端VUE3的面试题
前端·typescript·compositionapi·fragment·teleport·suspense
无责任此方_修行中4 小时前
每周见闻分享:杂谈AI取代程序员
javascript·资讯
Σίσυφος19004 小时前
halcon 条形码、二维码识别、opencv识别
前端·数据库
学代码的小前端4 小时前
0基础学前端-----CSS DAY13
前端·css
dorabighead5 小时前
JavaScript 高级程序设计 读书笔记(第三章)
开发语言·javascript·ecmascript
css趣多多5 小时前
案例自定义tabBar
前端