尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

NW.js Shortcut API 完全指南:实现应用失焦也能触发的全局桌面快捷键

NW.js Shortcut API 完全指南:实现应用失焦也能触发的全局桌面快捷键 NW.js Shortcut API 完全指南实现应用失焦也能触发的全局桌面快捷键【免费下载链接】nw.jsCall all Node.js modules directly from DOM/WebWorker and enable a new way of writing applications with all Web technologies.项目地址: https://gitcode.com/gh_mirrors/nw/nw.js导读Shortcut是 NW.js 提供的全局桌面快捷键系统级热键API只要注册成功即使应用窗口完全没有焦点用户按下对应组合键时应用依然能收到通知。本文以官方文档 docs/References/Shortcut.md 为主体结合仓库源码src/api/shortcut/目录及src/api/app/app.cc深入讲解快捷键的创建、注册、事件监听与注销全流程并给出修饰键、按键的完整合法取值表与底层实现原理帮助你为 NW.js 应用快速实现全局热键唤起类功能。基本概念全局快捷键与普通快捷键的区别Shortcut代表一个全局键盘快捷键global keyboard shortcut也就是常说的系统级热键system-wide hotkey。它与网页内keydown/keyup事件监听的最大区别在于普通按键事件只在应用获得焦点、且焦点位于页面内时才会触发全局快捷键由操作系统层面捕获即使应用没有焦点只要用户按下已注册的组合键应用就会收到通知。从源码结构看NW.js 通过nwapi::GlobalShortcutListener这一平台无关 平台具体两层设计来实现该能力公共逻辑维护快捷键 → 观察者映射表global_shortcut_listener.h而真正的系统级按键捕获委托给各平台实现macOS、Windows、X11/Linux 各有独立文件如 global_shortcut_listener_x11.cc。Shortcut对象继承自 Node.js 的EventEmitter。每次用户按下已注册的快捷键应用都会在该 shortcut 对象上收到active事件注册失败或按键无法解析时则会收到failed事件。完整示例最短可用代码官方文档给出的 Synopsis 覆盖了创建、注册、监听、注销四个完整步骤这里完整保留并加以注释var option { key : CtrlShiftA, active : function() { console.log(Global desktop keyboard shortcut: this.key active.); }, failed : function(msg) { // :(, fail to register the |key| or couldnt parse the |key|. console.log(msg); } }; // Create a shortcut with |option|. var shortcut new nw.Shortcut(option); // Register global desktop shortcut, which can work without focus. nw.App.registerGlobalHotKey(shortcut); // If register |shortcut| successfully and user struck CtrlShiftA, |shortcut| // will get an active event. // You can also add listener to shortcuts active and failed event. shortcut.on(active, function() { console.log(Global desktop keyboard shortcut: this.key active.); }); shortcut.on(failed, function(msg) { console.log(msg); }); // Unregister the global desktop shortcut. nw.App.unregisterGlobalHotKey(shortcut);使用要点通过new nw.Shortcut(option)创建快捷键对象通过nw.App.registerGlobalHotKey(shortcut)向系统注册监听active事件响应按键不再需要时用nw.App.unregisterGlobalHotKey(shortcut)注销避免热键被应用长期占用。在 JS 绑定层shorcut.js构造函数会做严格校验option必须是对象且必须包含key属性否则直接抛出TypeErroractive、failed若提供则必须是函数。也就是说key是唯一必填项两个回调均可选。new Shortcut(option) 构造参数详解参数类型必填说明optionObject是包含初始设置的对象option.keyString是快捷键组合如CtrlShiftA详见下文shortcut.keyoption.activeFunction否热键被触发时的回调对应shortcut.active属性option.failedFunction否热键注册失败时的回调对应shortcut.failed属性从 C 侧看Shortcut构造时shortcut.cc会从option中取出key字符串交给Parse()解析为ui::Accelerator如果解析结果主键码为VKEY_UNKNOWN会立即触发OnFailed(Can not parse shortcut: ...)把错误信息通过failed事件回报给 JS 层。shortcut.key组合键的书写规范与完整取值表shortcut.key用于获取一个Shortcut的按键组合它是一个字符串形如CtrlAltA。组合键由零个或多个修饰键modifiers与一个主键码key组成且只支持单个键码——即一个key字符串里只能有一个主键不能写成CtrlAB这种多主键形式。键码大小写不敏感例如ctrlshifta与CtrlShiftA等价。在底层解析时shortcut.ccParse()会先把整个字符串转为小写再按号分割成 token逐个识别为修饰键或主键码。支持的修饰键Modifiers修饰键说明Ctrl控制键AltAlt 键ShiftShift 键Command在 macOS 上映射为 Apple 键⌘在 Windows 和 Linux 上映射为 Windows 键值得注意的一个平台差异细节在 shortcut.cc 中Ctrl在 macOS 上被映射为EF_COMMAND_DOWN即 Command 键而在其他平台映射为EF_CONTROL_DOWNCtrl 键。这意味着CtrlA在 Mac 上实际绑定的是 ⌘A跨平台应用需要留意这一行为差异。支持的按键Keys类别合法取值字母A-Z数字0-9功能键F1-F24编辑/导航键Home/End/PageUp/PageDown/Insert/Delete方向键Up/Down/Left/Right媒体键MediaNextTrack/MediaPlayPause/MediaPrevTrack/MediaStop标点符号别名Comma或,Period或.Tab或\tBackquote或Enter或\nMinus或-Equal或Backslash或\Semicolon或;Quote或BracketLeft或[BracketRight或]其他Escape以及 DOM Level 3 W3C KeyboardEvent Code Values 中定义的键值这些取值与源码中的常量一一对应见 shortcut_constants.cc例如kKeyMediaNextTrack medianexttrack、kKeyPgUp pageup、kKeyTab tab。解析时字母和数字通过 ASCII 区间直接映射为VKEY_A-VKEY_Z、VKEY_0-VKEY_9shortcut.cc。警告无修饰键的单键注册需谨慎官方文档明确给出警告nw.App.registerGlobalHotKey()允许应用拦截单个按键如{ key: A }。但一旦注册成功在应用注销之前用户在系统里将无法正常使用字母 A因为该按键已被系统级截获。不过 API 本身不限制这种用法——如果你想监听媒体键如MediaNextTrack无修饰键注册反而是有用的。只在明确知道自己在做什么时才使用零修饰键的注册。shortcut.active 与 shortcut.failedshortcut.active获取或设置快捷键被按下时的回调函数。用户按下已注册组合键时触发。shortcut.failed获取或设置失败回调。当应用传入无效的按键无法解析或注册失败例如该热键已被其他程序占用时触发回调参数为失败原因字符串。在 JS 绑定层shorcut.jshandleEvent收到active事件时会调用this.active()收到failed事件时会以arguments[1]为参数调用this.failed(msg)随后继续交由exports.Base的handleEvent分发从而同步触发对应的 EventEmitter 事件见下节。C 侧对应的事件发送逻辑位于 shortcut.ccOnActive()发送空参数的active事件OnFailed()把错误消息字符串随failed事件一并发出。事件active 与 failedEvent:active与shortcut.active属性等价。用户按下已注册快捷键时触发。Event:failed与shortcut.failed属性等价。传入非法按键或注册失败时触发。因为Shortcut继承自EventEmittershorcut.js 中util.inherits(Shortcut, exports.Base)Base具备事件能力所以既可以在构造参数里传回调也可以事后用.on(active, ...)/.on(failed, ...)添加监听器两种方式可以混用。从源码看注册与注销的完整调用链当你调用nw.App.registerGlobalHotKey(shortcut)时实际发生的过程如下JS → C 桥接app.cc的同步方法分发中RegisterGlobalHotKey分支根据传入的object_id取出对应的Shortcut*对象然后调用GlobalShortcutListener::GetInstance()-RegisterAccelerator(shortcut-GetAccelerator(), shortcut)app.cc。如果注册失败会立刻回调shortcut-OnFailed(Register global desktop keyboard shortcut failed.)。公共逻辑去重GlobalShortcutListener::RegisterAcceleratorglobal_shortcut_listener.cc先检查该加速键是否已在accelerator_map_中若已被注册则返回false接着调用平台相关的RegisterAcceleratorImpl只有底层系统注册成功才会把加速键 → 观察者写入映射表。若此前没有任何注册会先StartListening()开始监听系统按键事件。平台实现以 X11/Linux 为例global_shortcut_listener_x11.cc实现通过XGrabKey在根窗口上抓取按键并且为了兼容 Num Lock、Caps Lock、Scroll Lock 三种锁定状态会对 8 种修饰键组合kModifiersMasks逐一抓取从而保证各平台行为一致。按键分发用户按下组合键后平台层回调NotifyKeyPressed(accelerator)在映射表中找到观察者并调用其OnKeyPressedShortcut::OnKeyPressed确认加速键匹配后触发OnActive()最终把active事件送回 JS 层shortcut.cc。注销过程是对称的nw.App.unregisterGlobalHotKey(shortcut)最终调用GlobalShortcutListener::UnregisterAccelerator执行平台层的XUngrabKey等解除抓取操作并从映射表移除条目当映射表清空时自动StopListening()global_shortcut_listener.cc。此外GlobalShortcutListener还提供了SetShortcutHandlingSuspended挂起/恢复机制用于避免在窗口设置快捷键时系统热键干扰输入。另外仓库中还存在一份扩展 API 的 IDL 定义 nw_shortcut.idl声明了registerAccelerator/unregisterAccelerator函数与onKeyPressed事件其Accelerator结构由key加command/ctrl/alt/shift四个布尔修饰键组成可看作 Shortcut 机制在扩展系统侧的另一种表达。典型应用场景与注意事项适合使用全局快捷键的场景包括全局唤起应用最小化或失焦时通过热键把主窗口重新显示并前置快捷操作截图、录音、翻译等工具型应用常驻后台时响应热键媒体控制注册MediaNextTrack/MediaPlayPause等媒体键实现全局播放控制这也是文档特别指出无修饰键注册有用的场景。实践建议始终在应用退出或不再需要时调用nw.App.unregisterGlobalHotKey(shortcut)释放热键避免占用系统资源或与其他应用冲突为failed事件编写兜底逻辑例如弹出提示或改用应用内快捷键因为同一组合键可能已被其他原生程序注册——GlobalShortcutListener::RegisterAccelerator的注释也说明注册失败最常见的原因就是该快捷键已被其他原生应用注册注意Command/Ctrl在 macOS 上的映射差异跨平台应用应针对不同平台选用合适的组合键。相关文档与源码索引官方参考文档docs/References/Shortcut.mdJS 绑定层src/api/shortcut/shorcut.jsC 实现与按键解析src/api/shortcut/shortcut.cc、src/api/shortcut/shortcut_constants.cc平台无关监听器src/api/shortcut/global_shortcut_listener.cc、src/api/shortcut/global_shortcut_listener.h平台实现X11/Linux 版 global_shortcut_listener_x11.cc另有 macOS、Windows 版本位于同目录注册/注销入口src/api/app/app.cc扩展 API 定义src/api/nw_shortcut.idl【免费下载链接】nw.jsCall all Node.js modules directly from DOM/WebWorker and enable a new way of writing applications with all Web technologies.项目地址: https://gitcode.com/gh_mirrors/nw/nw.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表