全局快捷键
功能特性
- ✅ 全局快捷键注册(应用失焦时依然有效)
- ✅ 跨平台快捷键支持(Windows、macOS、Linux)
- ✅ 快捷键冲突检测
- ✅ 自动注册和卸载
快捷键列表
开发工具
| 快捷键 | 功能 | 说明 |
|---|---|---|
Ctrl+Alt+D (Windows/Linux)Cmd+Alt+D (macOS) | 打开开发者工具 | 快速打开 DevTools 调试 |
javascript
globalShortcut.register('CmdOrCtrl+Alt+D', () => {
win.webContents.openDevTools();
});配置管理
| 快捷键 | 功能 | 说明 |
|---|---|---|
Ctrl+Alt+Shift+P (Windows/Linux)Cmd+Alt+Shift+P (macOS) | 打开配置页面 | 打开应用配置编辑窗口 |
javascript
globalShortcut.register('CmdOrCtrl+Alt+Shift+P', () => {
this.openConfigWindow();
});配置窗口特性:
- 模态窗口,独占交互
- 900x775 固定尺寸
- 支持编辑 config.ini 配置项
- 修改后需重启应用生效
性能优化
| 快捷键 | 功能 | 说明 |
|---|---|---|
Ctrl+Alt+Shift+G (Windows/Linux)Cmd+Alt+Shift+G (macOS) | 性能配置 | 打开性能模式配置窗口 |
javascript
globalShortcut.register('CmdOrCtrl+Alt+Shift+G', () => {
this.openPerformWindow();
});性能配置选项:
- 硬件加速开关
- 后台节流控制
- 内存优化设置
- GPU 进程配置
插件管理
| 快捷键 | 功能 | 说明 | 条件 |
|---|---|---|---|
Ctrl+Alt+Shift+M (Windows/Linux)Cmd+Alt+Shift+M (macOS) | 插件管理 | 打开插件管理界面 | 需启用插件系统 |
javascript
const enablePluginSystem = getConfigValue('enablePluginSystem');
if (enablePluginSystem) {
globalShortcut.register('CmdOrCtrl+Alt+Shift+M', () => {
this.openPluginManagerWindow();
});
}插件管理功能:
- 查看已安装插件列表
- 启动/停止插件
- 上传新插件
- 删除插件
- 查看插件详情
缓存清理
| 快捷键 | 功能 | 说明 |
|---|---|---|
Ctrl+Shift+R (Windows/Linux)Cmd+Shift+R (macOS) | 清除缓存并刷新 | 清除页面缓存并强制刷新 |
javascript
globalShortcut.register('CmdOrCtrl+Shift+R', async () => {
await win.webContents.session.clearCache();
win.webContents.reloadIgnoringCache();
});清理内容:
- HTTP 缓存
- 磁盘缓存
- 内存缓存
- Service Worker 缓存
悬浮球
| 快捷键 | 功能 | 说明 |
|---|---|---|
Ctrl+Alt+H (Windows/Linux)Cmd+Alt+H (macOS) | 收起到悬浮球 | 隐藏主窗口并显示悬浮球 |
javascript
globalShortcut.register('CmdOrCtrl+Alt+H', () => {
FloatingBallService.hideMainWindow();
});悬浮球特性:
- 始终置顶显示
- 可拖动位置
- 点击恢复主窗口
- 自动保存位置
快捷键实现
初始化
javascript
class ShortcutHandler {
constructor(win) {
this.win = win;
this.configWin = null;
this.performWin = null;
this.pluginManagerWin = null;
this.registerCustomShortcut();
this.setupIpcListeners();
}
/**
* 注册自定义键盘快捷键
*/
registerCustomShortcut() {
this.registerOpenDevTools();
this.registerOpenConfig();
this.registerOpenPerform();
this.registerClearPageCache();
this.registerOpenPluginManager();
this.registerMinimizeToFloatingBall();
}
}注册单个快捷键
javascript
registerOpenDevTools() {
const result = globalShortcut.register('CmdOrCtrl+Alt+D', () => {
this.win.webContents.openDevTools();
});
logger.info('注册开发者工具快捷键CmdOrCtrl+Alt+D:', result ? '成功' : '失败');
}快捷键检测
javascript
// 检查快捷键是否已注册
const isRegistered = globalShortcut.isRegistered('CmdOrCtrl+Alt+D');
// 如果已被其他应用占用,会注册失败
if (!result) {
logger.warn('快捷键已被占用,无法注册');
}卸载快捷键
javascript
static unregisterCustomShortcut() {
globalShortcut.unregister('CmdOrCtrl+Alt+D');
globalShortcut.unregister('CmdOrCtrl+Alt+Shift+P');
globalShortcut.unregister('CmdOrCtrl+Alt+Shift+G');
globalShortcut.unregister('CmdOrCtrl+Alt+Shift+M');
globalShortcut.unregister('CmdOrCtrl+Shift+R');
globalShortcut.unregister('CmdOrCtrl+Alt+H');
logger.info('所有快捷键已卸载');
}配置窗口
配置编辑窗口
javascript
openConfigWindow() {
if (this.configWin && !this.configWin.isDestroyed()) {
this.configWin.focus();
return;
}
this.configWin = new BrowserWindow({
width: 900,
height: 775,
parent: this.win,
modal: true, // 模态窗口
autoHideMenuBar: true,
minimizable: false,
maximizable: false,
resizable: false,
fullscreenable: false,
webPreferences: {
nodeIntegration: true, // 允许 Node 集成(配置编辑需要)
contextIsolation: false,
},
frame: process.platform !== 'darwin',
titleBarStyle: process.platform === 'darwin' ? 'hidden' : 'default',
});
this.configWin.loadFile(path.join(__dirname, 'update-config.html'));
this.configWin.on('closed', () => {
this.configWin = null;
});
}特点:
- 模态窗口,父窗口失焦
- 固定尺寸,不可调整
- 独立的 HTML 页面
- 直接编辑 INI 配置文件
性能配置窗口
javascript
openPerformWindow() {
if (this.performWin && !this.performWin.isDestroyed()) {
this.performWin.focus();
return;
}
this.performWin = new BrowserWindow({
width: 640,
height: 620,
parent: this.win,
modal: true,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
sandbox: false,
preload: path.join(app.getAppPath(), 'src/preload/preload-config.js'),
},
});
// 开发环境和生产环境加载不同路径
if (app.isPackaged) {
this.performWin.loadFile(path.join(process.resourcesPath, 'renderer', 'update-perform.html'));
} else {
this.performWin.loadURL('http://localhost:3000/update-perform.html');
}
}插件管理窗口
javascript
openPluginManagerWindow() {
if (this.pluginManagerWin && !this.pluginManagerWin.isDestroyed()) {
this.pluginManagerWin.focus();
return;
}
this.pluginManagerWin = new BrowserWindow({
width: 1200,
height: 800,
parent: this.win,
modal: true,
resizable: true, // 可调整大小
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
sandbox: false,
preload: path.join(app.getAppPath(), 'src/preload/preload-plugin.js'),
},
});
// 根据环境加载不同路径
if (app.isPackaged) {
// 生产环境:加载打包后的文件
this.pluginManagerWin.loadFile(
path.join(process.resourcesPath, 'renderer', 'plugin.html')
);
} else {
// 开发环境:使用 Vite 开发服务器
this.pluginManagerWin.loadURL('http://localhost:3000/plugin.html');
}
}IPC 通信
应用重启请求
配置修改后需要重启应用:
javascript
setupIpcListeners() {
ipcMain.on('app-restart-request', () => {
logger.info('收到重启应用请求');
app.relaunch();
app.exit(0);
});
}使用场景:
- 修改配置后重启
- 更新插件后重启
- 切换性能模式后重启
快捷键修饰符
跨平台修饰符
| 修饰符 | Windows/Linux | macOS | 说明 |
|---|---|---|---|
CmdOrCtrl | Ctrl | Cmd | 主修饰符 |
Alt | Alt | Option | 替代键 |
Shift | Shift | Shift | Shift 键 |
Super | Win | - | Windows 键 |
组合修饰符
javascript
// 单个修饰符
'Ctrl+A';
// 多个修饰符
'Ctrl+Shift+A';
// 跨平台
'CmdOrCtrl+Alt+Shift+A';
// 功能键
'F1';
'F12';
// 特殊键
'Space';
'Tab';
'Enter';
'Escape';生命周期
注册时机
javascript
// 在主窗口创建后注册
app.whenReady().then(() => {
const win = createWindow();
new ShortcutHandler(win);
});卸载时机
javascript
// 应用退出前卸载
app.on('will-quit', () => {
ShortcutHandler.unregisterCustomShortcut();
});
// 或者卸载所有快捷键
app.on('will-quit', () => {
globalShortcut.unregisterAll();
});最佳实践
1. 快捷键冲突避免
javascript
// 检查是否已被占用
const shortcut = 'CmdOrCtrl+Alt+D';
if (globalShortcut.isRegistered(shortcut)) {
logger.warn(`快捷键 ${shortcut} 已被占用`);
// 尝试使用备用快捷键
const fallback = 'CmdOrCtrl+Alt+Shift+D';
globalShortcut.register(fallback, callback);
}2. 错误处理
javascript
registerMinimizeToFloatingBall() {
const result = globalShortcut.register('CmdOrCtrl+Alt+H', () => {
try {
FloatingBallService.hideMainWindow();
logger.info('通过快捷键收起到悬浮球');
} catch (error) {
logger.error('快捷键收起到悬浮球失败:', error);
// 显示错误提示
dialog.showErrorBox('操作失败', error.message);
}
});
if (!result) {
logger.warn('快捷键注册失败,可能被占用');
}
}3. 窗口状态检查
javascript
openConfigWindow() {
// 检查窗口是否已存在
if (this.configWin && !this.configWin.isDestroyed()) {
this.configWin.focus();
return;
}
// 创建新窗口
this.configWin = new BrowserWindow({ /* ... */ });
// 清理引用
this.configWin.on('closed', () => {
this.configWin = null;
});
}4. 条件注册
javascript
// 只在启用插件系统时注册插件管理快捷键
registerOpenPluginManager() {
const enablePluginSystem = getConfigValue('enablePluginSystem');
if (!enablePluginSystem) {
logger.info('插件系统未启用,跳过注册插件管理快捷键');
return;
}
const result = globalShortcut.register('CmdOrCtrl+Alt+Shift+M', () => {
this.openPluginManagerWindow();
});
logger.info('注册插件管理快捷键:', result ? '成功' : '失败');
}5. 平台适配
javascript
// 根据平台设置窗口样式
const windowOptions = {
width: 900,
height: 775,
frame: process.platform !== 'darwin',
titleBarStyle: process.platform === 'darwin' ? 'hidden' : 'default',
};注意事项
1. 全局快捷键限制
- ⚠️ 全局快捷键在应用失焦时依然有效
- ⚠️ 可能与系统或其他应用快捷键冲突
- ⚠️ 某些系统保留快捷键无法注册
- ⚠️ macOS 需要在系统偏好设置中授予权限
2. 资源清理
javascript
// 必须在应用退出前卸载,否则可能影响其他应用
app.on('will-quit', () => {
globalShortcut.unregisterAll();
});3. 开发环境
javascript
// 开发环境下,热重载时需要重新注册快捷键
if (!app.isPackaged) {
app.on('before-quit', () => {
globalShortcut.unregisterAll();
});
}4. 模态窗口注意
javascript
// 模态窗口会阻止父窗口交互
modal: true; // 谨慎使用
// 如果需要非阻塞,设置为 false
modal: false;快捷键自定义
用户自定义快捷键(扩展)
可以通过配置文件支持用户自定义快捷键:
json
{
"shortcuts": {
"openDevTools": "CmdOrCtrl+Alt+D",
"openConfig": "CmdOrCtrl+Alt+Shift+P",
"clearCache": "CmdOrCtrl+Shift+R",
"hideToFloatingBall": "CmdOrCtrl+Alt+H"
}
}读取配置并注册:
javascript
const shortcuts = loadShortcutsConfig();
Object.keys(shortcuts).forEach((action) => {
const key = shortcuts[action];
globalShortcut.register(key, () => {
this[`handle${action}`]();
});
});常见问题
Q1: 快捷键不生效?
可能原因:
- 快捷键被其他应用占用
- 系统保留快捷键
- macOS 未授予权限
解决方案:
javascript
// 检查注册状态
const result = globalShortcut.register(shortcut, callback);
if (!result) {
console.error('快捷键注册失败');
}Q2: 如何临时禁用快捷键?
javascript
// 临时卸载
globalShortcut.unregister('CmdOrCtrl+Alt+D');
// 重新注册
globalShortcut.register('CmdOrCtrl+Alt+D', callback);Q3: 开发环境快捷键冲突?
开发环境下 Vite DevTools 快捷键可能冲突:
javascript
// 在开发环境使用不同的快捷键
const devShortcut = app.isPackaged ? 'CmdOrCtrl+Alt+D' : 'CmdOrCtrl+Alt+Shift+D';相关文件
packages/main/src/shortcut/global-shortcut.js- 快捷键处理器packages/renderer/src/pages/config/- 基础配置页面源码packages/renderer/src/pages/perform/- 性能配置页面源码packages/renderer/src/pages//plugin- 插件管理页面页面