Chrome垂直标签页快捷键设置

📅 2026/7/9 9:11:07 👁️ 阅读次数 📝 编程学习
Chrome垂直标签页快捷键设置

用 Hammerspoon 给 Chrome 侧边栏加一个快捷键

Chrome 有个内置的垂直标签页侧边栏(Vertical Tab Sidebar),体验不错,但有一个致命问题:没有键盘快捷键来切换它。每次想收起或展开侧边栏,都得用鼠标去点那个小按钮。

作为一个键盘流用户,这无法忍受。于是我写了一个 Hammerspoon 脚本来解决这个问题。

思路

macOS 有一个 Accessibility API(无障碍 API),可以遍历任何应用的 UI 元素树,找到按钮并模拟点击。Chrome 的侧边栏切换按钮在无障碍树中的标识是"Expand Tabs""Collapse Tabs"

所以核心逻辑很简单:

  1. 通过hs.axuielement.applicationElement()获取 Chrome 的 AX 根元素
  2. 递归遍历窗口的子元素,找到目标按钮
  3. 调用performAction("AXPress")模拟点击

这个方案参考了 ChromeSidebarToggleRaycast 的思路,但把它移植到了 Hammerspoon 上,并增加了鼠标触发的支持。

两种触发方式

脚本提供三个 scheme,通过顶部的SCHEME变量切换:

Scheme触发方式
仅键盘1Cmd+S切换侧边栏
仅鼠标2鼠标悬停屏幕左边缘展开,移出 380px 收起
键盘 + 鼠标3两种都生效(默认)

鼠标触发的原理是每 50ms 轮询一次鼠标位置。当鼠标进入屏幕左边缘 2px 范围内并停留超过 0.15 秒,触发展开;当鼠标移出 380px,触发收起。

关键实现细节

Grace Period 防误触

切换应用时,鼠标位置和按键事件可能被误判。脚本在 Chrome 获得/失去焦点、系统唤醒/休眠时都会设置一个 grace period(宽限期),期间所有触发都被忽略。

看门狗机制

鼠标轮询器偶尔会意外停止。键盘事件处理器中内置了一个看门狗:如果超过 5 秒没有收到鼠标轮询的心跳,自动重建所有服务。

生命周期管理

脚本监听了三个层面的事件:

  • 应用层:Chrome 激活/失焦/启动/退出
  • 系统层:系统休眠/唤醒
  • 初始化层:启动时检测当前是否在 Chrome 中

每个状态转换都会正确地启动或停止对应的监听器,避免资源浪费和误触发。

安装

# 安装 Hammerspoonbrewinstall--caskhammerspoon# 复制脚本cpinit.lua ~/.hammerspoon/init.lua# 授权辅助功能# 系统设置 → 隐私与安全性 → 辅助功能 → 添加 Hammerspoon

然后在 Hammerspoon 菜单栏图标点击 “Reload Config” 即可。

自定义快捷键

默认快捷键是Cmd+S。改这里就行:

-- Cmd+S -> toggle sidebarifflags.cmdandnotflags.ctrlandnotflags.altandnotflags.shiftandkeyCode==keycodes.map["s"]then

比如改成Ctrl+Shift+B

ifflags.ctrlandnotflags.cmdandflags.shiftandnotflags.altandkeyCode==keycodes.map["b"]then

调试

三个调试快捷键:

  • Cmd+Alt+D:显示服务状态(scheme、监听器运行状态、事件计数)
  • Cmd+Alt+B:dump Chrome 所有 AX 按钮到 Console
  • Cmd+Alt+R:强制重启所有服务

文件结构

项目只有两个 Lua 文件:

  • init.lua— 完整版,支持三种 scheme
  • init-keyboard-only.lua— 纯键盘版,没有鼠标检测,代码更简洁

如果你不需要鼠标边缘触发,用 keyboard-only 版本就好,少了一半代码,也少了轮询的开销。

写在最后

这个脚本解决了一个很小但很烦的问题。Hammerspoon + Accessibility API 的组合在 macOS 上非常强大,几乎可以给任何应用的任何 UI 元素绑定快捷键。

项目地址:Chrome-Vertical-Tab-Sidebar-Toggle