Skip to content

feat: 实现全局快捷键功能#52

Open
Afeng01 wants to merge 18 commits intoErlichLiu:mainfrom
Afeng01:feature/global-hotkey
Open

feat: 实现全局快捷键功能#52
Afeng01 wants to merge 18 commits intoErlichLiu:mainfrom
Afeng01:feature/global-hotkey

Conversation

@Afeng01
Copy link
Contributor

@Afeng01 Afeng01 commented Feb 27, 2026

功能概述

实现了全局快捷键功能,用户可以在设置中自定义快捷键来快速打开 Chat/Agent 对话。

实现的功能

核心功能

  • 全局快捷键注册和管理(基于 Electron globalShortcut API)
  • 快捷键设置界面(支持自定义录制)
  • Chat 模式快捷键(支持"新建对话"和"打开当前对话"两种行为)
  • Agent 模式快捷键(支持"新建会话"和"打开当前会话"两种行为)
  • 快捷键验证(检测冲突和可用性)
  • 快捷键启用/禁用开关

用户体验优化

  • 快捷键显示格式优化(Mac 显示 "Cmd+M",Windows 显示 "Ctrl+M")
  • 新对话/会话创建后立即显示在侧边栏
  • 支持区分 Command 和 Control 键(Mac 用户可设置专用快捷键)
  • 快捷键行为实时生效(无需重启应用)
  • Agent 会话正确关联工作区

技术实现

架构设计

  • 主进程: global-shortcut-service.ts 管理快捷键注册/注销/验证
  • 渲染进程: ShortcutSettings.tsx 提供设置界面,ShortcutRecorder.tsx 实现快捷键录制
  • IPC 通信: 主进程通过 shortcut:chat 和 shortcut:agent 事件通知渲染进程
  • 状态管理: 使用 Jotai atoms 管理快捷键配置和加载状态
  • 持久化: 快捷键配置保存在 ~/.proma/settings.json

关键实现

  1. 快捷键录制: 监听键盘事件,构建 Electron accelerator 格式
  2. 实时更新: 每次触发时重新读取最新设置,确保行为变更立即生效
  3. 注销机制: 注册新快捷键前先注销所有旧快捷键,避免冲突
  4. 工作区关联: Agent 会话创建时传递 currentWorkspaceId 参数

测试计划

快捷键设置测试

  • 打开设置 -> 快捷键,点击 Chat 快捷键输入框,按下 Cmd+T(Mac)或 Ctrl+T(Windows)
  • 验证显示格式正确("Cmd+T" 或 "Ctrl+T"),点击清除按钮,验证快捷键被清除,测试启用/禁用开关

Chat 模式快捷键测试

  • 设置 Chat 快捷键为 Cmd+T,行为选择"新建对话",按下快捷键,验证应用切换到 Chat 模式,验证创建新对话,验证新对话立即出现在左侧边栏
  • 修改行为为"打开当前对话",按下快捷键,验证如果有对话则保持当前对话

Agent 模式快捷键测试

  • 设置 Agent 快捷键为 Cmd+G,行为选择"新建会话",按下快捷键,验证应用切换到 Agent 模式,验证创建新会话,验证新会话出现在当前工作区的会话列表中
  • 修改行为为"打开当前会话",按下快捷键,验证行为正确

已修复的问题

  • 快捷键显示格式过长(已优化为简洁格式)
  • 新对话不立即显示(已修复)
  • "打开当前对话"行为不正确(已修复)
  • 清除快捷键后仍然触发(已修复)
  • Agent 会话找不到(已修复工作区关联)
  • 无法区分 Command 和 Control 键(已修复)

相关文件

新增文件

  • apps/electron/src/main/lib/global-shortcut-service.ts
  • apps/electron/src/renderer/components/settings/ShortcutSettings.tsx
  • apps/electron/src/renderer/components/settings/primitives/ShortcutRecorder.tsx
  • apps/electron/src/renderer/atoms/shortcut-atoms.ts
  • apps/electron/src/types/settings.ts(扩展)

修改文件

  • apps/electron/src/main/index.ts
  • apps/electron/src/main/lib/settings-service.ts
  • apps/electron/src/preload/index.ts
  • apps/electron/src/renderer/main.tsx
  • apps/electron/src/renderer/components/settings/SettingsPanel.tsx

其他

邮箱:fkufeng01@gmail.com

