Skip to content

About

Smooth, content-frozen window zoom animation overlay for macOS (Chromium/Electron-friendly), menu-bar app.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

SmoothZoom

macOS 菜单栏小工具:让「双击窗口标题栏放大 / 还原」的系统动画期间,窗口内容也保持顺滑, 同时完全保留系统原有动画时长与曲线。

icon

适用于 Chromium / Electron 系应用(Edge、Chrome、DeepSeek Harness、ZCode、VS Code、Obsidian…) 等"缩放时内容会重新排版"的窗口。


它解决什么问题

Chromium / Electron 应用在窗口放大 / 还原动画进行时,会实时重新排版网页内容。重排是异步的, 通常跟不上窗口边框的运动,于是你看到的是:窗口边框很丝滑,里面的内容却一格一格地跳、慢半拍。 原生 macOS 应用在缩放期间通常直接拉伸上一帧画面,所以看起来是顺的。

SmoothZoom 的做法是把系统动画「接管显示」:

  1. 双击标题栏时,截取窗口快照与屏幕背景快照(仅内存,不落盘);
  2. 检测到系统 zoom 动画开始后,显示一个全屏 overlay:冻结背景 + 冻结窗口内容, 窗口面 / 内容边缘按窗口实时 frame 平滑变化;
  3. 动画结束时撤掉 overlay,露出已经重新排版完成的清晰原生内容。

动画的时长、曲线、缓动全部沿用系统原生动画(overlay 只是逐帧跟随窗口 frame), 所以观感与原生一致——它不是改 NSWindowResizeTime / 关动画那种"变快变生硬"的方案。

特性

  • 系统级、全局:对任意 App 的普通窗口生效(全屏窗口自动跳过)
  • 保留系统原始动画时长与曲线(不修改任何系统设置)
  • 三种内容策略可在菜单栏实时切换(见下文「缩放内容效果」)
  • 双击瞬间无感预盖:内容不再出现"开始前一刻的偏移 / 跳帧"
  • 支持带透明 / 毛玻璃 / 半透明侧边栏的 UI(截取屏幕合成外观,而非仅窗口位图)
  • 仅需 屏幕录制 权限;不需要辅助功能(Accessibility)或输入监控
  • 截图只在内存中,不写盘、不上传

系统要求

  • macOS 14 或更新版本(在 macOS 26 / Apple Silicon 上开发验证)
  • 屏幕录制权限(唯一需要的权限)

编译 & 安装

./build.sh      # 编译 -> build/SmoothZoom.app
./install.sh    # 安装到 /Applications 并启动

首次启动会提示「屏幕录制」权限:系统设置 → 隐私与安全性 → 屏幕录制 → 勾选 SmoothZoom → 退出并重新打开 SmoothZoom(macOS 的屏幕录制授权需要重启 App 才生效)。

build.sh / install.sh 会优先使用本机已有的代码签名身份,找不到时退回 ad-hoc 签名。 使用 ad-hoc 签名的副作用:每次重新编译后系统可能要求重新授权屏幕录制。 如果希望"升级不再要求授权",可以自建一个稳定的代码签名证书(TCC 授权绑定证书,而非二进制哈希)。

使用

  • 双击任意窗口标题栏即可放大 / 还原;
  • 点击菜单栏图标:
    • 启用平滑缩放 — 全局开关
    • 只处理网页类 App(Chromium / Electron) — 更省资源
    • 缩放内容效果 — 切换三种内容策略(见下)
    • 登录时自动启动、写入调试日志、屏幕录制权限、打开日志文件夹、关于、退出
  • 日志:~/Library/Logs/SmoothZoom/smoothzoom.log

缩放内容效果(三种方案都保留,可随时切换)

模式 行为
① 位图缩放跟随 逐帧跟随窗口 frame,内容位图跟随边框缩放(最早版本)
② 合成缩放(CA 驱动) 由 Core Animation 驱动整段动画,内容位图平滑缩放(类绿色按钮过渡)
③ 内容保持不缩放,结束后加载(默认) 动画期间旧内容保持可见、不缩放也不移动;扩展区域用窗口底色填充;结束后淡入真实内容

对应 defaults:contentMode(0 / 1 / 2)。

高级选项(defaults 可调)

# 内容模式:0=位图跟随 1=合成缩放 2=保持不缩放+结束后加载(默认)
defaults write com.halo.smoothzoom contentMode -int 2
# 模式③:结束淡入时长(毫秒,0=硬切)
defaults write com.halo.smoothzoom holdFadeMs -float 160
# 模式③:内容 / 窗口边缘羽化开关与圆角
defaults write com.halo.smoothzoom feather -bool true
defaults write com.halo.smoothzoom cornerRadius -float 10
# 模式③:逐帧跟随真实窗口动画(默认);0 = 旧版合成动画
defaults write com.halo.smoothzoom trackNative -int 1
# 双击预盖(放大方向,避免开始前的内容偏移)
defaults write com.halo.smoothzoom preshow -int 1
# 合成动画时长(模式①②)
defaults write com.halo.smoothzoom syntheticMs -float 420
# 位图放大时的清晰度增强(GPU Lanczos + unsharp)
defaults write com.halo.smoothzoom enhance -bool true
defaults write com.halo.smoothzoom enhanceScale -float 2.4
defaults write com.halo.smoothzoom enhanceSharpness -float 0.55
# 调试
defaults write com.halo.smoothzoom debugLogging -bool true

已知限制

  • 全屏窗口(绿色按钮进入的系统全屏)不处理;原生全屏切换有自己的动画。
  • 系统开启「减弱动态效果」时不处理。
  • 应用自定义了标题栏双击行为(不做系统 zoom)时不会触发。
  • 模式③在缩回方向偶发一次约 1 帧的瞬闪(系统收缩启动瞬间的窗口帧报告时序问题), 概率约 3/10,尚未完全消除;介意可只用放大方向或切换到模式 ②。

技术实现

模块 方案
全局双击检测 NSEvent.addGlobalMonitorForEvents(鼠标事件无需 TCC 权限,自带 clickCount,不吞事件)
窗口快照 CGWindowListCreateImage(dlsym 获取;macOS 15+ 头文件标记 obsolete,但运行时仍可用,约 11–20 ms)
背景快照 CGWindowListCreateImage(.optionOnScreenBelowWindow)(约 15–40 ms,首击预取缓存)
窗口 frame 轮询 私有 SkyLight SLSGetWindowBounds(约 10 µs / 次,180 Hz),失败回退 CGWindowListCopyWindowInfo
覆盖层 全屏透明 NSWindow(.floating、ignoresMouseEvents、isOpaque=false、canJoinAllSpaces/fullScreenAuxiliary)+ CALayer
动画 逐帧跟随系统动画本身,所以时长/曲线与原生完全一致;结束以 frame 连续 3 帧稳定判定

目录结构

smoothzoom/
├── Sources/        # Swift 源码(菜单栏 App,无第三方依赖)
├── Resources/      # Info.plist / AppIcon
├── build.sh        # 编译
├── devbuild.sh     # 开发用构建(独立 bundle id,便于本地迭代)
├── install.sh      # 安装到 /Applications
└── README.md

License

MIT © 2026 Halo0sama

说明

本项目属于系统级视觉增强实验:通过外部 overlay 复现系统缩放动画观感,不修改任何系统设置、 不注入任何进程。使用风险自负。

About

Smooth, content-frozen window zoom animation overlay for macOS (Chromium/Electron-friendly), menu-bar app.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages