Skip to content

About

macOS 锁屏工具:屏幕正常显示,键鼠完全禁用,密码 / Touch ID 解锁。防止他人动你的电脑。

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

Repository files navigation

KeyboardLock

🔗 GitHub:github.com/rational-stars/KeyboardLock · 📦 下载(Release):最新 DMG

一个轻量的 macOS 菜单栏工具:锁住电脑,防止别人动手操作。

  • 锁定期间键盘、鼠标 / 触控板完全失效:任何 App 都收不到输入
  • 解锁流程:按 Esc → Touch ID 或密码 → 回车
  • 提示内容两种写法:直接填文字,或自己写整屏 HTML 页面(懂 HTML 的人可自由发挥)
  • 锁定期间屏幕可正常显示,也可整屏纯黑(防偷看,按 Esc 后浮现解锁界面)
  • 访客沙箱:只放行你指定的网页,其他 App 与其他网页一律点不动、切不走 —— 把项目交给别人看 / 调试时最合适
  • 锁定期间谁动过电脑、动了什么(不含密码输入),解锁后会给出一份操作记录
  • 快捷键支持单个按键(如妙控键盘右上角的 Lock 键),且录好后再点保存才生效
  • 支持在线更新(自动比对 GitHub Release 最新版本号并提示下载)

快速开始

cd KeyboardLock
./build.sh          # 编译 → 打包 .app → 生成 DMG 与 zip
open dist/KeyboardLock.app

想长期用,建议装到「应用程序」文件夹:

./install.sh        # 复制到 /Applications 并启动(不会覆盖同名的其他 App)

或直接双击 dist/KeyboardLock-1.5.0.dmg,把 App 拖进 Applications。

需要 macOS 13 及以上。只用到系统自带的 Swift 编译器,不需要安装 Xcode。

首次启动时会自动弹出系统授权窗口,两项权限都必须打开:

  1. 系统设置 ▸ 隐私与安全性 ▸ 辅助功能 → 勾选 KeyboardLock
  2. 系统设置 ▸ 隐私与安全性 ▸ 输入监控 → 勾选 KeyboardLock

授权后退出并重新打开 App(菜单栏图标变成「打开的锁 🔓」就说明生效了)。权限状态可以在「设置…」页面随时查看和重新检测。

使用

操作 说明
菜单栏图标 ▸ 立即锁定 手动锁定(默认快捷键 ⌘⌥L,可自定义)
自定义单个按键(如妙控键盘 Lock 键) 在「设置… ▸ 解锁方式」里点输入框后直接按该键即可(无需修饰键),录好后点「保存」生效
锁定后按 Esc 或自定义键 弹出解锁界面:优先 Touch ID,不支持则要求输入密码
Touch ID 验证 / 输入密码 + 回车 解锁成功(Esc 取消;Touch ID 界面下按任意键改用密码)
菜单栏 ▸ 设置… / 检查更新… 密码、Touch ID、快捷键、提示文案与位置、在线更新等
关于 KeyboardLock 显示开源地址、作者、头像

锁定状态下的行为:

  • 屏幕显示方式可选:正常显示(桌面、窗口、视频照常可见)或黑屏(整屏纯黑,防偷看)
  • 顶部「已锁定 · 按 Esc 后解锁」提示在正常显示模式下会显示,2 秒后自动消失;黑屏模式下不显示,按 Esc 后才浮现解锁界面
  • 键盘所有按键(含 ⌘Tab、⌘Q、⌘空格、强制退出组合键、妙控键盘 Lock 键)全部被拦截
  • 鼠标 / 触控板的点击被一张全屏置顶窗口吸收,不会落到任何 App 上
  • 有人动键鼠时弹出自定义提示(文字模式)或显示自定义 HTML 页面
  • 操作记录只记除密码外的键鼠操作,密码输入不会被记录,只统计尝试次数;解锁后若期间存在其它操作才弹出报告(可一键复制),否则不弹
  • 可设置开始记录前的等待时间(立即 / 5 秒 / 自定义秒数),避免把自己锁定瞬间那一下误记进去
  • 锁定期间菜单栏的「设置」「退出」被禁用,⌘Q 也无效,必须先解锁
  • 默认锁定期间保持屏幕常亮(可在设置里关掉)

访客沙箱(只放行指定网页)

适合这个场景:你打开一个项目要让别人看 / 调试,只许他碰这个页面,别的都不许动。