Afeng01 and others added 18 commits February 26, 2026 19:49
- 添加 ShortcutBehavior 类型(new-conversation | current-conversation)
- 添加 ShortcutConfig 接口(accelerator, enabled, behavior)
- 添加默认配置常量(DEFAULT_CHAT_SHORTCUT, DEFAULT_AGENT_SHORTCUT)
- 在 AppSettings 接口中添加 chatShortcut 和 agentShortcut 字段
- 扩展 SETTINGS_IPC_CHANNELS 常量(REGISTER_SHORTCUTS, UNREGISTER_SHORTCUTS, VALIDATE_SHORTCUT)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- 创建 GlobalShortcutService 管理全局快捷键
- 实现 registerShortcuts() 注册快捷键
- 实现 unregisterShortcuts() 注销快捷键
- 实现 validateShortcut() 验证快捷键可用性
- 实现窗口显示和聚焦逻辑
- 处理 Chat 和 Agent 快捷键触发事件

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- 导入 DEFAULT_CHAT_SHORTCUT 和 DEFAULT_AGENT_SHORTCUT
- 在 getSettings() 中添加快捷键默认值处理
- 文件不存在时返回默认快捷键配置
- 从文件读取时使用默认值填充缺失的快捷键配置
- 读取失败时返回默认快捷键配置
- updateSettings() 已支持快捷键字段(通过展开运算符)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- 注册全局快捷键
- 注销全局快捷键
- 验证快捷键可用性
Task 5 & 6:
- 创建快捷键 Atoms (shortcut-atoms.ts)
- 扩展 Preload 桥接暴露快捷键 IPC 方法
- 支持加载、更新、验证快捷键配置
- 实现键盘事件监听
- 支持快捷键格式化(Electron accelerator 格式)
- 添加冲突检测提示
- 支持清除快捷键
- 使用 SettingsSection/SettingsCard/SettingsRow 组件
- 集成快捷键录制组件
- 支持启用/禁用开关
- 支持行为选项配置(新对话/当前对话)
- 添加 macOS 权限提示
- 在 settings-tab.ts 中添加 'shortcuts' 类型
- 在 SettingsPanel.tsx 中添加快捷键标签页
- 在 index.ts 中导出 ShortcutSettings
- 使用 Keyboard 图标
- 在 app.whenReady() 中设置主窗口引用并注册快捷键
- 在 app.on('before-quit') 中注销快捷键
- 确保应用启动时快捷键立即生效
- 添加 onChatShortcut 和 onAgentShortcut 事件监听器
- 监听主进程发送的 shortcut:chat 和 shortcut:agent 事件
- 返回清理函数用于取消订阅
Task 11 & 12: 完成快捷键功能的渲染进程集成

- 创建 ShortcutInitializer 组件
- Task 12: 应用启动时加载快捷键配置
- Task 11: 监听 Chat/Agent 快捷键触发事件
- 根据 behavior 执行相应操作:
  - new-conversation: 创建新对话/会话
  - current-conversation: 打开当前对话/会话(无则创建)
- 自动切换到对应模式和视图
问题3和4修复:
- 触发时重新读取最新设置,确保使用最新的 behavior 配置
- 注册前先注销所有旧快捷键,确保配置更新生效
- 禁用的快捷键不再触发
问题2修复:
- 创建新对话/会话后立即刷新列表
- 确保左侧对话框立即显示,无需等待发送消息
问题1修复:
- 添加 formatAccelerator 函数格式化显示
- macOS: CommandOrControl → Cmd, Alt → Option
- Windows/Linux: CommandOrControl → Ctrl
- 显示更简洁友好,如 'Cmd+Shift+C' 而不是 'CommandOrControl+Shift+C'
1. Agent 会话现在正确关联工作区
   - 快捷键创建的会话传递 currentWorkspaceId 参数
   - 会话现在可以在对应工作区中找到

2. 快捷键录制器现在能区分 Command 和 Control 键
   - 分别检测 metaKey 和 ctrlKey
   - 用户可以设置 Mac 专用的 Command 快捷键或跨平台的 Control 快捷键
   - 更新 formatAccelerator 支持新格式

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
修复问题2和问题3:
- 添加 validateChatShortcut 和 validateAgentShortcut 函数
- 在录制快捷键时检测与另一个快捷键的冲突
- 如果冲突,显示"快捷键已被占用"提示
- 防止设置相同的快捷键给 Chat 和 Agent

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
问题:当没有选中的对话时(currentConversationId 为 null),
但历史对话列表不为空(conversations.length > 0),
快捷键不会创建新对话也不会打开任何对话。

修复:
- 添加 currentConversationId 和 currentAgentSessionId 的读取
- 修改逻辑为三种情况:
  1. 没有任何对话 → 创建新对话
  2. 有对话但没有选中 → 打开第一个对话
  3. 已经有选中的对话 → 保持不变

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
问题:使用打开当前对话行为时,如果当前工作区没有会话,
但其他工作区有会话,代码会打开其他工作区的会话,
导致在当前工作区左侧看不到这个会话。

根本原因:代码直接使用全局 agentSessions[0],
没有考虑工作区过滤。

修复:先过滤出当前工作区的会话,然后再判断:
- 当前工作区没有会话 → 创建新会话
- 当前工作区有会话但没有选中 → 打开第一个
- 已经有选中的会话 → 保持不变

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant