SumatraPDF 自定义键盘快捷键完全指南:命令、按键语法、带参命令与全局热键
SumatraPDF 自定义键盘快捷键完全指南:命令、按键语法、带参命令与全局热键
本篇指南以 SumatraPDF 官方文档《Customize keyboard shortcuts》为骨架,结合仓库源码(src/Accelerators.cpp、src/ShortcutParse.cpp、src/GlobalHotkeys.cpp、src/AppSettings.cpp 等)进行深度展开。阅读本文后,你将掌握:如何通过高级设置文件的 Shortcuts 数组新增或重绑快捷键、Key 字段的完整语法(修饰键、特殊键、大小写规则)、Global 前缀的全局热键、支持参数的命令(如带颜色参数的高亮批注、带翻页数的滚动命令),以及如何恢复 3.5 时代的 Ctrl+Tab 切换行为。
自定义键盘快捷键功能自 SumatraPDF 3.4 起可用(
Shortcuts配置段),Global全局快捷键自 3.7 起可用。
打开高级设置并定位 Shortcuts
自定义快捷键的第一步是打开高级设置文件(advanced settings file):
- 通过菜单
Settings/Advanced Options...打开; - 或按下
Ctrl + K打开命令面板,输入adv缩小结果,选择Advanced Options...(对应命令CmdAdvancedOptions)打开。
设置文件会以记事本(Notepad)打开,在文件中找到 Shortcuts 数组,即可在其中添加或修改快捷键定义。保存文件后改动立即生效,无需重启 SumatraPDF(详见文末"生效时机"一节)。
Shortcuts 数组结构与完整示例
高级设置文件使用类似 ini 的结构化格式。Shortcuts 是一个数组,每个元素是一条快捷键定义,可包含以下字段:
| 字段 | 含义 | 说明 |
|---|---|---|
Cmd |
命令 ID | 必须。可以带参数,例如 CmdCreateAnnotHighlight #00ff00;可绑定 CmdNone 来禁用某个内置快捷键 |
Key |
按键定义 | 可选。语法见下文"Key 字段的格式";前缀 Global 可注册系统级全局热键(3.7+) |
Name |
命令名称 | 可选(3.6+)。提供后该命令会出现在命令面板(Ctrl + K)中 |
ToolbarText |
工具栏按钮文字 | 可选。提供后会在工具栏生成一个对应按钮 |
ToolbarSvgIcon |
工具栏按钮图标 | 可选(从源码 gShortcutFields 可见该字段,见 src/Settings.h) |
官方文档给出的完整示例:
Shortcuts [
[
Cmd = CmdOpen
Key = Alt + o
]
[
Cmd = CmdNone
Key = q
]
[
Name = Create green highlight
Cmd = CmdCreateAnnotHighlight #00ff00
Key = a
]
[
Cmd = CmdNextTab
ToolbarText = Next Tab
]
]
逐条解读:
- 默认情况下
CmdOpen(打开文件)绑定在Ctrl + O上,这里将其改为Alt + O; - 默认情况下
q用于关闭当前文档,将其绑定到CmdNone(什么都不做)即可禁用该内置快捷键; - 3.6+:
CmdCreateAnnotHighlight接受颜色参数(#00ff00为绿色)。这里把a重新绑定为创建绿色高亮批注(默认a创建黄色高亮); - 3.6+:
Name为可选字段,提供后命令会出现在命令面板(Ctrl + K)里; - 只有
Cmd和ToolbarText的条目不会绑定任何按键,而是在工具栏添加一个"Next Tab"按钮。
在源码实现上,Shortcut 结构体与字段表定义于 src/Settings.h 与 src/Settings.h;AppSettings.cpp 中的 CreateCustomShortcuts() 会把每条 Shortcuts 配置转换为独立的命令对象,并为每条快捷键克隆出唯一命令 ID(保证工具栏按钮 tooltip 与快捷键各自独立,见 src/AppSettings.cpp)。
自定义快捷键的生效层级
从 src/Accelerators.cpp 的 CreateSumatraAcceleratorTable() 可以看出实现细节:
- 先加入全部自定义快捷键,再加入内置快捷键;
Add()在追加时检查按键是否重复(sameAccelKey),重复的会被丢弃——因为自定义先加入,所以自定义快捷键会覆盖同键位的内置快捷键;- 最终生成三张加速表:普通表、编辑框(edit)表、树视图(tree view)表,保证在编辑框或书签树获得焦点时,快捷键也能按控件语义安全处理(详见 src/Accelerators.cpp)。
Key 字段的格式
Key 字段的写法遵循以下规则:
1. 单独按键
直接写字母或数字:a、Z、5。支持 a~z、A~Z 和 0~9。
2. 修饰键 + 按键
修饰键包括 Shift、Alt、Ctrl,以及 AltGr(别名 RAlt / RightAlt)。例如 Alt + F1、Ctrl + Shift + Y、AltGr + Return。注意:在 Windows 上 AltGr 等同于 Ctrl + Alt——源码注释也印证了这一点("Windows reports Right Alt / AltGr as Ctrl+Alt",见 src/ShortcutParse.cpp)。
3. 特殊键 除常规按键外支持下列特殊键(部分示例见官方文档,完整清单见下文源码):
F1-F24功能键;numpad0-numpad9:数字小键盘上的0~9;Delete、Backspace、Insert、Home、End、Escape;Left、Right、Up、Down:方向键。
特殊键的完整名称对照表在 src/ShortcutParse.cpp(numpad 键)、src/ShortcutParse.cpp(F1-F24)以及 src/ShortcutParse.cpp(方向键与标点键)中逐一定义。官方文档指向的"特殊键完整列表"在 src/Accelerators.cpp 的内置加速表附近,ShortcutParse.cpp 是按键字符串的权威解析实现(入口函数 ParseShortcutString 声明见 src/ShortcutParse.h)。
4. 大小写规则
- 无修饰键时大小写敏感:
a与A是不同快捷键(A默认是CmdCreateAnnotHighlight openedit,即创建高亮并进入编辑模式); - 带修饰键时用
Shift表达大写:Alt + a与Alt + A等价;要指定大写A需写Alt + Shift + A。
值得注意的工程细节:内置加速表中的字母快捷键都按虚拟键(
FVIRTKEY)编码,而不是 ASCII 码,这是为了让字母快捷键在西里尔文、希伯来文等非英语键盘布局下也能工作(见 src/Accelerators.cpp)。
全局快捷键(Global,3.7+)
3.7+ 版本支持注册系统级全局快捷键:只要在 Key 前加 Global 前缀,即使 SumatraPDF 没有焦点也能触发命令。示例:
Shortcuts [
[
Cmd = CmdGoToNextPage
Key = Global PageDown
]
[
Cmd = CmdScreenshot
Key = Global Alt+PrtSc
]
]
全局快捷键的运行时语义(与官方文档一致,并可由 src/GlobalHotkeys.cpp 的 RegisterGlobalHotkeys() 印证):
- 避免热键冲突:全局热键只由第一个运行的 SumatraPDF 实例注册(
IsOtherSumatraProcessRunning()检测到其他实例时直接返回,见 src/GlobalHotkeys.cpp); - 命令分发目标:需要窗口或文档的命令会派发到最近激活的窗口;若该窗口已关闭,则回退到之前激活的窗口。触发全局热键不会抢焦点,也不会把后台窗口带到前台(
GetTargetWindowForGlobalHotkey()按 MRU 顺序挑选目标窗口,见 src/GlobalHotkeys.cpp); - 注册失败提示:若系统拒绝了注册(例如热键已被其他程序占用),SumatraPDF 会弹出一条警告通知(
MaybeDelayedWarningNotification(...),见 src/GlobalHotkeys.cpp)。
底层实现通过 Windows RegisterHotKey API 完成注册(src/GlobalHotkeys.cpp),消息循环中由 HandleGlobalHotkey() 派发命令(src/GlobalHotkeys.cpp)。特殊的 CmdScreenshot 命令即使不加 Global 前缀也会被当作全局热键处理(src/GlobalHotkeys.cpp)。
可用命令列表
快捷键最终都要绑定到一个命令。命令 ID 的完整列表见 Commands.md(源码定义在 src/Commands.h 起,每个命令从 CmdOpenFile = 201 开始依次编号,CmdNone = 513 用于禁用快捷键)。
按类别列举常用命令 ID(完整清单请查阅上述文档):
- 文件:
CmdOpenFile(Ctrl+O)、CmdClose、CmdCloseCurrentDocument(q)、CmdExit(Ctrl+Q)、CmdPrint(Ctrl+P)、CmdSaveAs(Ctrl+S)、CmdReloadDocument(r)、CmdProperties(Ctrl+D); - 搜索:
CmdFindFirst(Ctrl+F)、CmdFindNext(F3)、CmdFindPrev(Shift+F3); - 查看:
CmdToggleFullscreen(f / F11)、CmdTogglePresentationMode(F5 / Ctrl+L)、CmdToggleMenuBar(F9)、CmdToggleToolbar(F8)、CmdRotateLeft/CmdRotateRight、CmdInvertColors(Shift+I); - 标签页:
CmdNextTab(Ctrl+PageDown)、CmdPrevTab(Ctrl+PageUp)、CmdNextTabSmart(Ctrl+Tab,3.6+)、CmdCloseAllTabs、CmdCloseOtherTabs; - 导航:
CmdGoToNextPage(n)、CmdGoToPrevPage(p)、CmdGoToPage(g)、CmdNavigateBack(Alt+Left)、CmdScrollUp(k / Up)、CmdScrollDown(j / Down); - 批注:
CmdCreateAnnotHighlight(a)、CmdCreateAnnotUnderline(u)、CmdCreateAnnotStrikeOut、CmdCreateAnnotSquiggly、CmdCreateAnnotFreeText、CmdCreateAnnotCircle、CmdCreateAnnotInk、CmdCreateAnnotSquare、CmdDeleteAnnotation(Delete); - 缩放:
CmdZoomIn(Ctrl+Add)、CmdZoomOut(Ctrl+Subtract)、CmdZoomActualSize(Ctrl+1)、CmdZoomFitPage(Ctrl+0)、CmdZoomFitWidth(Ctrl+2)、CmdZoomFitContent(Ctrl+3)、CmdZoomCustom(Ctrl+Y); - 收藏:
CmdFavoriteAdd(Ctrl+B)、CmdFavoriteDel、CmdFavoriteToggle; - 系统:
CmdAdvancedOptions、CmdChangeLanguage、CmdScreenshot、CmdShowLog。
带参数的命令(3.6+)
从 3.6 起,部分命令支持参数,这为快捷键提供了更丰富的定制能力。参数类型可以是字符串、数字、布尔值或颜色(#rrggbb 或 #aarrggbb 格式)。
参数书写规则:
- 参数有名字,格式为
CmdCreateAnnotHighlight color: #fafafa copytoclipboard: true; - 布尔参数:只写名字等价于
名字: true,即copytoclipboard与copytoclipboard: true相同; - 默认参数:可以省略参数名,例如
color是CmdCreateAnnotHighlight的默认参数,所以CmdCreateAnnotHighlight #fafafa等价于CmdCreateAnnotHighlight color: #fafafa; - 两条规则可组合:
CmdCreateAnnotHighlight #fafafa copytoclipboard等价于CmdCreateAnnotHighlight color: #fafafa copytoclipboard: true。
示例:默认 a 绑定 CmdCreateAnnotHighlight(黄色),可覆盖为创建绿色高亮,并为多种颜色创建多个快捷键:
Shortcuts [
[
Cmd = CmdCreateAnnotHighlight #00ff00
Key = a
]
[
Cmd = CmdCreateAnnotHighlight #ff0000
Key = Alt + a
]
]
下面逐一说明常用带参命令(详见 Commands.md)。
CmdCreateAnnotHighlight 与其他 CmdCreateAnnot*
参数:
color:默认参数,颜色类型。高亮批注的颜色,默认黄色;openedit:布尔,默认false。置为true时创建批注后会开启 Edit PDF 模式并在属性行打开 Contents 编辑器。内置的Shift + A/Shift + U就使用该参数;copytoclipboard:布尔,默认false。对高亮/下划线/波浪线/删除线批注,把选区(批注文本)复制到剪贴板。这曾是内置快捷键(如a)的默认行为,现在需显式指定;setcontent:布尔,默认false。对上述四种文本标记批注,把批注内容设为选区文本。
典型用途:改变批注默认颜色;为不同颜色创建多个快捷键。
其他 CmdCreateAnnot* 参数(3.6+)
在 CmdCreateAnnotHighlight 参数基础上,文本/图形批注还支持:
color:文本与边框颜色,未指定时为黑色;bgcolor:批注背景色,未指定时完全透明;textsize:批注文本字号,默认 12;borderwidth:自由文本、墨迹、直线、折线、多边形、正方形和圆形批注的边框宽度,默认 1;alignment:3.7+,自由文本在文本框中的对齐方式:left、center或right,默认left;opacity:批注不透明度,0 = 完全透明(不可见),100 = 完全不透明(默认);interiorcolor:圆形、正方形等批注的内部填充色,未指定时完全透明。
CmdScrollUp / CmdScrollDown(3.6+)
参数:
n:默认参数,整数,一次滚动多少行(默认 1)。
用途:加速 j / k 键的滚动:
Shortcuts [
[
Cmd = CmdScrollDown 5
Key = j
]
[
Cmd = CmdScrollUp n: 5
Key = k
]
]
CmdGoToNextPage / CmdGoToPrevPage(3.6+)
参数:
n:默认参数,整数,一次翻多少页(默认 1)。
用途:一次向前/向后翻多页。
CmdToggleBoolSetting(3.7+)
参数:
name:默认参数,字符串。某个布尔型高级设置的名称(不区分大小写的叶子名或点分路径,如Fullscreen.ShowMenubar)。
该命令在 true / false 之间切换目标设置,适合自定义快捷键或工具栏按钮。未知的设置名在定义快捷键时和命令执行时都会显示警告。
不带 name 参数时,命令面板会列出所有非内部布尔设置(= 前缀),回车或点击即可切换所选设置并关闭面板。
示例:用 t 切换全屏菜单栏:
Shortcuts [
[
Cmd = CmdToggleBoolSetting Fullscreen.ShowMenubar
Key = t
Name = Toggle Fullscreen Menubar
]
]
同一条目加 ToolbarText 即可同时获得工具栏按钮。例如用 w 或工具栏按钮切换 MouseWheelTurnsPage(滚轮翻页)设置:
Shortcuts [
[
Cmd = CmdToggleBoolSetting MouseWheelTurnsPage
Key = w
Name = Wheel Turns Page
ToolbarText = Wheel Turns Page
]
]
同样的方法适用于任意布尔高级设置,如 CmdToggleBoolSetting RememberViewOffsetOnPageTurn 或 CmdToggleBoolSetting ClickEdgeToTurnPage。
CmdZoomCustom(3.6+)
参数:
level:默认参数,字符串或整数,缩放级别。
level 的取值:
- 百分比数字,如
50或50%表示 50% 缩放、125表示 125% 缩放; - 虚拟缩放级别:
actual size(100%)、fit page(适合页面)、fit width(适合宽度)、fit content(适合内容)。
示例:把 z 绑定为 50% 缩放:
Shortcuts [
[
Cmd = CmdZoomCustom 50%
Key = z
]
]
CmdCommandPalette(3.6+)
参数:
mode:默认参数,可选字符串,指定命令面板的打开模式:@打开文件(标签页)#文件历史>命令(不带参数时默认>)&页面缩略图%目录(等价于CmdCommandPaletteTOC,Shift + F12)$收藏夹(等价于CmdCommandPaletteFavorites)*当前 PDF 中的批注=布尔高级设置(CmdToggleBoolSetting)
建议:为某个面板模式绑定快捷键时,优先使用专用命令 CmdCommandPaletteTOC / CmdCommandPaletteFavorites,而不是 CmdCommandPalette 加 mode 参数。因为设置文件里字面量 $ 必须写成 $$(转义规则见下节)。
示例:
Shortcuts [
[
Cmd = CmdCommandPalette #
Key = Ctrl + h
]
[
Cmd = CmdCommandPaletteFavorites
Key = b
]
]
带 state 参数的开关命令(3.7+)
以下开关命令支持可选的 state 布尔参数,用于强制指定状态而不是盲目切换——这对通过 DDE 的自动化特别有用:
CmdToggleFullscreenCmdTogglePresentationModeCmdToggleToolbarCmdToggleMenuBarCmdToggleContinuousViewCmdToggleTableOfContents、CmdToggleBookmarksCmdToggleDisableLinks
参数:
state:默认参数,布尔。on/true/1/yes强制开启,off/false/0/no强制关闭。文档已处于目标状态时不做任何事;省略参数则保持原有"切换"行为。
DDE 调用示例:
[CmdToggleFullscreen on]
[CmdToggleToolbar off]
[CmdToggleContinuousView state: on]
设置值中的转义规则
高级设置文件中的字符串值使用 $ 作为转义字符:
- 字面量
$必须写成$$; - 位于值末尾的单个
$会被当作尾部空白标记,而不是美元符号。
这对 CmdCommandPalette 的 mode 参数很重要:绑定快捷键时应使用 CmdCommandPaletteFavorites(或目录用 CmdCommandPaletteTOC),而不要写 CmdCommandPalette $ / CmdCommandPalette %(% 不涉及转义,但专用命令语义更清晰;$ 则必须写成 $$ 才能表示字面量)。
恢复 3.6 之前的 Ctrl+Tab 行为(无 Smart Tab Switch 弹窗)
3.6+ 将 Ctrl + Tab / Ctrl + Shift + Tab 绑定到 Smart Tab Switch(CmdNextTabSmart / CmdPrevTabSmart):按住 Ctrl 时弹出标签列表,松开后切换到所选标签,类似浏览器的标签切换器。而在 3.5 及更早版本中,这两个组合键会立即按标签条顺序切换标签(CmdNextTab / CmdPrevTab)。
3.7+ 恢复旧行为的最简单方法:在高级设置中把 CtrlTabSimple 设置为 true(该设置项定义于 src/Settings.h)。此后 Ctrl + Tab / Ctrl + Shift + Tab 立即按标签条顺序切换,弹窗不再出现;设回 false 即可恢复 Smart Tab Switch。
也可以直接重绑按键(适用于 3.6+):
Shortcuts [
[
Cmd = CmdNextTab
Key = Ctrl + Tab
]
[
Cmd = CmdPrevTab
Key = Ctrl + Shift + Tab
]
]
Ctrl + PageDown / Ctrl + PageUp 本来就不经过弹窗直接切换上/下一个标签。更多细节见 Tabs and windows 中的"Restore pre-3.6 Ctrl+Tab"章节——那里还指出:TabsMru 高级设置只改变 Smart Tab Switch 列表中标签的排列顺序(最近使用 vs 标签条顺序),并不会隐藏弹窗;隐藏弹窗请用 CtrlTabSimple 或上面的重绑方案。
生效时机与故障排查
- 即时生效:保存设置文件的瞬间改动即被应用,无需重启 SumatraPDF。源码中
ApplySettingsToOpenWindows()(src/AppSettings.cpp)在设置重载后重建菜单栏、工具栏并重新注册全局热键(ReRegisterGlobalHotkeys()),这正是"保存即生效"的实现基础; - 快捷键无效的可能原因:命令名拼写错误、命令参数非法,以及(特殊键场景下)按键名不在支持清单内;
- 查看日志:SumatraPDF 会记录快捷键解析失败的日志信息。若快捷键不工作,请按 Debugging-Sumatra 文档获取日志排查(解析入口
ParseShortcutString定义于 src/ShortcutParse.cpp,合法性校验IsValidShortcutString/IsGlobalShortcut声明于 src/ShortcutParse.h)。
小结
SumatraPDF 的快捷键系统由"命令 ID + 按键字符串"组成,配置集中在一个 Shortcuts 数组里:
- 键位语法:字母/数字、四类修饰键(
Shift/Alt/Ctrl/AltGr)、F1-F24、numpad、方向键等特殊键,加上无修饰键时的大小写敏感规则; - 带参命令:颜色(
#rrggbb)、整数(滚动行数/翻页数)、布尔(openedit/copytoclipboard/state/name)等参数让一条命令可以衍生出多种用途; - 全局热键:
Global前缀把快捷键提升到系统级,且只由首个实例注册、不抢焦点、注册失败有通知; - 兼容性:
CtrlTabSimple = true一行即可找回 3.5 的极简Ctrl+Tab切换。
从 Shortcuts 配置到 CustomCommand 再到三张 Windows 加速表,再到 RegisterHotKey 全局热键,整个链路在 src/AppSettings.cpp、src/Accelerators.cpp、src/ShortcutParse.cpp 与 src/GlobalHotkeys.cpp 中均有清晰实现可循。动手改一行设置,保存即生效,是快速验证这套机制的最好方式。