和全屏锁定相反,沙箱是「默认全禁,只放行受控窗口」:

  • 受控页面由 App 用独立浏览器配置启动(Chrome / Edge,--app= 或 --kiosk),读不到你自己的书签、插件与登录态,解锁后一并关闭,不留痕迹
  • 鼠标:只有落在受控窗口内的点击、滚动、拖拽才生效;落在别处一律吞掉,点不动任何东西
  • 键盘:走白名单 —— 字符、方向、回车、退格、⌘C/V/A/X/Z/R、⌘F、缩放、F5 刷新等正常放行(对方能在页面里正常输入和调试);而 ⌘Tab、⌘Q、⌘空格、调度台、Ctrl+←→、强制退出等一律拦截,跳不出去
  • 受控窗口本身没有地址栏和标签栏,对方无法输入别的网址(可再叠加「顶部预留高度」彻底封死顶部区域)
  • 越界操作(点白名单外、按被禁的键)会被记进解锁报告,谁偷偷试了什么一目了然

两种窗口形态:

形态 说明
单页全屏(kiosk) 一个网址独占全屏,无地址栏无标签栏,几乎无法跳出。最严格
多页独立窗口 每个网址一个独立窗口(同样无地址栏标签栏),可同时放行多个页面。页面内点链接仍可能跳转,风险略高

开启路径:设置… ▸ 锁定范围 ▸ 选「访客沙箱」→ 填网址(一行一个)→ 选窗口形态 → 照常锁定即可。可选项:允许对方用开发者工具(F12 / ⌘⌥I)、把 Esc 交给页面(改由快捷键唤出解锁)。

沙箱是为「防误触 / 防顺手」设计的,不是防恶意:页面内的链接跳转、电源键与强制关机这类物理操作仍无法拦截。要按 URL 严格限制导航,需要再加一个浏览器扩展。

设置项

  • 锁定范围:全屏锁定(键鼠全禁)或访客沙箱(只放行指定网页,详见上一节)
  • 沙箱窗口形态:单页全屏(kiosk)/ 多页独立窗口;允许访问的网址(一行一个);浏览器程序路径(默认 Chrome)
  • 沙箱可选:允许开发者工具(F12 / ⌘⌥I);把 Esc 交给页面、改用快捷键唤出解锁
  • 解锁密码:只保存 salt + SHA256 哈希,不保存明文,支持字母、数字、符号
  • 优先 Touch ID:支持指纹的机器按 Esc 直接刷指纹,失败或取消后退回密码;不支持则始终用密码
  • 锁定快捷键:可开关;支持组合键或单个按键(如妙控键盘的 Lock 键)。点输入框 → 按下按键(显示录到的键)→ 点「保存」才生效,「恢复默认」直接生效并回到 ⌘⌥L
  • 提示方式:二选一 —— 文字(直接填提示文案,纯文本渲染);或自定义 HTML 页面(整屏渲染你写的 HTML,密码 / Touch ID 解锁界面浮在其上)
  • 有人动键鼠时显示提示:可开关,提示文案完全自定义;「测试效果」按钮会按当前提示方式(文字 / HTML 页面 / 黑屏)不锁屏全屏预览当前锁屏画面
  • 锁定期间屏幕:正常显示或黑屏(整屏纯黑,防偷看,按 Esc 后浮现解锁界面)
  • 提示位置:屏幕中央 / 顶部 / 底部 / 右下角;停留时长:2 / 3 / 5 / 10 秒
  • 记录锁定期间的操作:可开关,解锁后弹出报告(无操作则不弹),报告可复制到剪贴板
  • 开始记录等待:立即 / 5 秒 / 自定义秒数 —— 锁定后先等待一段时间再开始记录操作
  • 在线更新:「检查更新」按钮 + 「启动时自动检查」开关;自动比对 GitHub Release 最新版本号并提示下载
  • 锁定期间保持屏幕常亮:防止锁着锁着息屏
  • 无操作自动锁定:1 / 5 / 15 / 30 分钟,或关闭
  • 登录时自动启动:需要先把 App 放进「应用程序」文件夹

忘记密码怎么办

  • 还没锁定:菜单栏 ▸ 设置… ▸ 「忘记密码…」→ 重置后重新设置。
  • 已经锁死且忘了密码:
    1. 用另一台设备 SSH 登录,或在终端执行 pkill -9 KeyboardLock;
    2. 然后执行 defaults delete com.xq.KeyboardLock 清掉密码哈希;
    3. 重新打开 App 重新设置密码。

