我把“显示器有单独的空间”关掉后,系统菜单栏只留在主显示器顶端,副屏顶部空空如也,观感和可用性都不太好。于是配置了SketchyBar,在多个屏幕显示统一的顶栏,并添加了一些自定义组件。SketchyBar一般和yabai或aerospace窗口管理工具配合使用,我进行了一些开发,使其能单独正常工作。


安装和配置SketchyBar
基于SketchyBar作者的配置文件,采用 SketchyBar + SbarLua 的组合,主要逻辑用 Lua,少量 C语言小工具做事件和数据采集。辅助程序(定位、桌面窗口扫描等)放在 helpers/
下,按需编译调用。由于窗口最大化会盖住SketchyBar,我使用Hammerspoon做了顶部调整,不用依赖 yabai 或 aerospace 窗口管理工具。
安装方法有两种:快速安装和手动安装。
快速安装
运行一行命令,自动下载配置文件并安装所需软件。
curl -L https://raw.githubusercontent.com/binbinsh/sketchybar-config/main/install_sketchybar.sh | sh
自动安装脚本会完成以下操作:
安装 lua、nowplaying-cli、sketchybar 这三个软件。
安装字体:SF Symbols、SF Mono、SF Pro 和 sketchybar-app-font.ttf.
安装 SbarLua.
下载配置文件到 ~/.config/sketchybar 文件夹(如果已有旧配置会先备份)。
重新启动 SketchyBar.
安装和配置 Hammerspoon,并添加最大化快捷键。
为了防止窗口挡住顶部SketchyBar状态栏,需要配置 Hammerspoon:设置窗口顶部留出 32px 空间,并添加 Alt+Shift+M 快捷键来最大化窗口(但不遮挡状态栏)。
手动安装
按照自动安装脚本的步骤,逐个安装需要的软件和字体,然后启动服务。
SketchyBar组件
我的主要目的是“显示器有单独的空间”关闭时,实现跨屏一致的顶栏,多个桌面和App菜单快速切换。我陆陆续续添加了组件:音量和SoundSource配置、更详细的WiFi信息、基于设备定位的实时OpenWeather天气、剪贴板管理、基于Raycast的快速谷歌翻译、加载/卸载LM Studio模型、最近3个Time Machine备份、微信未读信息、1Password、Synergy状态、Quantumult X和公网IP信息、iStat Menus 整合。
大部分组件支持点击弹窗、右键直达设置或应用,减少跳转。
前台应用
显示当前激活应用名,点击通过 swap_menus_and_spaces 事件在 menus/spaces 之间切换。
LM Studio
点击弹出已安装模型列表,点击即可加载模型,右键打开 LM Studio 应用。所有操作通过lms
完成,安装LM Studio CLI的方法:
https://lmstudio.ai/docs/cli
.
Clipboard
点击打开 Raycast Clipboard History,右键打开 Raycast Ask Clipboard.
Dictionary
点击即时翻译所选文本,右键打开 Raycast Quick Translate。需要安装 Raycast Google Translate (gebeto/translate
) 扩展。
Volume
显示当前的输出音量,点击打开 SoundSource 配置界面,SoundSource 支持设置耳机EQ,比如我的Sennheiser HD 490 Pro耳机。右键打开系统声音设置。
Quantumult X
点击弹出公网 IP、位置、ISP,这些信息从ipinfo.io
获取,右键点击打开 Quantumult X.
1Password
点击打开1Password Quick Access (通过Cmd+Shift+Space),右键打开应用。
微信
通过读取 Dock Badge 显示未读信息数,点击打开微信。需要安装 macOS 版 WeChat,并打开WeChat的通知图标标记。
iStat Menus
通过SketchyBar的alias功能,从macOS原menubar获取和显示iStat Menus合并组件。点击打开活动监视器。
Time Machine
点击通过系统自带 tmutil
读取最近1-3次备份时间,并弹窗显示。右键打开time machine.
Synergy
点击弹窗显示Synergy 1的server和client运行状态,右键打开Synergy配置界面。
Weather
使用OpenWeather One Call API 3.0获取当前天气,通过SketchyBar Location Helper获取当前设备定位,再用OpenStreetMap Nominatim反查地点名,最后从OpenWeather获取实时天气。
使用OpenWeather API需要注册API key并写入钥匙串:
# 将OpenWeather API密钥存在钥匙串中
security add-generic-password -a "$USER" -s OPENWEATHERMAP_API_KEY -w '<YOUR_API_KEY>' -U
# SketchyBar读取OpenWeather API的方法
security find-generic-password -a "$USER" -s OPENWEATHERMAP_API_KEY -w
API key申请后,可能需要等1–2小时才会生效。
SketchyBar Location Helper
为了能够获取本地实时天气,我实现了小工具SketchyBarLocationHelper.app
,用Core Location获取设备定位,并写入缓存文件 ~/.cache/sketchybar/location.txt
(格式:ts|lat|lon|label
)。天气小部件读取定位、用OpenStreetMap反查地点名、再请求 OpenWeather获取天气。
手动触发方式:
open -W ~/.config/sketchybar/helpers/event_providers/location/bin/SketchyBarLocationHelper.app
首次运行会出现While Using the App
的定位授权,可在系统设置→隐私与安全性→定位服务
管理。无法获取定位会出现⚠️ LOC
错误,可以重试或检查定位服务。
space_scan获取桌面所有窗口
由于不使用yabai和aerospace等窗口管理工具,SketchyBar又无法获取桌面所有窗口,我实现了一个小工具 helpers/event_providers/space_scan/space_scan.c
,通过CoreGraphics和SkyLight API获取窗口。在启动SketchyBar或切换桌面时,会扫描当前活跃桌面上的所有窗口,以应用为维度计数,并发布 space_snapshot
事件,items/spaces.lua
订阅后即时更新对应 space.<index>
的图标与计数。
macOS系统设置
把系统菜单栏设为始终自动隐藏:
系统设置→菜单栏→自动隐藏和显示菜单栏→始终
若使用天气组件,首次定位授权选择“使用App期间即可”。
用iStat Menus时,需启用
合并
菜单项,用于整体alias到SketchyBar.