- 桌面应用
【免费下载链接】KeepingYouAwake
Prevents your Mac from going to sleep.
本篇技术指南以 KeepingYouAwake 的 1.3.1 版本发布文档(docs/Versions/v1.3.1.md)为主线,剖析该版本围绕三大主题的修复与新增:Sparkle 自动更新通道的恢复、自定义菜单栏图标的模板图像渲染修复,以及通过defaults命令新增的“禁用点击高亮矩形”高级设置。读完本文,你将掌握该版本引入的更新机制原理、自定义图标规范与背后的源码实现,并能在当前 macOS 环境下复现与验证这些配置。
一、版本背景:1.3.1 为何而来
KeepingYouAwake 是一款防止 Mac 进入睡眠的菜单栏小工具,其核心是对 Apple 官方caffeinate命令的封装。1.3.1 发布于2015 年 12 月 8 日(见 docs/Versions/v1.3.1.json 中的日期字段),紧随 2015 年 11 月 2 日发布的 1.3 版本。1.3 版本刚引入了通过keepingyouawake://URI scheme 进行命令行激活/停用的能力,以及自定义菜单栏图标支持(详见 docs/appcast.xml 中 1.3 版本的 release notes)。1.3.1 则是对 1.3 出现的关键问题的一次集中修复,官方发布文档将其命名为"Updater and Icon Fixes"(更新器与图标修复),共包含三项变更:
- 修复 Sparkle 自动更新(受 OS X 10.11 App Transport Security 与 GitHub 关闭 Pages 的 HTTPS 支持影响而失效);
- 修复自定义图标的渲染:现在它们被渲染为模板图像(template images);
- 新增高级设置,可禁用点击时的蓝色高亮矩形。
在 CHANGELOG.md 与 docs/appcast.xml 中记录的 1.3.1 release notes 与发布文档完全一致,三处信息相互印证。下面分别深入三项变更的来龙去脉与实现细节。
二、修复 Sparkle 自动更新:ATS 与 HTTPS 双重冲击
2.1 故障根因
发布文档明确指出,1.3.1 之前的自动更新功能“坏掉”的原因有两个:
- App Transport Security(ATS):OS X 10.11(El Capitan)起,系统默认强制 App 的网络请求必须走 HTTPS,并对证书、加密强度等提出更严格的要求。若更新 Feed 或下载地址不符合 ATS 规定,请求会被直接拦截。
- GitHub 关闭 Pages 的 HTTPS 支持:该项目当时将 Sparkle 更新 Feed(appcast)托管在 GitHub Pages 上,而 GitHub 一度关闭了 Pages 的 HTTPS 访问,导致更新通道在协议层面失效。
两者叠加,使得 1.3.0 用户无法通过应用内自动更新获取新版本。发布文档因此特别强调:如果认识仍在使用 1.3.0 的用户,请告知他们 1.3.1 已发布,可手动下载安装,以便重新获得后续更新能力——这正是“噩梦成真”的应急写照。
2.2 更新机制在当前仓库中的实现
尽管仓库当前版本已演进到基于 Sparkle 2 的架构,但更新通道的设计思路仍与 1.3.1 修复后一脉相承。相关实现位于 KeepingYouAwake/KYAAppUpdater/KYAAppUpdater.m,其关键点包括:
- 通过
SPUStandardUpdaterController封装 Sparkle 更新器,并以单例形式对外提供defaultAppUpdater; - 通过实现
SPUUpdaterDelegate的feedURLStringForUpdater:方法动态选择更新 Feed:
static NSString * const KYAAppUpdaterReleaseFeedURLString = @"https://newmarcel.github.io/KeepingYouAwake/appcast.xml"; static NSString * const KYAAppUpdaterPreReleaseFeedURLString = @"https://newmarcel.github.io/KeepingYouAwake/prerelease-appcast.xml"; - (NSString *)feedURLStringForUpdater:(SPUUpdater *)updater { Auto defaults = NSUserDefaults.standardUserDefaults; if([defaults kya_arePreReleaseUpdatesEnabled]) { return KYAAppUpdaterPreReleaseFeedURLString; } else { return KYAAppUpdaterReleaseFeedURLString; } }这里可以看到:Feed URL 全部使用 HTTPS,这正是 1.3.1 修复“HTTPS 失效”问题的直接延续——从源码结构看,项目在后续版本中始终坚持以 HTTPS 托管 appcast,以满足 ATS 要求。是否启用预发布通道则由用户默认值kya_arePreReleaseUpdatesEnabled控制(对应键名info.marcel-dierkes.KeepingYouAwake.PreReleaseUpdatesEnabled,见下文源码详解)。
仓库中还保留了完整的发布 Feed 文件,可直接在仓库内验证更新内容的组织方式:
- 正式版更新通道:docs/appcast.xml;
- 预发布版更新通道:docs/prerelease-appcast.xml。
以 docs/appcast.xml 中 1.3.1 条目为例,其结构包含<title>、<description>(即版本发布说明)、<pubDate>(2015 年 12 月 8 日 09:00 GMT)以及<enclosure>(指向 1.3.1 的 zip 包下载地址,sparkle:version="131"、sparkle:shortVersionString="1.3.1")。这正是 Sparkle 检查更新时所依据的“版本清单”格式。
另外注意,KeepingYouAwake/KYAAppUpdater/KYAAppUpdater.h 中定义了编译开关KYA_APP_UPDATER_ENABLED(默认 0),即更新模块可通过编译配置整体启用/关闭,这为“去除更新功能的构建变体”提供了条件编译入口。
三、自定义图标修复:改为模板图像渲染
3.1 修复内容
发布文档第二条:"Fixed rendering for custom icons: They are now rendered as template images"。在此之前,用户放置的自定义菜单栏图标会以原始色彩/样式被直接绘制;1.3.1 起,自定义图标一律以template image(模板图像)方式渲染,从而让 macOS 根据菜单栏的深色/浅色外观自动着色(黑色部分适配高亮、透明度变化保留阴影效果),使自定义图标与系统原生菜单栏图标的观感保持一致。
3.2 自定义图标的文件规范
1.3.1 沿用 1.3 引入的自定义图标功能,命名与尺寸规范如下(见 Documentation/Custom Icons.md):
| 文件名 | 尺寸(px) | 说明 |
|---|---|---|
ActiveIcon.png | 22 x 20 | 激活状态图标(非 Retina) |
ActiveIcon@2x.png | 44 x 40 | 激活状态图标(Retina) |
InactiveIcon.png | 22 x 20 | 未激活状态图标(非 Retina) |
InactiveIcon@2x.png | 44 x 40 | 未激活状态图标(Retina) |
放置位置取决于版本是否启用 App Sandbox:
- 1.5.0 及以后(启用 App Sandbox):
~/Library/Containers/info.marcel-dierkes.KeepingYouAwake/Data/Documents/ - 更早版本(无沙箱,1.3.1 属于此类):
~/Library/Application Support/KeepingYouAwake/
文档同时给出设计建议:由于图标会被当作模板图像处理,推荐仅使用黑色作为基色,用不同透明度值表现阴影或较亮区域。仓库中的示例文件位于 Documentation/Custom Icons/(包含ActiveIcon.png、ActiveIcon@2x.png、InactiveIcon.png、InactiveIcon@2x.png),可作参考。
3.3 源码级印证
当前仓库中,自定义图标的加载与模板化渲染逻辑集中在KYAStatusItemUI包内:
- 在 Packages/KYAStatusItemUI/Sources/KYAStatusItemUI/KYAStatusItemImageProvider/NSImage+KYAStatusItemImage.m 中,
customIconNamed:方法加载自定义图标后显式设置image.template = YES,并追加@2x的 Retina 表示:
+ (NSImage *)customIconNamed:(NSImageName)imageName { NSParameterAssert(imageName); Auto fileURL = [NSURL kya_iconImageFileURLWithName:imageName isRetinaIcon:NO]; Auto image = [[NSImage alloc] initWithContentsOfURL:fileURL]; image.template = YES; Auto retinaFileURL = [NSURL kya_iconImageFileURLWithName:imageName isRetinaIcon:YES]; Auto retinaRep = [NSImageRep imageRepWithContentsOfURL:retinaFileURL]; if(retinaRep != nil) { [image addRepresentation:retinaRep]; } return image; }- 文件路径拼接逻辑位于 Packages/KYAStatusItemUI/Sources/KYAStatusItemUI/KYAStatusItemImageProvider/NSURL+KYAStatusItemImage.m:根据
isRetinaIcon追加@2x后缀并生成Documents目录下的完整 URL——即当前版本读取沙箱容器内Documents目录的图标文件。 - 图标提供者在 Packages/KYAStatusItemUI/Sources/KYAStatusItemUI/KYAStatusItemImageProvider/KYAStatusItemImageProvider.m 中通过
KYACustomIconImageFilesExist()判断四份图标文件是否齐全,全部存在才启用自定义图标(customProvider),否则回退到内置图标(standardProvider)。四文件缺一不可——NSImage+KYAStatusItemImage.m中的KYACustomIconImageFilesExist()对ActiveIcon/InactiveIcon各检查了普通与@2x两种规格。
从源码结构看,1.3.1 的“模板图像渲染修复”在后续版本中被完整保留并演进为上述模块化实现:图标从Documents目录读取、以模板图像渲染、自动适配 Retina。
四、新增高级设置:禁用菜单栏图标点击高亮
4.1 功能说明与命令
发布文档第三条新增了高级设置:禁用点击菜单栏图标时出现的蓝色高亮矩形。官方给出的启用命令为:
defaults write info.marcel-dierkes.KeepingYouAwake info.marcel-dierkes.KeepingYouAwake.MenuBarIconHighlightDisabled -bool YES命令解析:
defaults write是 macOS 标准的用户默认值写入命令,写入对象是偏好设置域info.marcel-dierkes.KeepingYouAwake(即该应用的 bundle identifier 域);- 键名为
info.marcel-dierkes.KeepingYouAwake.MenuBarIconHighlightDisabled; - 值为
-bool YES表示启用“禁用高亮”;按发布文档说明,将 YES 替换为 NO 即可恢复默认行为,即:
defaults write info.marcel-dierkes.KeepingYouAwake info.marcel-dierkes.KeepingYouAwake.MenuBarIconHighlightDisabled -bool NO需要注意的是,在 1.6.5 版本中,设置界面里的对应高级选项入口被移除,但该行为仍可通过上述defaults命令开启(见 CHANGELOG.md 与 docs/Versions/v1.6.5.md)。因此在现代 macOS 上,命令行写入仍然是控制该开关的官方途径。
4.2 偏好键的源码实现
该偏好键在KYAApplicationSupport包中定义与实现:
- 键常量声明位于 Packages/KYAApplicationSupport/Sources/KYAApplicationSupport/include/KYAApplicationSupport/NSUserDefaults+KYAKeys.h(
KYAUserDefaultsKeyMenuBarIconHighlightDisabled),并在同一文件的分类属性中暴露为kya_isMenuBarIconHighlightDisabled/kya_menuBarIconHighlightDisabled。 - 实际实现位于 Packages/KYAApplicationSupport/Sources/KYAApplicationSupport/NSUserDefaults+KYAKeys.m,通过
KYA_GENERATE_BOOL_PROPERTY宏生成 getter/setter 与键常量字符串。该宏将键名按固定格式展开为info.marcel-dierkes.KeepingYouAwake.<ShortKey>——这正是上述defaults命令中键名的来源。例如:
KYA_GENERATE_BOOL_PROPERTY(isMenuBarIconHighlightDisabled, menuBarIconHighlightDisabled, MenuBarIconHighlightDisabled);宏内部会生成:
NSString * const KYAUserDefaultsKeyMenuBarIconHighlightDisabled = @"info.marcel-dierkes.KeepingYouAwake.MenuBarIconHighlightDisabled";- 该键还配备了单元测试:在 Packages/KYAApplicationSupport/Tests/KYAApplicationSupportTests/KYAUserDefaultsKeysTests.m 中,
KYA_GENERATE_BOOL_TEST宏对每个 BOOL 偏好键验证 setter/getter 往返读写、以及通过boolForKey:直接读取的一致性,覆盖了该键的读写正确性。
4.3 高亮行为的底层挂接
高亮开关最终作用于NSStatusItem的highlightMode属性。在 Packages/KYAStatusItemUI/Sources/KYAStatusItemUI/KYAStatusItemController.m 中,菜单栏状态项配置时直接读取该偏好:
- (void)configureStatusItem { Auto statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; statusItem.highlightMode = ![NSUserDefaults standardUserDefaults].kya_menuBarIconHighlightDisabled; ... }即:kya_menuBarIconHighlightDisabled为YES时,highlightMode为NO,点击图标不再出现蓝色/高亮背景矩形;为NO(默认)时,highlightMode为YES,保持系统默认的点击高亮反馈。这一行代码完整串联起“defaults命令 →NSUserDefaults偏好 → 状态栏图标行为”的完整链路。
五、验证与实用建议
5.1 验证偏好写入
在安装了 1.3.1 及以上版本 KeepingYouAwake 的 macOS 上,可通过读取命令确认开关状态:
defaults read info.marcel-dierkes.KeepingYouAwake info.marcel-dierkes.KeepingYouAwake.MenuBarIconHighlightDisabled输出1表示已禁用高亮,0或键不存在表示使用默认行为。如需完全恢复默认,可使用:
defaults delete info.marcel-dierkes.KeepingYouAwake info.marcel-dierkes.KeepingYouAwake.MenuBarIconHighlightDisabled(注意:当前仓库仅介绍配置与查看方式,仓库本身为只读。)
5.2 三项变更的适用前提与限制
- 更新通道:1.3.1 修复针对的是 OS X 10.11 时代的 ATS 与 GitHub Pages HTTPS 问题;当前仓库版本已将 Feed 与下载全部切换到 HTTPS 托管,并要求 macOS 10.13 及以上(见 README.md)。1.3.1 所在时代对应的是 macOS Yosemite(10.10)与 El Capitan(10.11),README.md 明确指出 1.5.2 是支持这两个系统版本的最后一个版本。
- 自定义图标:模板图像渲染意味着图标中应避免使用非黑基色;未遵循规范(如使用彩色图标)时,渲染效果可能与预期不符。另外沙箱版本的图标目录(
Documents)与非沙箱版本的目录(Application Support)不同,需按版本选择。 - 高亮开关:该开关仅控制点击高亮矩形,不影响左键/右键、Ctrl/Option 点击等交互行为(相关交互逻辑同样可在 KYAStatusItemController.m 中查看)。
六、小结
KeepingYouAwake 1.3.1 是一次典型的“修复性发布”:
- 更新机制:修复了由 ATS 与 GitHub Pages HTTPS 变更共同导致的 Sparkle 更新失效,恢复用户获取后续版本的通道;
- 自定义图标:将自定义图标改为模板图像渲染,使图标外观与系统菜单栏风格统一;
- 高级设置:新增
MenuBarIconHighlightDisabled偏好键,允许用户通过defaults命令关闭点击高亮矩形,该设置至今仍可通过命令行启用。
三个主题分别对应仓库中可验证的实现:更新模块见 KYAAppUpdater.m 与 docs/appcast.xml;图标模板化渲染见 NSImage+KYAStatusItemImage.m;高亮开关见 NSUserDefaults+KYAKeys.m 与 KYAStatusItemController.m。对 macOS 菜单栏工具开发而言,这三项变更也是“更新通道可靠性、图标渲染适配、偏好设置可配置性”三类问题的典型处理范例,具有直接的参考价值。
- 桌面应用
【免费下载链接】KeepingYouAwake
Prevents your Mac from going to sleep.
相关推荐
dromara/electron-egg 前端组件库选择与集成指南
dromara/electron egg 前端组件库选择与集成指南 引言 在企业级桌面应用开发中,前端组件库的选择与集成直接影响开发效率和用户体验。dromar
桌面应用grok-build 0.2.50 版本更新解读:Mermaid 图表渲染增强、MCP 菜单修复与输入体验优化
grok build 0.2.50 版本更新解读:Mermaid 图表渲染增强、MCP 菜单修复与输入体验优化 导读 本文基于 grok build 仓库(Sp
人工智能大模型AI Agent代码智能体CLI工具调用MCP ClientsMacVim菜单栏图标自定义:更换应用图标与Dock显示设置
MacVim菜单栏图标自定义:更换应用图标与Dock显示设置 MacVim作为macOS平台上的Vim文本编辑器,提供了丰富的自定义选项,其中图标定制能让应用更
开发工具桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考