实现原理

  • CGEventTap(HID 层)全局拦截键鼠事件:锁定期间键盘事件直接吞掉,鼠标事件放行但被顶层透明窗口吸收
  • 密码输入不依赖系统焦点:由事件流直接解析按键字符,所以键盘被"禁用"的同时仍能接收密码
  • 每个屏幕一个全屏透明、置顶(CGShieldingWindowLevel)窗口,屏幕内容照常显示,但点击无法穿透
  • 解锁校验支持 LocalAuthentication(Touch ID),失败自动退回密码输入,密码始终是兜底
  • 键鼠事件(不含密码输入)写入操作日志(鼠标移动节流 5 秒一条、滚轮 2 秒一条);锁定后有一个「开始记录等待时间」的宽限期,期间不记录;解锁后仅当存在除密码外的操作时才回调弹出报告,并附密码尝试次数
  • 密码校验失败会有退避冷却(1 秒起递增),防止暴力试密码
  • 在线更新:GitHubUpdater 查询 GitHub Release 最新版本号并与本地比对
  • 提示文案渲染:文字模式按纯文本渲染;自定义 HTML 页面模式通过 WKWebView 整屏渲染用户编写的 HTML。「测试效果」会创建同等层级的全屏预览窗口,不真正锁屏
  • 访客沙箱:SandboxManager 用独立 --user-data-dir 启动受控 Chrome/Edge 实例(独立 PID,与用户自己的浏览器互不干扰),每 0.4 秒用 CGWindowListCopyWindowInfo 刷新该 PID 名下的窗口矩形作为「放行白名单」(bounds / PID / App 名无需屏幕录制权限,窗口标题才需要)。事件拦截从「全吞」改为「白名单放行」:鼠标按坐标判定,键盘按键位判定。沙箱下不铺全屏遮罩,只在屏幕上方挂一块 ignoresMouseEvents 的浮层承载状态与解锁界面,鼠标穿透到受控页面
  • 版本号唯一来源是 Sources/AppInfo.swift,build.sh 会自动同步进 Info.plist 和 DMG 文件名

已知限制

  • 签名与权限:「辅助功能 / 输入监控」授权是按代码签名身份记录的。build.sh 会自动挑选本机可用的签名证书并按以下优先级使用:Developer ID Application → Apple Development → 其它自签代码签名证书。只要每次构建用同一个证书身份,更新替换 App 后就不必重新勾选权限。三者都没有时才回退 ad-hoc(此时更新后需重新授权一次)。
  • 没有 Apple 付费证书也能解决:直接跑 ./Tools/make-codesign-cert.sh,它会创建一张 20 年有效的自签代码签名证书(含根 CA)并导入钥匙串,再执行 ./build.sh 即可。脚本可重复执行,已存在同名有效身份时会跳过。
    • 换机器时把 ~/.keyboardlock-certs/KeyboardLock-CodeSign.p12 拷过去双击导入(导出密码 keyboardlock)。
    • 想手动操作也可以:打开「钥匙串访问 ▸ 证书助理 ▸ 创建证书」,身份类型选「代码签名」,创建后在证书上右键 ▸ 显示简介 ▸ 信任 ▸ 代码签名 设为「始终信任」。
  • 自签证书未经过公证,首次运行仍可能需要在「系统设置 ▸ 隐私与安全性」点「仍要打开」(有 Developer ID 后可再用 xcrun notarytool 公证)
  • 访客沙箱的残留风险:页面内的链接跳转无法拦截(--app 模式下点链接会导航;单页 kiosk 模式已大幅缓解);受控窗口被关闭后白名单会变空、输入全部失效,需要重新锁定;电源键、强制关机等物理操作无解
  • 进程被 pkill 或崩溃时锁会解除(后续可加 launchd 守护 + 锁定状态持久化)
  • 登录窗口、系统关机界面等系统级安全界面不受本 App 控制
  • 在线更新需联网;若为内网或离线环境,检查更新会自动失败(不影响锁定功能)

目录结构

Sources/
  main.swift           入口
  AppDelegate.swift    菜单栏、设置窗口、权限引导、关于面板
  LockManager.swift    事件拦截引擎、锁屏层、Touch ID、密码校验、提示预览
  PasswordStore.swift  密码哈希存储
  AppInfo.swift        版本号 / 仓库 / 作者信息唯一来源
  GitHubUpdater.swift  在线更新检查(比对 GitHub Release 版本号)
  Views.swift          锁屏界面、设置界面、快捷键录制控件、关于界面(SwiftUI)
Resources/Info.plist
Tools/make_icon.swift  图标绘制
Tools/make-codesign-cert.sh  创建自签代码签名证书(消除更新后的权限重授权)
build.sh               编译 → .app → 签名 → DMG/zip
install.sh             安装到「应用程序」(不会覆盖同名第三方 App)
gen_icon.sh            生成 AppIcon.icns

About

macOS 锁屏工具:屏幕正常显示,键鼠完全禁用,密码 / Touch ID 解锁。防止他人动你的电脑。

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages