cherry-studio/docs/technical/ShortcutSystemRefactor.md
2025-10-30 11:35:00 +08:00

9.3 KiB
Raw Blame History

Cherry Studio 快捷键系统重构设计文档 v2.1

最近更新2025-01-30
维护者Architecture Team

目录


背景与目标

旧版快捷键系统存在以下问题:

  1. 依赖已弃用的 configManager,与 v2 架构不兼容;
  2. Redux store 与本地存储重复维护状态;
  3. 处理器通过 switch-case 硬编码,可维护性差;
  4. 快捷键定义分散,缺乏统一真相源;
  5. 新增快捷键需要触达多处文件,易错且低效。

新版系统要实现:

  • 单一真相源:快捷键定义集中管理,保证一致性;
  • 偏好服务优先:所有运行时状态通过 preferenceService 管理;
  • 处理器注册表:解除 switch-case 依赖,改用 Map 注册;
  • 类型安全:从定义、存储到消费全链路具备 TypeScript 约束;
  • 易扩展:新增快捷键仅需「定义 → 注册处理器 → 使用」三步;
  • 性能稳定:支持 100+ 快捷键规模,主/渲染进程高效同步;
  • 多窗口同步:借助 preferenceService 自动推送变更。

核心原则

  1. 关注点分离

    • 定义层:静态元数据(名称、默认绑定、作用域、分类等);
    • 偏好层:用户可变配置(绑定、启用状态等);
    • 服务层:主进程注册、电焦/失焦时的生命周期管理;
    • UI 层:设置面板、快捷键提示等。
  2. 复用基础设施

    • 所有持久化均依赖 preferenceServiceSQLite + 内存缓存 + IPC
    • 变更通过订阅自动广播至所有窗口;
    • 新增键位无需改动主进程/渲染进程的底层框架代码。

架构分层

┌──────────────────────────────────────────────┐
│                   Shortcut 系统               │
├──────────────────────────────────────────────┤
│ 📋 Definitions (packages/shared/shortcuts)   │
│   - types.ts类型、作用域、分类              │
│   - definitions.ts静态定义真相之源      │
│   - utils.ts转换/校验工具                   │
│                                              │
│ 💾 Preferences (preferenceService)            │
│   - preferenceSchemas.ts 默认值               │
│   - preferenceTypes.ts 类型导出               │
│                                              │
│ ⚙️ Services                                   │
│   - src/main/services/ShortcutService.ts      │
│     · 处理器注册表、focus/blur 生命周期       │
│     · preference 订阅、主进程快捷键注册       │
│   - 渲染进程 useShortcut/useShortcutDisplay   │
│                                              │
│ 🎨 UI                                         │
│   - 设置页 ShortcutSettings                   │
│   - 各功能模块中的 useShortcut/useShortcutDisplay │
└──────────────────────────────────────────────┘

关键实现

1. 静态定义

  • 所有快捷键在 packages/shared/shortcuts/definitions.ts 中集中维护;
  • 包含 scopemain / renderer / bothcategorypersistOnBlur 等元信息;
  • enabledWhen 支持动态启用(如 mini window 与 quick assistant 开关关联);
  • 新增快捷键步骤:
    1. preferenceSchemas.ts 中声明默认值;
    2. definitions.ts 中补充静态定义;
    3. 在主/渲染进程相关模块注册处理器或消费 Hook。

2. 偏好系统

  • 所有运行时配置通过 preferenceService 读写;
  • 默认值与 PreferenceShortcutType 结构保持一致;
  • ShortcutService / useShortcuts 访问偏好时统一调用 coerceShortcutPreference,确保 fallback 与类型安全;
  • 批量重置通过 preferenceService.setMultiple 实现。

3. 主进程服务

  • ShortcutService 负责:
    • 生命周期:随着窗口 focus/blur 注册或卸载快捷键;
    • 处理器注册Map 替换 switch-case
    • 订阅偏好变更:自动重新注册;
    • persistOnBlur:例如 show_main_window 在窗口失焦时仍可触发;
    • shortcut.app.show_settings 会在需要时唤起窗口并调用 window.navigate('/settings/provider'),避免重复 blur/focus。

4. 渲染进程 Hook

  • useShortcut:从偏好获取绑定 → 转为 react-hotkeys-hook 字符串 → 注册快捷键;
  • useShortcutDisplay:转换为 UI 显示字符串( / Ctrl+ 等);
  • useAllShortcuts:批量拉取配置 + diff 默认值,供设置面板使用;
  • 新增 enableOnContentEditable 等配置支撑设置页和富文本场景。

5. 设置界面

  • ShortcutSettings 直接消费 useAllShortcuts
  • 支持录制、清空、重置默认、启用/禁用、冲突检测;
  • 重新绑定时使用 convertKeyToAccelerator / isValidShortcut / formatShortcutDisplay
  • “重置全部” 通过 preferenceService.setMultiple 一次性写入默认配置;
  • 新增表格展示 hasCustomBinding,区分用户自定义与继承默认值。

数据流

启动阶段

  1. preferenceService.initialize() 载入缓存;
  2. shortcutService 构造时注册处理器与订阅;
  3. 窗口创建后调用 shortcutService.registerForWindow,在 focus 时注册主进程快捷键。

运行时变更

  1. 设置页或其他模块调用 preferenceService.set / setMultiple
  2. 主进程订阅触发 → globalShortcut.unregisterAll() → 按新配置重注册;
  3. 渲染进程通过 usePreference/useMultiplePreferences 自动收到更新UI 即时刷新。

默认快捷键

preference key 默认绑定 描述 / 备注
shortcut.app.show_main_window Cmd/Ctrl + Shift + A 主窗口显示(失焦持久)
shortcut.app.show_mini_window Cmd/Ctrl + E Mini 窗口(与 quick assistant 联动)
shortcut.app.show_settings Cmd/Ctrl + , 设置页入口
shortcut.app.toggle_show_assistants Cmd/Ctrl + [ 助手侧边栏
shortcut.app.exit_fullscreen Escape 系统级,不可编辑
shortcut.app.zoom_in/out/reset Cmd/Ctrl + = / - / 0 包含数字键盘变体
shortcut.app.search_message Cmd/Ctrl + Shift + F 全局搜索
shortcut.chat.clear Cmd/Ctrl + L 清空消息
shortcut.chat.search_message Cmd/Ctrl + F 聊天内搜索
shortcut.chat.toggle_new_context Cmd/Ctrl + K 新上下文
shortcut.chat.copy_last_message Cmd/Ctrl + Shift + C 复制最后一条
shortcut.chat.edit_last_user_message Cmd/Ctrl + Shift + E 编辑最后一条用户消息
shortcut.topic.new Cmd/Ctrl + N 新增话题(默认启用)
shortcut.topic.rename Cmd/Ctrl + T 重命名话题(默认启用,自 2025-01 调整)
shortcut.topic.toggle_show_topics Cmd/Ctrl + ] 话题侧边栏
shortcut.selection.* 无默认绑定 划词助手开关、取词

具体配置以 preferenceSchemas.ts 为准,可在设置页查看或调整。


迁移与兼容性

  • 已有用户偏好:沿用旧值;新增键(如 shortcut.topic.rename)在数据库不存在时继承新默认;
  • 旧版 Redux store / configManager 已彻底移除;
  • IpcChannel.Shortcuts_Updatewindow.api.shortcuts.update 相关逻辑已弃用;
  • PreferenceMigrator 中保留与旧 keys 的映射,确保升级顺畅。

后续演进方向

  1. 冲突检测增强:主/渲染进程联动校验冲突并提示;
  2. 导入导出:允许用户批量备份/恢复自定义快捷键;
  3. 多作用域绑定:同一逻辑支持按窗口类型或上下文切换;
  4. 可视化录制:增加「录制模式」避免输入框手动录制;
  5. 自动化测试:补充主进程/渲染进程快捷键单元测试样板。

如需扩展或有疑问,请联系架构团队或在仓库中提交 Issue。
设计文档 v2.1 同步最新实现2025-01包含 shortcut.topic.rename 默认启用、show_settings 优化等补充说明。