使用SketchyBar代替macOS菜单栏

Contents

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

左边栏:系统菜单、空间切换、在屏窗口、空间和App菜单快速切换
左边栏:系统菜单、空间切换、在屏窗口、空间和App菜单快速切换
右边栏:iStat Menus、实时天气、App状态、Wi-Fi信息
右边栏:iStat Menus、实时天气、App状态、Wi-Fi信息

我构建了一个macOS多显示器SketchyBar菜单栏方案。主要开发了以下模块和工具:

  • space_scan扫描空间窗口

  • SketchyBarLocationHelper获取定位

  • now_playing 桥接媒体播放信息

  • Chrome浏览器扩展SketchyBar Now Playing Bridge,桥接YouTube Music播放状态

  • 基于 OpenWeather API和设备定位的实时天气

  • 通过Hammerspoon去掉对yabai依赖

  • 创建了多个自定义组件,包括 LM Studio 模型管理、剪贴板历史、实时翻译、微信未读消息、Time Machine备份状态、Quantumult X 公网 IP 显示、iStat Menus 整合等

所有配置文件和代码托管在 GitHub:https://github.com/binbinsh/sketchybar-config,并提供了一键安装脚本方便快速部署。

安装和配置SketchyBar #

基于SketchyBar作者的配置文件,采用 SketchyBar + SbarLua 的组合,主要逻辑用 Lua,少量 C语言小工具做事件和数据采集。辅助程序(定位、空间窗口扫描等)放在 helpers/ 下,按需编译调用。由于窗口最大化会盖住SketchyBar,我使用Hammerspoon做了顶部调整,不用依赖 yabai 或 aerospace 窗口管理工具。

安装方法有两种:快速安装和手动安装。

快速安装 #

运行一行命令,自动下载配置文件并安装所需软件。

shell
curl -L https://raw.githubusercontent.com/binbinsh/sketchybar-config/main/install_sketchybar.sh | sh

自动安装脚本会完成以下操作:

  • 安装 lua、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并写入钥匙串:

shell
# 将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小时才会生效。

Now Playing 与 YouTube Music 支持 #

我实现了一个C语言插件now playing事件助手与Chrome浏览器扩展桥接,状态栏可展示并控制当前播放的曲目信息,支持 Apple Music、Spotify和YouTube Music. 其中,对 YouTube Music 的支持通过自制浏览器扩展 + Native Messaging 实现。

SketchyBar Now Playing Bridge(Chrome插件) #

通过浏览器扩展 + Native Messaging 实现 YouTube Music 支持。扩展监听播放状态,通过 Native Messaging 协议将元数据传递给本地 C 程序,再由 C 程序向 SketchyBar 发送事件更新状态栏。

安装步骤:加载扩展 → 复制扩展 ID → 运行安装脚本注册 Native Host → 重启浏览器验证

now_playing 事件助手 #

核心原理:C 程序作为桥接层,既能接收浏览器扩展通过 Native Messaging 发来的播放数据(YouTube Music),也能通过 macOS Distributed Notification 获取本地 Apple Music 的播放状态。两种数据源统一转换为 media_nowplaying 事件发送给 SketchyBar。

SketchyBar Location Helper #

为了能够获取本地实时天气,我实现了小工具SketchyBarLocationHelper.app,用Core Location获取设备定位,并写入缓存文件 ~/.cache/sketchybar/location.txt(格式:ts|lat|lon|label)。天气小部件读取定位、用OpenStreetMap反查地点名、再请求 OpenWeather获取天气。

手动触发方式:

shell
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系统设置 #

  1. 把系统菜单栏设为始终自动隐藏:系统设置→菜单栏→自动隐藏和显示菜单栏→始终

  2. 若使用天气组件,首次定位授权选择“使用App期间即可”。

  3. 用iStat Menus时,需启用合并菜单项,用于整体alias到SketchyBar.

参考资料 #