
前端CMS【免费下载链接】wp-calypsoThe JavaScript and API powered WordPress.com项目地址https://gitcode.com/gh_mirrors/wp/wp-calypso点击查看免费下载导读client/lib/desktop-listeners是 WordPress.com 桌面应用WP Desktop中连接 Calypso Web 前端与 Electron 主进程的桥梁模块它基于 Electron 的 IPC进程间通信机制在渲染进程内监听主进程发送的导航、登录、通知等控制指令并反向回传页面状态、登录状态与编辑器加载状态。通过本文你将完整掌握该模块的输入/输出事件清单、底层window.electron桥接原理、Redux store 的接入方式以及在desktop功能开关下的运行条件与安全边界。模块定位Calypso 与 Electron 之间的 IPC 接口根据 desktop-listeners/README.md 的说明该模块Provides an interface between Calypso and Electron using Electrons IPC mechanism即它只在启用desktop功能特性时才会运行。其中ipc模块在 Calypso 中被定义为 external因此这段代码只会在 Electron 环境内ipc已定义之处真正执行。从源码结构看该目录只有两个文件client/lib/desktop-listeners/index.js—— 模块唯一实现导出一个DesktopListeners对象client/lib/desktop-listeners/README.md—— 事件协议的权威文档。模块的入口由 client/boot/common.js 在 Calypso 引导阶段调用if ( window.electron ) { DesktopListeners.init( reduxStore ); }也就是说只有当window.electron桥接对象存在即渲染进程运行在 Electron 内且 preload 脚本注入了桥接 API时DesktopListeners.init( reduxStore )才会被调用。普通浏览器环境直接跳过这与 README 中仅在 desktop 功能启用时运行的约束一致。底层桥接preload 脚本如何暴露window.electron要理解事件如何流动需要先看 Electron 侧的 preload 脚本 desktop/public_desktop/preload.js。它通过contextBridge.exposeInMainWorld( electron, ... )向渲染进程暴露了一个白名单化的桥接对象contextBridge.exposeInMainWorld( electron, { send: ( channel, ...args ) { if ( sendChannels.includes( channel ) ) { ipcRenderer.send( channel, ...args ); } }, receive: ( channel, onReceived ) { if ( receiveChannels.includes( channel ) ) { const callback ( _, ...args ) onReceived( ...args ); ipcRenderer.on( channel, callback ); } }, // ... } );关键设计点send/receive都做了通道白名单校验sendChannels与receiveChannels各自按字母序维护只有命中名单的通道才会真正走ipcRenderer.send或ipcRenderer.onreceive的回调包装中显式排除了ipcRenderer事件对象( _, ...args ) onReceived( ...args )保证 Calypso 侧收到的是纯净的业务参数桥接对象还额外注入了logger按 namespace 分级写日志、config、styles如 macOS 标题栏 padding与features特性开关覆写支持WP_DESKTOP_DEBUG_FEATURES环境变量运行时调整。DesktopListeners.init()中调用的window.electron.receive( ... )与window.electron.send( ... )正是经由这个 preload 桥接完成双向通信。输入事件Electron 主进程 → Calypso 渲染进程README 列出 8 个输入事件源码 client/lib/desktop-listeners/index.js 中init方法逐一注册监听IPC 事件名Calypso 侧处理函数触发动作page-my-sitesonShowMySites导航到/sites我的站点page-readeronShowReader导航到/reader阅读器page-profileonShowProfile导航到/me个人资料页new-postonNewPost触发新建文章流程导航到newPost( this.selectedSite )signoutonSignout派发redirectToLogout()登出toggle-notification-baronToggleNotifications切换通知面板的开关状态cookie-auth-complete——由通知客户端处理强制通知客户端以新 cookie 刷新page-helponShowHelp导航到/help帮助页README 中列出的cookie-auth-complete事件在DesktopListeners中并没有注册回调——它由 Electron 主进程直接作用于通知客户端见 preload.js 的receiveChannels白名单用于登录 cookie 更新后让通知 WebSocket 重新建立连接。此外init中还注册了 README 未列出的扩展事件可视为文档的补充实现细节notifications-panel-show→onNotificationsPanelShow( show )根据参数显式打开/关闭通知面板对isNotificationsOpen状态做幂等判断避免重复 dispatchnotifications-panel-refresh→onNotificationsPanelRefresh派发forceNotificationsRefresh( true )强制刷新通知数据notification-clicked→onNotificationClicked( notification )记录calypso_web_push_notification_clickedTracks 事件当前实现中recordTracksEventAction的 dispatch 调用缺少括号仅完成调用而未被真正派发代码注释标注了 TODO计划改为桌面专属 Tracks 事件navigate→onNavigate( url )接收任意 URL 并执行navigate( url )request-user-login-status→sendUserLoginStatus主进程主动查询登录状态时立即回传。所有导航类处理函数都会先调用onNotificationsPanelShow( null, false )关闭通知面板再执行navigate( to )保证页面切换时 UI 状态干净。事件发送方主进程菜单/命令层这些输入事件在 Electron 主进程侧由 desktop/app/lib/calypso-commands/index.js 发出例如showMySites: function ( mainWindow ) { log.info( showMySites triggered ); mainWindow.webContents.send( page-my-sites ); },showMySites、showReader、showProfile、newPost、showHelp、signOut、ping分别对应应用菜单项或系统快捷键触发通过webContents.send把指令推进渲染进程。输出事件Calypso 渲染进程 → Electron 主进程README 将输出事件分为两类随页面/UI 变化的常规事件与启动时一次性发送的状态事件。常规输出事件IPC 事件名语义render( context )页面route切换时发送context为 page.js 的page上下文clear-notices-count用户打开通知面板时清空桌面通知角标editor-iframe-loaded文章编辑器Gutenberg 或经典/TinyMCEiframe 加载完成后发送其中clear-notices-count的发送链路值得展开Calypso 侧的 Redux middleware client/state/desktop/middleware.js 监听NOTIFICATIONS_PANEL_TOGGLEaction当用户切换通知面板时window.dispatchEvent( new window.CustomEvent( NOTIFY_DESKTOP_NOTIFICATIONS_UNSEEN_COUNT_RESET ) );该自定义事件名NOTIFY_DESKTOP_NOTIFICATIONS_UNSEEN_COUNT_RESET定义于 client/state/desktop/window-events.js由DesktopListeners.init()中的window.addEventListener捕获后调用resetUnseenNotifications()最终执行window.electron.send( clear-notices-count )。Electron 主进程侧 desktop/app/window-handlers/notifications/index.js 监听该通道ipc.on( clear-notices-count, function () { if ( notificationBadgeCount 0 ) { log.info( Notification badge count reset ); notificationBadgeCount 0; updateNotificationBadge(); } } );即把累计的未读角标计数清零并根据notification-badge设置决定调用Platform.showNotificationsBadge或Platform.clearNotificationsBadge。对应的主进程侧协议说明见 desktop/app/window-handlers/notifications/README.md。启动时一次性发送的状态事件IPC 事件名语义user-login-status( loggedIn )布尔值表示用户是否已登录user-auth( user, oAuthToken )发送 Calypso 用户对象与 OAuth token两者都可能为 falsesendUserLoginStatus()的实现如下index.jssendUserLoginStatus: function () { let status true; if ( ! isUserLoggedIn( this.store.getState() ) ) { status false; } window.electron.send( user-login-status, status, { id: getCurrentUserId( this.store.getState() ) }, oAuthToken.getToken() ); },细节要点登录状态取自 Reduxcurrent-userselectorisUserLoggedIn用户 ID 通过getCurrentUserId从 store 提取OAuth token 则来自automattic/oauth-token包init()在注册完所有监听后会立即调用一次sendUserLoginStatus()即启动时一次性发送的来源——它同步了桌面应用菜单的可用状态主进程侧 desktop/app/window-handlers/login-status/README.md 说明该事件用于切换需要登录才能使用的菜单项的可用性同时它也会被request-user-login-status请求再次触发回传。通知面板的联动闭环把输入、输出事件串联起来可以看到桌面端通知功能的完整闭环用户在桌面端收到系统通知点击后主进程通过webContents.send( notification-clicked, notification )通知渲染进程见 notifications/index.jsCalypso 侧onNotificationClicked记录 Tracks 事件主进程同时发送navigate带目标 URL或notifications-panel-show无 URL 时Calypso 侧分别执行onNavigate/onNotificationsPanelShow( true )打开通知面板面板打开会 dispatchNOTIFICATIONS_PANEL_TOGGLE经 desktop middleware 派发NOTIFY_DESKTOP_NOTIFICATIONS_UNSEEN_COUNT_RESET窗口事件DesktopListeners捕获后回发clear-notices-count主进程清空角标新通知到达时主进程经notifications-panel-refresh通道通知渲染进程onNotificationsPanelRefresh派发forceNotificationsRefresh( true )强制刷新。这也解释了为什么 README 特别标注clear-notices-count的语义是当用户打开通知面板时清除桌面通知徽标——它是整个通知 UI 状态同步链条的最后一环。模块的注册时机与运行前提综合来看desktop-listeners的完整运行前提有四点desktop功能开关启用window.electron桥接对象存在由 Electron preload 注入client/boot/common.js 中的if ( window.electron )才会成立ipc作为 external 由 Electron 提供Calypso 的 webpack 构建将ipc声明为 external普通浏览器环境不存在该模块代码自然不可运行Redux store 已就绪DesktopListeners.init( reduxStore )在createReduxStore之后被调用client/boot/common.js模块内部依赖 store 的getState()与dispatch读取登录态、触发导航/登出/通知等 actionpreload 白名单匹配所有收发通道必须命中 preload.js 中的sendChannels/receiveChannels否则桥接层直接丢弃。扩展事件协议一览README 之外的实现事实综合 index.js 与 preload.js 的白名单桌面端实际可用的 IPC 通道远多于 README 列出的核心事件整理如下Calypso 接收receiveapp-config、cookie-auth-complete、is-calypso、is-calypso-response、navigate、new-post、notification-clicked、notifications-panel-refresh、notifications-panel-show、page-help、page-my-sites、page-profile、page-reader、request-site、request-user-login-status、signout、toggle-notification-bar。Calypso 发送sendcopy-text-to-clipboard、get-config、get-settings、log、request-site-response、clear-notices-count、back-button-clicked、forward-button-clicked、home-button-clicked、user-auth、user-login-status、view-post-clicked、print、secrets、toggle-dev-tools、title-bar-double-click、magic-link-set-password。其中user-auth通道README 提到但未展开用于把用户对象与 OAuth token 回传主进程配合登录状态切换桌面菜单log通道对接桥接层暴露的window.electron.logger实现按 namespace 分级的前端日志上报。小结client/lib/desktop-listeners以不足两百行代码承担了桌面应用与 Calypso 之间全部业务级 IPC 语义导航指令路由、登录状态同步、通知面板联动与角标清空。理解它的关键在于把握三层结构——Electron 主进程的webContents.send命令源头、preload 桥接的白名单通道安全边界、以及 Calypso 侧window.electron.receive/send与 Redux store 的对接行为落地。在桌面端功能迭代或新增 IPC 事件时需要同时修改三处主进程发送方、preload.js 白名单、以及本模块的监听/回传逻辑并保持 README.md 中的事件协议文档同步更新。赞分享前端CMS【免费下载链接】wp-calypsoThe JavaScript and API powered WordPress.com项目地址https://gitcode.com/gh_mirrors/wp/wp-calypso点击查看免费下载相关推荐LobeHub 桌面端 IPC 客户端封装包 lobechat/electron-client-ipc 全解析LobeHub 桌面端 IPC 客户端封装包 lobechat/electron client ipc 全解析 导读 lobechat/electron c人工智能AI 应用大模型AI Agent多智能体工具调用前端后端LobeHub 桌面端 IPC 链路解析lobechat/electron-server-ipc 如何打通 Electron 主进程与服务端LobeHub 桌面端 IPC 链路解析lobechat/electron server ipc 如何打通 Electron 主进程与服务端 LobeHub人工智能AI 应用大模型AI Agent多智能体工具调用前端后端MediaGo 桌面端 preload 桥接层解析基于 contextBridge 的安全 IPC 通信设计MediaGo 桌面端 preload 桥接层解析基于 contextBridge 的安全 IPC 通信设计 导读 本文围绕 MediaGo 开源仓库中的 p音视频桌面应用后端上一篇Virtual-Display-Driver为Windows系统添加虚拟显示器的完整指南下一篇终极指南如何高效参与Robyn开源项目开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考