不许睡
macOS 菜单栏小工具

不许睡KEEPAWAKE

让 MacBook 合盖且熄屏之后还能继续运行——下载、编译、SSH、远程连接不断线。

去 GitHub
macOS 13+ Apple Silicon 单文件 Swift 无第三方依赖 不需要 Xcode MIT

01为什么需要它

macOS 上「睡过去」有两条完全独立的路径。几乎所有保活工具让人困惑,根源都在这里:它们只挡住了其中一条,而用户以为两条都挡住了。

触发路径机制谁能挡住
空闲计时器
一段时间没人碰键鼠
用户态电源断言
IOPMAssertion
caffeinate、Amphetamine、KeepingYouAwake、Lungo、Caffeine……一切断言类工具
合盖
关上屏幕
霍尔传感器的硬件中断
→ clamshell sleep
只有 sudo pmset -a disablesleep 1
断言类工具在架构上就够不着
显示器全部断开 零显示器 → 强制睡眠 同上

第一行和第二行的区别,就是全部问题所在。断言是在用户态请求系统别睡,系统认这个请求;而合盖是一次硬件中断,走的是另一条路,根本不看断言。

那些「合盖还能跑」的工具是怎么做到的?

它们不是在挡合盖,而是在绕合盖:靠外接显示器进入 clamshell 模式「骗」过系统——而 clamshell 模式本身要求外接屏必须亮着。所以那种「合盖可用」的体验,代价是你得一直挂着一块屏。

本项目是直接挡:合盖 + 熄屏 + 继续跑。代价是必须用 disablesleep 这个开关。它是全局的、持久的、系统不会有任何提示的——所以下面花了很大篇幅讲怎么把它关起来。

02合盖熄屏:本项目补的那一刀

disablesleep 挡住的是整个 clamshell 流程,连「关掉内建屏」这一步也一起挡掉了。结果是合盖了、屏幕还亮着——在包里暗暗发光、持续耗电、持续发热。

开关开着&& 已合盖&& 无外接屏在线&& 内建屏还亮着
▼
/usr/bin/pmset displaysleepnow

有外接屏时刻意不动作——那时你正在用 clamshell 模式,外接屏就是工作屏,把它灭掉是事故。

关于锁屏

熄屏之后系统可能要求输入密码。这是 macOS 自己的策略(取决于「系统设置 → 锁定屏幕」里「需要密码」设的是「立即」还是延时),与本工具无关,也不影响后台继续运行。锁屏只是一层 UI,下载、编译、SSH 会话都照常。

03功能特性

一个总开关,一层补丁,四个安全阀,一行常驻状态。

图标三态

实心月亮已开启 · 空心月亮已关闭 · 感叹号风险性自动松开(电池到下限、系统进入低电量模式)。

计时器到点、开盖这类预期内的松开不报警——它们是你自己设的,不是出事了。

合盖熄屏

补上被 disablesleep 一起挡掉的灭屏步骤。判定条件见上,有外接屏时不动作。

安全阀(四个)

电池低于阈值、系统进入低电量模式、计时器到点、盖子打开后——任一条件满足时自动松开。默认已开最关键的两个。

状态可视化

菜单里常驻显示 电源 / 电量 / 盖子 / 在线显示器台数 / 内建屏状态,不用去开系统设置对照。

退出自动复位

从菜单退出会先把 disablesleep 复位。启动时若发现上次残留的标志,只复位,绝不自动开启。

5 秒巡检 + 停手报警

保活期间每 5 秒比对系统里的 SleepDisabled。被系统或别的程序改回去了,就真的停手、把图标切成感叹号,而不是假装还在工作。

安全阀默认值

安全阀默认说明
电池低于阈值自动松开 开 · 20% 仅在电池供电时判定;阈值可选 10 / 15 / 20 / 30 / 50%
低电量模式时自动松开 开 只在开启保活之后系统才进低电量模式时触发
计时器到点自动松开 关 不限 / 30 分 / 1 时 / 2 时 / 4 时
盖子打开后自动松开 关 默认关,否则开盖看个消息就把保活关掉了

04快速开始

需要 macOS 13+ 与 Apple Silicon。只需要 Command Line Tools(xcode-select --install),不需要安装 Xcode。

终端
# 1. 构建(产物在 build/不许睡.app)
./build.sh
# 2. 安装(复制到 /Applications,并按需写入一条 sudoers 白名单)
./install.sh

然后从「应用程序」或 Spotlight 打开「不许睡」,菜单栏出现月亮图标。它是纯菜单栏 App,没有 Dock 图标、没有主窗口。

安装脚本做了什么

已知边界